线性回归
利用大量的样本数据,通过监督学习,学习到X到Y的映射f, 利用该映射关系对未知数据进行预测。因为y是连续的所以是回归
线性回归的表达式
假设函数 :
使用向量表示(X, 都是向量):
损失函数:
利用损失函数来衡量,损失函数度量预测值和标准答案的偏差,不同的参数有不同的偏差,
所以要通过最小化损失函数,也就是最小化偏差来得到最好的参数。
因为有m个样本,所以要平均,分母的2是为了求导方便
该函数就是一个二次函数,是一个凸函数,图像如下
代价函数也有可能是这样的,存在局部最优解
损失函数的优化
那么接下来就是对损失函数的优化,可以利用数学的极值思想,求导数等于0的值就找到了这个极值点,但是这个
方法在工业上会有相当大的计算量,因此在工业上实际是使用的梯度下降法,又称最速下降法。
梯度下降法:
1.逐步最小化损失函数的过程
2.初始位置选取很重要
3.θ的更新如公式,每个参数都是分别更新的
4.高维情况, 梯度方向就是垂直于登高线的方向
梯度下降公式如下:
循环直到收敛 {
}
一元线性回归,梯度下降如下:
多元线性回归,梯度下降如下:
(
)
.....
影响梯度下降的因素:
1.对于多个参数如果其数据集相差很大,应该将多个参数集归一化到一个数据集上,这样利于使用梯度下降,不然在
梯度下降过程中很容易走出z字形
参数归一化可以将数据数据归一到(0,1)这个区间内
2.学习率,这个太大导致不能收敛,太小导致梯度下降缓慢,一般可取0.01, 0.001, ..., 然后使用交叉验证来寻找最优的学习率
在学习的过程中容易出现,欠拟合,过拟合
欠拟合:
模型没有很好地捕捉到数据特征,不能够很好地拟合数据
解决方法:
1.添加其他特征项,模型出现欠拟合的时候是因为特征项不够导致的,可以添加其他特征项来很好地解决。
2.添加多项式特征,例如将线性模型通过添加二次项或者三次项使模型泛化能力更强。
3.减少正则化参数,正则化的目的是用来防止过拟合的,当模型出现了欠拟合,则需要减少正则化参数。
过拟合:
1.如果我们有很多的特征或模型很复杂,则假设函数曲线可以对训练样本拟合的非常好,学习能力太强了,但是丧失了一般性。
2.眼见不一定为实,训练样本中肯定存在噪声点,如果全都学习的话肯定会将噪声也学习进去。
过拟合造成什么结果:
过拟合是给参数的自由空间太大了,可以通过简单的方式让参数变化太快,并未学习到底层的规律,模型抖动太大,很不稳定,variance变大,对新数据没有泛化能力。
解决办法:
1.利用正则化解决
2.重新清洗数据,导致过拟合的一个原因也有可能是数据不纯导致的, 如果出现了过拟合就需要我们重新清洗数据。
3.增大数据的训练量,之前用于训练的数据量太小导致的,训练数据占总数据的比例过小。
正则化的作用:
a.控制参数变化幅度,对变化大的参数惩罚
b.限制参数搜索空间
添加正则化的损失函数:
m:样本有m个
n:n个参数,对n个参数进行惩罚:对误差的惩罚程度,λ越大对误差的惩罚越大,容易出现过拟合,λ越小,对误差的惩罚越小,对误差的容忍度越大,泛化能力好。
实现线性回归
在实际实现算法时,要注意对数据的运算进行向量化处理,慎用循环。因为在训练的过程中会运行大量的数据,在参数很多的情况下实际的运行速度很慢,因此要进行向量化处理。
具体实现代码如下:
'''多元一次线性回归'''
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
def computeCost(X, Y, theta):
'''
计算真实值与预测值间的误差
X: 要预测的数据列表
Y: label列表
theta: 参数列表
'''
# 向量化处理
# (m, n)
X = np.matrix(X).T
# (m, 1)
Y = np.matrix(Y).T
# (n, 1)
theta = np.matrix(theta).T
m = X.shape[1]
if m != theta.shape[0]:
'''如果维度不一致就报错'''
raise RuntimeError('维度不一致')
temp = np.dot(X, theta) - Y
total = (1/(2*X.shape[0])) * np.sum(np.power(temp, 2))
return total
# 训练数据量与模型之间应该有什么关系,是越多越好吗?
def gradientDescent(X, Y, theta, alpha, iters):
'''
梯度下降
X: 要预测值的数据列表
Y: label列表
theta: 参数列表
alpha: 学习率
iters: 迭代次数
'''
'''对数据进行向量化处理'''
# (m, n)
X = np.matrix(X)
# (m, 1)
Y = np.matrix(Y)
# (n, 1)
theta = np.matrix(theta).T
m = X.shape[0]
for i in range(iters):
temp = np.dot(X, theta) - Y
temp1 = np.multiply(temp, X)
temp2 = np.sum(temp1, axis=0)
theta = theta - (alpha/m) * temp2.T
return theta
# 加载数据
path = 'data.txt'
data = pd.read_csv(path, header=None, names=['x', 'y'])
data.head()
data.insert(0, 'x0', 1)
data.head()
# 准备数据
cols = data.shape[1]
X = data.iloc[:,0:cols-1]#X是所有行,去掉最后一列
Y = data.iloc[:,cols-1:cols]#X是所有行,最后一列
theta = np.array([0, 0])
alpha = 0.01
iters = 1000
# 开始训练模型
g = gradientDescent(X, Y, theta, alpha, iters).T
print(g)
x = np.linspace(data.x.min(), data.x.max(), 100)
f = g[0,0] + (g[0,1] * x)
fig, ax = plt.subplots(figsize=(12,8))
ax.plot(x, f, 'r', label='Prediction')
ax.scatter(data.x, data.y, label='Traning Data')
ax.legend(loc=2)
ax.set_xlabel('x')
ax.set_ylabel('y')
plt.show()