机器学习--基础

1. 介绍

机器学习,也就是实现AI的一种方式,跟我们以往硬编码的方式不同,是能够让计算机拥有学习能力的编程方式。其理论基础自然是数学,将高等数学运用到在编程之中。由于现在数据的爆炸式增长,为需求大量数据的机器学习算法打下了基础,所以最近人工智能火了起来,数据,数据,大数据。

1.1 定义

下面给出两个定义:

Arthur Samuel (1959). Machine Learning: Field of
study that gives computers the ability to learn
without being explicitly programmed.


Tom Mitchell (1998) Well-posed Learning
Problem: A computer program is said to learn
from experience E with respect to some task T
and some performance measure P, if its
performance on T, as measured by P, improves
with experience E

上面的定义虽然都有点久远,但是也从侧面反映了机器学习很久以前就可以研究了,只是最近因为大数据时代才火了起来。看不懂的自行Google翻译 ..


1.2 运用场景

机器学习可以运用的方向,我觉是只有你没想到,没有它做不到。下面列出一些常见的运用场景。

  1. 自动驾驶
  2. 语音、图像识别
  3. 机器翻译
  4. 推荐系统(好的推荐系统带来的盈利难以想象)

1.3 机器学习算法

说得那么厉害,那么到底是怎样实现的呢?机器学习算法主要有两个:

  • Supervise Learning - 监督学习
  • Unsupervise Learning - 无监督学习

    1.3.1 监督学习

    监督学习,顾名思义就是就是监督着计算机来学习,就是对提出的问题会给出参考答案给计算机;然后让计算机根据正确答案,不断的进行迭代,使得计算机看到类似的问题时也能给出正确的答案。这种学习方式,跟找规律很相像,只是这些规律的特征很多,我们人脑无法找出,只能靠计算机高速运行以及大容量的优势来处理。
    机器学习--基础_第1张图片
    如上图,出给房子的大小,并给出房子的价格(需要计算机预测的)。通过数据的灌输和迭代使得计算机能够得出一条能够拟合数据的曲线,这就是回归模型了啊。

1.3.2 无监督学习

那么无监督学习,自然就是不给出正确的答案啦,具体是这样的,给出一组数据,让计算机自己去找出其中的规律。看图:

机器学习--基础_第2张图片
根据数据的分布的特点,自动给数据进行了分类。


2. 无监督学习

2.1 线性回归模型

通常我们将数据划分为训练集、验证集以及测试集。不论是什么集,数据中拿去训练模型的成为特征,用X作为记号,Y为结果(如果有的话)。

有了数据,怎么用是个问题?

于是就有了 Hypothesis Function —— 仿函数,不要在意名字,我们就是利用仿函数来实现数据到结果的映射的。说了叫线性回归,那么这个映射函数就是 hθ(x)=θ0+θ1x 。正如房价预测的模型一样,特征X只有一个就是房子大小,这个函数也是线性函数,对房价的预测将会是一条直线。

机器学习--基础_第3张图片

等等,好像 θ0,θ1 都还没有说是什么,其实 θ (向量,包含了 θ0,θ1 ,之后没有特别说明没有下标的都为向量)就是我们希望通过机器学习自动给出的参数,就好像房价估测,我们想让计算机通过计算得出能最好的 θ 来拟合上面的数据集的。

这样就可以了?No,No,No.计算机怎么会知道哪个 θ 好,哪个不好。所以还有 Cost Function 代价函数,用 J(θ)=12mm1(hθ(xi)yi)2 ,我们用 J(θ) 来评判 θ 的好坏,这样计算机就知道如何“选择”合适的 θ 了,目标变成使 J(θ) 达到最小,这里m是训练集的个数。

这选择是什么意思?还打引号…难道到是暴力遍历每一种可能?这可能吗?先不说实数是无穷的,就算是整数,还限制了取值范围,当你只有一个特征的时候是时间复杂度是 O(n) ,那两个,三个呢?在机器学习中,数据的特征甚至可能成百上千,就例如一张30*30像素的gray图片,也有900个特征了。用暴力法,难以想象,感觉比汉诺塔还伤。

So,我们应该怎么处理?这里数学君来又来了, J(θ) 不是二次函数吗?二次函数开口向上的,就有最小值。看图:
机器学习--基础_第4张图片
我知道图片有点大,可是….大图不好吗?这里是我们熟悉的二次函数,我们可以把 X 看函数的常量, θ 看成变量,那么总有个 θ 能够让 J 达到最小值。那么求导记得吗?我们随机初始化 θ ,对 J 求导,导数为0的点,就是极值点。对于这个图,其他点的导数都为负数。那么我们可以通过下面的公式更新 θ

θj=θjαJ(θ)θj

J(θ)θj=1mi=0m(hθ(xi)yi)xij

因为 θ 是个向量,所以是求偏导,然后通过这样就可以有方向的找到最好的 θ 了,其中 α 是学习率,可以看出影响了每次更新 θ 的步伐。对于求导的地方有了 xij 这里是第 i 个训练样本的第 j 个特征。

好的,那么如何训练一个模型的过程我们就知道了,下面总结一下。

记号 说明
Hypothesis 仿函数 计算特征到结果的映射
Parameters θ 模型的参数
Cost Function J J(θ)=12mm1(hθ(xi)yi)2
Goal 目标 最小化 J(θ)

Step:

  1. 首先有函数 J(θ)
  2. 目标最小化 J(θ)
  3. 选择一些 θ 为初始值,经常随机初始化
  4. 通过不断改变 θ 来减少 J(θ) ,直到达到一个我们期望的值。

伪代码:
θ=Initialization(x)

do until J(θ) convergence{
hθ(x)=xθT
J(θ)=12mm1(hθ(xi)yi)2
J(θ)θj=1mmi=0(hθ(xi)yi)xij
θj=θjαJ(θ)θj
}

真的假的,我读得书少,你不要骗我…好吧,我知道,是时候来点实例来“睡服”你们了。

注:代码都是用Python实现。

2.2 线性回归模型实例

问题描述:假设你是一家餐厅的老板并且考虑在别的城市开分店,并且你有不同城市的人口及食物货车的收益数据。你希望通过这些数据帮助你选择在哪个城市开分店。

数据集: X (97,1) , Y (97,1) 表示有 97 个数据,X是城市人口,Y是收益。将使用 m 作为数据个数 , n 作为特征个数, 这里 m 为 97 , n 位 1 。

在开始任何工作前,将数据可视化,都是有用的。下图就是根据数据所画的点。

机器学习--基础_第5张图片

训练好模型后,我们希望给出一个新的城市人口数据,模型能够返回一个可能的收益值。

有了数据,现在我们应该初始化 θ ,在程序中,使用 theta 作为 θ

"""
    这里给X加了一列 1,因为有theta0,theta1, H_theta = theta0 + theta * x 的.
    所以为了实现向量话的运算,就为X加了一列1. theta 是(2,1). 所以 X * theta = (m , 1)
"""
def initilization(X):
    m,n = X.shape
    theta = np.ones((n+1,1))
    X = np.column_stack(( np.ones((m,1)) ,X))

    return X,theta

初始化好 θ 后,下一步我们开始计算 Cost J

def compute_cost(X,Y,theta):
    H_theta = np.dot( X , theta )
    J = np.sum( np.power( H_theta-Y , 2 ) )/(2*m)

    return J,H_theta

此时我们测试一下。

X,theta = initilization(X_raw)
J,H_theta = compute_cost(X,Y,theta)
print(J)
输出:10.2665204914

然后就是利用梯度下降更新 θ 的值了。

def gradient_descent(X,Y,H_theta,theta,alpha):
    m = X.shape[0]

    Dtheta = np.sum( (H_theta-Y)*X ,axis=0,keepdims=True)/m
    theta = theta - alpha*Dtheta.transpose()

    return theta

再测试一下:

X,theta = initilization(X_raw)
J,H_theta = compute_cost(X,Y,theta)
theta = gradient_descent(X,Y,H_theta,theta,alpha=0.01)
print(theta)
输出:
[[ 0.96679335]
 [ 0.75765107]]

嗯,一切都跟计划中的一样,现在我们把他整合起来。

def model(X,Y,theta,alpha=0.01,iterations=1000):

    for i in range(iterations):
        J,H_theta = compute_cost(X,Y,theta)
        theta = gradient_descent(X,Y,H_theta,theta,alpha)


    return theta

传入训练集数据,已经初始化好的 theta ,选择 α 学习率,以及迭代次数。每次迭代,我们计算出当前 θ 对应的 Cost J ,然后再更新 θ 。一个简单的模型就完成了。我们看一下结果。
机器学习--基础_第6张图片

可以看出,在训练完后,我们得出了一条蓝色的直线,使得数据点的的分布在直线附近。现在我们输入新的人口数据,就可以得出对应的收益值了。

也来试试,下载资源 点这里。
或者Github。

2.3 逻辑回归模型实例

问题描述:假设你是工厂的产品经理,并且你有对一些微芯片的两个不同测试的结果。 从这这些测试中,你想确定新的微芯片是否应该接受或拒绝。

数据集:X(118,2) ,Y(118,1) 。

数据可视化:
机器学习--基础_第7张图片

问题发现:可以发现数据的分布无法用一条直线将其分开,而应该是一条较为复杂的曲线。那么我们只有两个特征的模型过于简单了,无法将这两类数据很好的分开,这里就有一个新的概念,“多项式特征”。多项式是指它是利用原来的特征生成多项式,这样我们的方程就变成多元多次方程,这样足够复杂的去描述数据的分布了。

Python中特征多项式生成:

from sklearn.preprocessing import PolynomialFeatures

poly = PolynomialFeatures(6)
poly_features = poly.fit_transform(X)

我们将特征进行6次的多项式转化,y 就变成了 二元六次方程,这样就足够我们去拟合数据了。

跟前面一样,我们需要初始化 θ ,一样的代码。只是我们记得先用X生成多项式特征。 θ 会是 (29,1)。

不同的地方是 Hθ ,因为我们现在是逻辑回归模型,我们需要的输出是介于 0-1 之间的数(我们可以选择 >=0.5 为真 ,否则为假 )。所以我们对 θ 作了调整如下:

def sigmoid(Z):
    return 1/(1+np.exp(-Z))

H_theta = sigmoid( X*theta )

Sigmoid 函数的图像如下:

对应的,我们的Cost J函数也要稍作调整:

J=1mim(Ylog(Hθ)+(1Y)log(1Hθ))

可以看出,当Y为1时,只有 log(Hθ) 这一项 ,那么 Cost J 就仅受此项的影响,为了让 Cost J 变小,根据上面的Sigmoid 可以知,我们期望 Xθ 的值尽可能的大,这一 Sigmoid(Xθ) 就会越靠近 1 ,同样机会有 log(Hθ) 越靠近 0 。当 Y 为 0 时的情况就相反。 至于梯度下降函数,则不变(其实是有变的,只是求导后形式一样而已)。

另外,我们的模型已经足够复杂去识别数据了,意味着我们可以在训练集上的表现得很好,但是实际情况中,我们并不希望在训练集上的表现得太过好,因为这很可能意味着我们的模型对训练集过度拟合了。我们根据训练集的数据来训练模型,并不是说只希望它能正确的识别训练集上的数据,要是这样,何不硬编码实现?所以我们是希望它能够正确的处理未出现过的数据。所以我们有了正规项:

J=1mim(Ylog(Hθ)+(1Y)log(1Hθ))+λ2mjnθ2j

我们需要在Cost J 后面加上最后一项。同样在梯度下降也许要加上对应的项:

J(θ)θj=1mi=0m(hθ(xi)yi)xij+λmθj

注意:因为 θ0 是常量项,在上面的正规项我们通常不会处理 θ0 所以 j 从 1 开始。只是梯度下降的项喔。

在实现上述步骤后,我们训练完模型。得出以下数据:

机器学习--基础_第8张图片

还有精度界线:

机器学习--基础_第9张图片

通过精度界限,我们可以很直观的了解到模型区分数据的情况,圈内的都为 真 ,圈外的都为 假 。

具体实现及数据

3. 总结

为了控制文章篇幅,就在此作出基础总结。

习惯

在训练模型的时候,如果数据是二维或者三维的,我们都会讲数据可视化,以便我们分析数据的分布。在开始的时候,模型不必很复杂,根据 Cost J 的变化图,我们可以适当的调整模型,加入多项式特征或者正规项又或者是其他参数。

尝试

上面介绍了,线性回归以及逻辑回归模型,且都给出了相应的实现。所以如果你想建立自己模型也是可以的了。至于分类问题,上面介绍的是二元分类,如果是多元的话,我们可以利用划分的技术实现多元分类,也就是把其中一个看为“真”,其它 N-1个看为“假”,循环 N 次,选择概率最高的。

你可能感兴趣的:(AI,Machine,Learning--人工智能)