机器学习学习笔记(2)----线性回归
线性回归算法据说是机器学习中的Hello World,相对简单,机器学习的具体算法主要有三步:
1)为假设函数设定参数,通过假设函数画出一条直线,然后根据输入的点得到预测值。
2)将测试值带入损失函数,计算出一个损失值。(关于损失函数的定义,以后再讨论)
3)通过得到的损失值,利用梯度下降等优化方法,不断调整假设函数的参数,使得损失值最小。这个不断调整参数使得损失值最小化的过程就是线性回归的学习过程,通常称为训练模型。
我们使用python现有的算法库,体验一下线性回归是怎么回事。
首先,需要能够手工生成训练数据:
>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> x = np.linspace(-3, 3, 30)
>>> y = 2*x + 1
>>> plt.scatter(x, y)
<matplotlib.collections.PathCollection object at 0x0EEDC6B8>
>>> plt.show()
linspace函数会生成一个从-3到3区间的分布均匀的30个元素的数组:
>>> print(x)
[-3. -2.79310345 -2.5862069 -2.37931034 -2.17241379 -1.96551724
-1.75862069 -1.55172414 -1.34482759 -1.13793103 -0.93103448 -0.72413793
-0.51724138 -0.31034483 -0.10344828 0.10344828 0.31034483 0.51724138
0.72413793 0.93103448 1.13793103 1.34482759 1.55172414 1.75862069
1.96551724 2.17241379 2.37931034 2.5862069 2.79310345 3. ]
但是这个数据还不能直接作为python线性回归算法库的输入,输入需要是一个矩阵,就是二维数组。利用Python语言的特性,转换成一个二维数组:
>>> x = [[i] for i in x]
>>> y = [[i] for i in y]
>>> print(x)
[[-3.0], [-2.793103448275862], [-2.586206896551724], [-2.3793103448275863], [-2.1724137931034484], [-1.9655172413793103], [-1.7586206896551724], [-1.5517241379310345], [-1.3448275862068966], [-1.1379310344827587], [-0.9310344827586206], [-0.7241379310344827], [-0.5172413793103448], [-0.31034482758620685], [-0.10344827586206895], [0.10344827586206895], [0.31034482758620685], [0.5172413793103448], [0.7241379310344827], [0.9310344827586206], [1.137931034482759], [1.3448275862068968], [1.5517241379310347], [1.7586206896551726], [1.9655172413793105], [2.1724137931034484], [2.3793103448275863], [2.586206896551724], [2.793103448275862], [3.0]]
这样就可以进行训练了:
>>> from sklearn import linear_model
>>> model = linear_model.LinearRegression()
>>> model.fit(x,y)
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)
训练完成后,需要对结果进行预测:
>>> x_=[[1],[2]]
>>> model.predict(x_)
array([[3.],
[5.]])
确实得到了与传入y=2*x+1函数进行计算的正确结果。可以直接查看这条直线的斜率和截距:
>>> print(model.coef_)
[[2.]]
>>> print(model.intercept_)
[1.]
刚才使用的数据过于理想,实际数据不可能是这样精确的一条直线,没有任何偏差,为了模拟这个过程,引入随机扰动:
>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> x = np.linspace(-3,3, 30)
>>> y = 2*x +1
>>> x = x+np.random.rand(30)
>>> plt.scatter(x, y)
<matplotlib.collections.PathCollection object at 0x014DA6B8>
>>> plt.show()
random.rand会随机产生30个0到1之间的扰动。
>>> print(x)
[-2.16144777 -2.76506089 -2.32159976 -1.84251162 -1.72781795 -0.97250097
-1.64947717 -1.2628163 -1.00404317 -1.11145524 -0.62903975 -0.47164274
0.47264047 0.64308539 0.6206358 0.50142541 1.14480243 1.08690082
1.34787022 1.88569334 1.66215232 2.11401431 1.72883373 1.91215144
2.31214991 2.5244596 2.61453155 3.04187951 3.01564882 3.39603272]
采用前面的步骤,可以看到训练后的预测效果,就不是很准确了(斜率还可以,截距不准了):
>>> x = [[i] for i in x]
>>> y = [[i] for i in y]
>>> from sklearn import linear_model
>>> model = linear_model.LinearRegression()
>>> model.fit(x,y)
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)
>>> x_=[[1],[2]]
>>> model.predict(x_)
array([[2.04145197],
[4.00713494]])
>>> print(model.coef_)
[[1.96568298]]
>>> print(model.intercept_)
[0.07576899]
参考资料:
《机器学习算法的数学解析与Python实现》