机器学习-8.线性回归
Posted wyply115
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了机器学习-8.线性回归相关的知识,希望对你有一定的参考价值。
1. 概述
- 定义:线性回归通过一个或多个自变量(理解为特征)与因变量(理解为目标值)之间进行建模的回归分析。其中可以为一个或多个自变量之间的线性组合(线性回归的一种)。
- 一元线性回归:涉及到的变量只有一个。
- 多元线性回归:涉及到的变量两个或两个以上。
- 通用公式:
h
(
w
)
=
w
0
+
w
1
x
1
+
w
2
x
2
+
.
.
.
=
w
T
x
h(w)=w_0+w_1x_1+w_2x_2+... = w^Tx
h(w)=w0+w1x1+w2x2+...=wTx
其中w,x为矩阵:
w = ( w 0 w 1 w 2 ) , x = ( 1 x 1 x 2 ) w=\\left(\\beginmatrixw_0\\\\w_1\\\\w_2\\endmatrix\\right),x=\\left(\\beginmatrix1\\\\x_1\\\\x_2\\endmatrix\\right) w=⎝⎛w0w1w2⎠⎞,x=⎝⎛1x1x2⎠⎞ - 假设只有单特征(面积)计算目标值(房价)
我们需要做的是找出一条线(是个迭代计算的过程),这条线和图中的点的误差最小,即损失函数最小。 - 损失函数(就是误差的平方和):
- 那么线性回归的目的就是:如何去求模型中的W,使得损失最小?
- 如何寻找这个W值,有两种求解方式:
- 正规方程(非重点):可以直接求到损失最低的点(但特征复杂时很难求出来)
- 梯度下降
- 正规方程(非重点):可以直接求到损失最低的点(但特征复杂时很难求出来)
2. 正规方程与梯度下降
- 正规方程API:sklearn.linear_model.LinearRegression
- 梯度下降API:sklearn.linear_model.SGDRegressor
- 案例:预测波士顿房价,数据集在sklearn.datasets.load_boston中获取,下面是影响房价的特征:
- 正规方程方式:
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
def linear():
'''
线性回归预测房价
:return: None
'''
# 获取数据
lb = load_boston()
# 分割数据
x_train, x_test, y_train, y_test = train_test_split(lb.data, lb.target, test_size=0.25)
# 标准化,这里特征值和目标值都必须进行标准化处理
std_1 = StandardScaler()
x_train = std_1.fit_transform(x_train)
x_test = std_1.transform(x_test)
std_2 = StandardScaler()
y_train = std_2.fit_transform(y_train.reshape(-1, 1))# 转换为2维数据
y_test = std_2.transform(y_test.reshape(-1, 1))
# estimator预测
# 正规方程求解方式预测结果
lr = LinearRegression()
lr.fit(x_train, y_train)
print(lr.coef_) # 回归系数,即W值
y_predict = lr.predict(x_test)
# 由于进行标准化了,所以y_predict需要转回来
y_predict = std_2.inverse_transform(y_predict)
print("测试集里每个房子的预测价格:", y_predict)
return None
if __name__ == '__main__':
linear()
输出结果部分截图:
- 梯度下降方式:
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import SGDRegressor
from sklearn.preprocessing import StandardScaler
def linear():
'''
线性回归预测房价
:return: None
'''
# 获取数据
lb = load_boston()
# 分割数据
x_train, x_test, y_train, y_test = train_test_split(lb.data, lb.target, test_size=0.25)
# 标准化,这里特征值和目标值都必须进行标准化处理
std_1 = StandardScaler()
x_train = std_1.fit_transform(x_train)
x_test = std_1.transform(x_test)
std_2 = StandardScaler()
y_train = std_2.fit_transform(y_train.reshape(-1, 1))# 转换为2维数据
y_test = std_2.transform(y_test.reshape(-1, 1))
# estimator预测
# 梯度下降求解方式预测结果
sgd = SGDRegressor()
sgd.fit(x_train, y_train)
print(sgd.coef_) # 回归系数,即W值
y_predict = sgd.predict(x_test)
# 由于进行标准化了,所以y_predict需要转回来
y_predict = std_2.inverse_transform(y_predict)
print("测试集里每个房子的预测价格:", y_predict)
return None
if __name__ == '__main__':
linear()
输出结果部分截图:
3. 回归性能评估
- 均方误差API:sklearn.metrics.mean_squared_error
- 以上面的案例中的梯度下降解法为基础,进行评估
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression, SGDRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
def linear():
'''
线性回归预测房价
:return: None
'''
# 获取数据
lb = load_boston()
# 分割数据
x_train, x_test, y_train, y_test = train_test_split(lb.data, lb.target, test_size=0.25)
# 标准化,这里特征值和目标值都必须进行标准化处理
std_1 = StandardScaler()
x_train = std_1.fit_transform(x_train)
x_test = std_1.transform(x_test)
std_2 = StandardScaler()
y_train = std_2.fit_transform(y_train.reshape(-1, 1))# 转换为2维数据
y_test = std_2.transform(y_test.reshape(-1, 1))
# estimator预测
# 梯度下降求解方式预测结果
sgd = SGDRegressor()
sgd.fit(x_train, y_train)
#print(sgd.coef_) # 回归系数,即W值
y_predict = sgd.predict(x_test)
# 由于进行标准化了,所以y_predict需要转回来
y_predict = std_2.inverse_transform(y_predict)
#print("测试集里每个房子的预测价格:", y_predict)
# 均方误差进行性能评估
mse = mean_squared_error(std_2.inverse_transform(y_test),y_predict)
print("均方误差为:", mse)
return None
if __name__ == '__main__':
linear()
输出结果:均方误差为: 29.37517305937515
4. 正规方程与梯度下降对比
5. 过拟合与欠拟合
- 问题:训练数据训练的很好啊,误差也不大,为什么在测试集上面有问题呢?
- 欠拟合:一个假设在训练数据上不能获得很好的拟合,但是在训练数据以外的数据集上也不能很好的拟合数据,此时认为这个假设出现了欠拟合现象。(模型过于简单)
下图所示,机器学习到的天鹅特征太少,导致区分标准太粗糙,不能准确识别出天鹅。
- 过拟合:一个假设在训练数据上能够获得比其他假设更好的拟合,但是在训练数据外的数据集上却不能很好的拟合数据,此时认为这个假设出现了过拟合现象。(模型过于复杂)
- 再比如下图所示,更直观的看出欠拟合和过拟合的情况。
- 欠拟合的原因:学到的数据的特征过少。
- 欠拟合解决办法:增加数据的特征数量。
- 过拟合原因:原始特征过多,存在一些嘈杂特征,模型过于复杂是因为模型尝试去兼顾各个测试数据点。
- 过拟合解决办法:
- 进行特征选择,消除关联性大的特征(很难做)
- 交叉验证(让所有数据都有过训练)
- L2正则化
- 正则化解决过拟合的思想:不断尝试减少高次项特征的权重,趋近于0。
- L2正则化作用:可以使得W的每个元素都很小,都接近于0。
- 优点:越小的参数说明模型越简单,越简单的模型则越不容易产生过拟合现象。
6. Ridge岭回归(带有正则化的线性回归)解决过拟合
- API:sklearn.linear_model.Ridge
alpha取值,根据经验通常情况下会取:0到1之间的小数,或者1-10之间的整数。
官网给出的正则化力度和权重之间的关系图:正则化力度越大,权重越来越趋近于0(不会等于0)
- 案例:同上面的波士顿房价一样。
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Ridge
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
def linear():
'''
线性回归预测房价
:return: None
'''
# 获取数据
lb = load_boston()
# 分割数据
x_train, x_test, y_train, y_test = train_test_split(lb.data, lb.target, test_size=0.25)
# 标准化,这里特征值和目标值都必须进行标准化处理
std_1 = StandardScaler()
x_train = std_1.fit_transform(x_train)
x_test = std_1.transform(x_test)
std_2 = StandardScaler()
y_train = std_2.fit_transform(y_train.reshape(-1, 1))# 转换为2维数据
y_test = std_2.transform(y_test.reshape(-1, 1))
# 岭回归进行房价预测
rd = Ridge(alpha=1.0) #alpha为超参数,可通过网格搜索找到更合适的值
rd.fit(x_train, y_train)
#print(rd.coef_) # 回归系数,即W值
y_predict = rd.predict(x_test)
# 由于进行标准化了,所以y_predict需要转回来
y_predict = std_2.inverse_transform(y_predict)
#print("测试集里每个房子的预测价格:", y_predict)
# 均方误差进行性能评估
mse = mean_squared_error(std_2.inverse_transform(y_test), y_predict)
print("均方误差为:", mse)
return None
if __name__ == '__main__':
linear()
输出:均方误差为: 33.48485484981214
- 线性回归LinearRegression与Ridge对比:
- 岭回归得到的回归系数更符合实际,更可靠。另外,能让估计参数的波动范围变小,变的更稳定。在存在病态数据偏多的研究中有较大的实用价值。
以上是关于机器学习-8.线性回归的主要内容,如果未能解决你的问题,请参考以下文章