线性关系模型
一个通过属性的线性组合来进行预测的函数:
线性回归
定义: 线性回归通过一个或者多个自变量与因变量之间进行建模的回归分析。其中可以为一个或多个自变量之间的线性组合(线性回归的一种)
一元线性回归:涉及到的变量只有一个
多元线性回归:涉及到的变量两个或两个以上
最小二乘法
损失函数(误差大小)
总损失定义:
又称,最小二乘法
yi为第i个训练样本的真是值,hw(xi)为第i个训练样本特征值组合预测函数
最小二乘法之梯度下降:
最小二乘法之正规方程:
sklearn线性回归正规方程API:sklearn.linear_model.LinearRegression
sklearn线性回归梯度下降API:sklearn.linear_model.SGDRegressor
回归性能评估
LinearRegression与SGDRegressor评估
梯度下降(SGDRegressor) | 正规方程(LinearRegression) |
需要学习率α | 不需要 |
需要多次迭代 | 一次运算得出 |
当特征数量大时也能较好适用 | 需要计算 如果特征数量较大则运算代价大,因为矩阵逆的计算时间复杂度,通常当n<10000时还可以接受 |
适用于各种类型的模型 | 只适用于线性模型,不适合逻辑回归模型等其他模型 |
sklearn回归评估API:sklearn.metrics.mean_squared_error
注:真实值,预测值为标准化之前的值
特点:
线性回归是最为简单、易用的回归模型。从某种程度上限制了使用,尽管如此,在不知道特征之间关系的前提下,我们仍然使用线性回归作为首要选择。
小规模数据:LinearRegression(不能解决拟合问题以及其他)
大规模数据:SGDRegressor
欠拟合与过拟合
欠拟合:
一个假设在训练数据上不能够获得更好的拟合,但是在训练数据外的数据集上也不能很好的拟合数据,此时认为这个假设出现了欠拟合的现象(模型过于简单)。
原因:学习到数据特征过少
解决办法:增加数据的特征数量
过拟合:
一个假设在训练数据上能够获得比其他假设更好的拟合,但是在训练数据外的数据集上却不能很好的拟合数据,此时认为这个假设出现了过拟合现象(模型过于复杂)。
原因:原始特征过多,存在一些嘈杂特征;模型过于复杂是因为模型尝试去兼顾各个测试数据点
解决办法:1、进行特征选择,消除关联性大的特征;2、交叉验证(让所有数据都有过训练);3、正则化
L2正则化
作用:可以使得每个元素都很小,都接近于0
优点:越小的参数说明模型越简单,越简单的模型则越不容易产生过拟合现象
sklearn带有正则化的线性回归API:sklearn.linear_model.Ridge
岭回归:回归得到的回归系数更符合实际,更可靠。另外,能让估计参数的波动范围变小,变得更稳定。在存在病态数据偏多的研究中有较大的使用价值。
# -*- coding: utf-8 -*-
from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_absolute_error
def my_regression():
"""
回归预测房价
: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_x = StandardScaler()
x_train = std_x.fit_transform(x_train)
x_test = std_x.transform(x_test)
std_y = StandardScaler()
y_train = std_y.fit_transform(y_train.reshape(-1, 1))
y_test = std_y.transform(y_test.reshape(-1, 1))
# print(std_y.inverse_transform(y_test)) # 还原原来的数值
# estimator估计
"""线性回归之正规方程求解"""
lr = LinearRegression()
lr.fit(x_train, y_train)
# print(lr.coef_)
# 这个预测值是比较小的结果,因为标准化之后,如果想要得到正常房子的价格,通过inverse_transform
y_lr_predict = lr.predict(x_test)
# 评价回归模型的结果, 把预测结果和真实结果没有标准化之前的进行分对比
result = mean_absolute_error(std_y.inverse_transform(y_test), std_y.inverse_transform(y_lr_predict))
print("lr正规方程求解的均方误差为:", result)
"""线性回归之梯度下降求解"""
sgd = SGDRegressor()
sgd.fit(x_train, y_train)
# print(sgd.coef_)
y_sgd_predict = sgd.predict(x_test)
result = mean_absolute_error(std_y.inverse_transform(y_test), std_y.inverse_transform(y_sgd_predict))
print("sgd梯度下降求解的均方误差为:", result)
"""带有L2正则化的线性回归"""
rd = Ridge(alpha=1.0)
rd.fit(x_train, y_train)
y_rd_predict = rd.predict(x_test)
result = mean_absolute_error(std_y.inverse_transform(y_test), std_y.inverse_transform(y_rd_predict))
print("L2正则化求解的均方误差为:", result)
if __name__ == '__main__':
my_regression()