补充:
分类算法:是一种对离散型随机变量建模或预测的监督学习算法。使用案例包括邮件过滤、金融欺诈和预测雇员异动等输出为类别的任务。许多回归算法都有与其相对应的分类算法,分类算法通常适用于预测一个类别(或类别的概率)而不是连续的数值。
简而言之:分类算法用于目标值是离散型的。
回归算法:回归方法是一种对数值型连续随机变量进行预测和建模的监督学习算法。使用案例一般包括房价预测、股票走势或测试成绩等连续变化的案例。
回归任务的特点是标注的数据集具有数值型的目标变量。也就是说,每一个观察样本都有一个数值型的标注真值以监督算法。
简而言之:回归算法用于目标值是连续型的。
例如:能不能得到银行贷款可以使用分类算法,而贷款的额度就可以用回归算法。
线性回归
由图可知:线性回归就是寻找一种可以预测的趋势。
从函数角度来说就是找到一个合适的y=kx b函数, b表示偏置,当有多个特征是时候变成 y =k1*x1 k2*x2 b,以此类推。
线性回归就是找到合适的k1和k2。(y表示目标,x1,x2..表示特征值,b表示偏置常用w0表示,k1,k2...表示权重常用w表示)
那么线性关系模型就是: f(x) = w1*x1 w2*x2 ... w0
定义:线性回归通过一个或多个自变量与因变量之间进行建模的回归分析。
一元线性回归:涉及到的变量(特征)只有一个。
多元线性回归:涉及到的变量(特征)是多个。
权重存在多个,属性(特征)也有多个,这里需要引入矩阵的概念。
矩阵就是为了满足特定的运算需求而来。
w(权重)的矩阵就是w0,w1,w2....
x(特征)的矩阵就是1,x1,x2....
矩阵相乘变成:
h(w) = w0*1 w1*x1 w2*x2 ...就是线性关系模型。
由上图也可以知道这种预测是不可能100%的预算准确,在分类问题中用准确率来评估一个算法预测的好坏。
在回归算法中,用损失函数(误差大小)来评估。也称之为最小二乘法。
公式为:
简而言之:每个预测的结果减去真实结果的平方和。
如何找到最优的权重值(也就是损失函数的最小值)是需要一步一步的迭代计算得来。
计算的方式:
1、最小二乘法的正规方程(一次直接找到损失函数最小值从而找到最优权重,不通用)
计算模块:
sklearn.linear_model.LinearRegression
2、最小二乘法的梯度下降(一点一点改变权重值找到最优权重)
计算模块:
sklearn.linear_model.SGDRegressor
实例:
波士顿房价预测
数据来源:scikit-learn中自带数据集
数据详情:
属性 解释
CRIM 该镇犯罪率
ZN 住宅占地比率
INOUS 非零售商业用地比例
CHAS 位置的好坏
NOX 一氧化碳浓度
RM 每栋楼平均客房数
AGE 1940年前建成的单位比例
DIS 距离就业中心的加权距离
RAD 径向公路可达指数
TAX 财产税率
RTRAIO 学生和教师比例
B 黑人占比
LATAT 低收入人群比例
MEDV 同类房屋价格的中位数
目标:求出13个权重值。得出预测房价
整理思路:
1、数据获取
2、数据分割
3、训练与测试数据标准化
4、使用LinearRegression和SGDRegressor进行对比预测。
代码:
代码语言:javascript复制# 导出数据
from sklearn.datasets import load_boston
# 导入线性回归算法
from sklearn.linear_model import LinearRegression, SGDRegressor,Ridge
# 导入分割数据集
from sklearn.model_selection import train_test_split
# 导入标准化
from sklearn.preprocessing import StandardScaler
# 导入均方误差模块
from sklearn.metrics import mean_squared_error
def mylinear():
# 获取数据
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)
# 目标值标准化,0.18以上要求数据为二维,这里目标值为一维需要转换
std_y = StandardScaler()
y_train = std_y.fit_transform(y_train.reshape(-1,1))
y_test = std_y.transform(y_test.reshape(-1,1))
# 回归预测
# 正规方程预测
lr = LinearRegression()
lr.fit(x_train,y_train)
# 打印权重参数
print(lr.coef_)
# 预测房价结果,这里为标准化的值,还需要使用inverse_transform转化
y_lr_predict = std_y.inverse_transform(lr.predict(x_test))
print("正规方程预测测试集的房价为:",y_lr_predict)
'''
数据较多,截取部分:
[[-0.12157973 0.11723016 0.02835006 0.12766732 -0.25491009 0.23101974
0.00070696 -0.3238203 0.3036738 -0.19670105 -0.23052557 0.09048442
-0.44183499]]
正规方程预测测试集的房价为: [[22.59139843]
[22.13524512]
[24.98056613]
[13.78823607]
[29.75290977]
[20.46082081]
'''
# 梯度下降进行预测
sgd = SGDRegressor()
sgd.fit(x_train,y_train)
# 打印权重参数
print(sgd.coef_)
# 预测房价结果,这里为标准化的值,还需要使用inverse_transform转化
y_sgd_predict = std_y.inverse_transform(sgd.predict(x_test))
print("梯度下降预测测试集的房价为:",y_sgd_predict)
'''
[-0.06787717 0.06950101 -0.05363521 0.07500903 -0.11281586 0.35603079
-0.01215854 -0.22425126 0.0763868 -0.05216806 -0.2198393 0.09826212
-0.33527296]
梯度下降预测测试集的房价为: [20.25084059 26.56297835 25.26518906 26.69280554 18.04244274 23.68836509
26.1134737 12.70430044 39.9574648 16.99725142 22.80953768 35.03861297
'''
# 均方误差计算回归性能
print("正规方程的均方误差:",mean_squared_error(std_y.inverse_transform(y_test),y_lr_predict))
print("梯度下降的均方误差:",mean_squared_error(std_y.inverse_transform(y_test),y_sgd_predict))
'''
正规方程的均方误差: 33.299367980869704
梯度下降的均方误差: 36.10472557919503
说明正规方程效果要好一点。
'''
if __name__ == "__main__":
mylinear()
回归性能评估
公式:
模块:
mean_squared_error(y_true,y_pred)
y_true:真实值
y_pred:预测值
欠拟合和过拟合
欠拟合:
在训练数据上不能获得更好的拟合,在测试的数据上也不能更好的拟合数据这种现象称之为欠拟合现象。
(模型过于简单)
原因:学习的特征过少
解决方法:
增加数据的特征数量
过拟合:在训练数据上能够获得很好的拟合,但是在训练集以外的数据不能很好地拟合数据,这种称之为过拟合。
(模型过于复杂)
对线性模型进行训练学习就会变成复杂模型,可能从原来的线性关系,变成非线性关系(曲线)。
原因:原始特征过多,存在影响特征
解决方法:
进行特征选择,消除关联性大的特征
交叉验证
正则化
如何判断是过拟合还是欠拟合:
1、根据定义现象判断
2、交叉验证,在交叉验证的时候效果很好,在训练集表现不好就是过拟合
二者表现都不好就是欠拟合
既然线性回归容易出现过拟合,就出现了岭回归(带有l2正则化的线性回归)来解决过拟合
岭回归
什么是正则化
简而言之:将复杂的权重做趋近于零处理
模块:
sklearn.linera_model.Ridge(alpha=1.0)
alpha:正则化力度
正则化的力度越大,权重越趋近于零。
实例:
同样是上面的例子,来添加岭回归。
添加如下代码:
代码语言:javascript复制# 导入线性回归算法
from sklearn.linear_model import LinearRegression, SGDRegressor,Ridge
# mylinear添加如下代码
# 岭回归预测
rd = Ridge()
rd.fit(x_train,y_train)
# 打印权重参数
print(rd.coef_)
# 预测房价结果,这里为标准化的值,还需要使用inverse_transform转化
y_rd_predict = std_y.inverse_transform(rd.predict(x_test))
print("岭回归预测测试集的房价为:",y_rd_predict)
print("岭回归的均方误差:",mean_squared_error(std_y.inverse_transform(y_test),y_rd_predict))
'''
[[-0.0632925 0.12363312 0.01722252 0.05482988 -0.24365054 0.27211061
0.01847566 -0.31955953 0.28390266 -0.20539899 -0.23716384 0.09414787
-0.41097606]]
岭回归预测测试集的房价为: [[ 7.896142 ]
[30.8306591 ]
...
岭回归的均方误差: 15.389314479161092
'''
岭回归:回归得到的值更符合实际,更加可靠,能让估计参数的波动范围变小,更加稳定。