机器学习算法-线性回归
1.K-近邻算法
(略)
2.线性回归
2.1线性回归简介
1.线性回归应用场景
- 房价预测
- 销售额度预测
- 贷款额度预测
2.什么是线性回归
2.1定义与公式
线性回归(Linear regression)是利用回归方程(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方法.
特点:只有一个自变量的情况称为单变量回归,多于一个自变量情况叫做多元回归
通用公式:
h
(
w
)
=
w
1
x
1
+
w
2
x
2
+
w
3
x
3
.
.
.
+
b
=
w
T
x
+
b
h(w)=w_1x_1+w_2x_2+w_3x_3...+b=w^Tx+b
h(w)=w1x1+w2x2+w3x3...+b=wTx+b
其中w,x可以理解为矩阵:
w
=
(
b
w
1
w
2
)
,
x
=
(
1
x
1
x
2
)
w=\bigg( \begin{smallmatrix} b\\w_1\\w_2 \end{smallmatrix} \bigg),x=\bigg( \begin{smallmatrix} 1\\x_1\\x_2 \end{smallmatrix} \bigg)
w=(bw1w2),x=(1x1x2)
-
线性回归用矩阵表示举例
{ 1 × x 1 + x 2 = 2 0 × x 1 + x 2 = 2 2 × x 1 + x 2 = 3 \left\{ \begin{matrix} 1 \times x_1 + x_2=2\\ 0 \times x_1 + x_2=2\\ 2 \times x_1 + x_2=3 \end{matrix} \right. ⎩ ⎨ ⎧1×x1+x2=20×x1+x2=22×x1+x2=3 -
写成矩阵形式:
[ 1 1 0 1 2 1 ] [ x 1 x 2 ] = [ 2 2 3 ] ↑ ↑ ↑ A × x = b \left[\begin{matrix}1&1\\0&1\\2&1\end{matrix}\right] \left[\begin{matrix}x_1\\x_2\end{matrix}\right] =\left[\begin{matrix}2\\2\\3\end{matrix}\right]\\ \uparrow \quad \quad \quad \uparrow \quad \quad \quad \uparrow\\ A \quad \times \quad x\quad = \quad b 102111 [x1x2]= 223 ↑↑↑A×x=b
2.2线性回归api初步使用
code
from sklearn.linear_model import LinearRegression
# 1.获取数据
X = [[80, 86],
[82, 80],
[90, 90],
[85, 78],
[86, 82],
[82, 90],
[78, 80],
[92, 94]
]
y = [84.2, 80.6, 80.1, 90, 83.2, 86.6, 79.4, 93.4]
# 2.模型训练
# 2.1实例化一个估计器
estimator = LinearRegression()
# 2.2使用fit方法进行训练
estimator.fit(X, y)
# 打印对应的系数
print("线性回归的系数是:\n", estimator.coef_)
# 打印预测结果
print("输出预测结果:\n", estimator.predict([[100, 80]]))
# D:\Python\Python311\python.exe D:\work\pyprj\ml\linser_demo.py
# 线性回归的系数是:
# [0.41212411 0.13044053]
# 输出预测结果:
# [90.47473664]
2.3数学:求导
1、常见的函数导数
n 公式 例子 1 ( 常数 ) ′ = 0 ( 5 ) ′ = 0 ( 10 ) ′ = 0 2 ( x a ) ′ = a x a − 1 ( x 3 ) ′ = 3 x 2 3 ( a x ) ′ = a x l n a ( 2 x ) ′ = 2 x l n 2 4 ( e x ) ′ = e x ( e x ) ′ = e x 5 ( l o g a x ) ′ = 1 x l n a ( l o g 10 x ) ′ = 1 x l n 10 6 ( l n x ) ′ = 1 x ( l n x ) ′ = 1 x 7 ( s i n x ) ′ = c o s x ( s i n x ) ′ = c o s x 8 ( c o s x ) ′ = − s i n x ( c o s x ) ′ = − s i n x \begin{array} {|c|l|l|} \hline n & \text{公式} & \text{例子} \\ \hline 1 & (常数)'=0 & (5)'=0 (10)'=0 \\ \hline 2 & (x^a)'=ax^{a-1} & (x^3)'=3x^2 \\ \hline 3 & (a^x)'=a^xlna & (2^x)'=2^xln2 \\ \hline 4 & (e^x)'=e^x & (e^x)'=e^x\\ \hline 5 & (log_ax)'= \frac{1}{xlna} & (log_{10}x)'= \frac{1}{xln10}\\ \hline 6 & (lnx)'= \frac{1}{x} & (lnx)'= \frac{1}{x}\\ \hline 7 & (sinx)'= cosx & (sinx)'= cosx \\ \hline 8 & (cosx)'= -sinx & (cosx)'= -sinx\\ \hline \end{array} n12345678公式(常数)′=0(xa)′=axa−1(ax)′=axlna(ex)′=ex(logax)′=xlna1(lnx)′=x1(sinx)′=cosx(cosx)′=−sinx例子(5)′=0(10)′=0(x3)′=3x2(2x)′=2xln2(ex)′=ex(log10x)′=xln101(lnx)′=x1(sinx)′=cosx(cosx)′=−sinx
2、导数的四则运算
n 公 式 1 [ u ( x ) ± v ( x ) ] ′ = u ′ ( x ) ± v ′ ( x ) 2 [ u ( x ) ⋅ v ( x ) ] ′ = u ′ ( x ) ⋅ v ( x ) + u ( x ) ⋅ v ′ ( x ) 3 [ u ( x ) v ( x ) ] ′ = u ′ ( x ) ⋅ v ( x ) − u ( x ) ⋅ v ′ ( x ) v 2 ( x ) 4 { g [ h ( x ) ] } ′ = g ′ ( h ) ⋅ h ′ ( x ) \begin{array} {|c|l|} \hline n & \text{公 式} \\ \hline 1 & [u(x)\pm v(x)]'=u'(x)\pm v'(x) \\ \hline 2 & [u(x) \cdot v(x)]'=u'(x) \cdot v(x) + u(x) \cdot v'(x) \\ \hline 3 & [ \frac {u(x)} {v(x)} ]' = \frac {u'(x) \cdot v(x) - u(x) \cdot v'(x)} {v^2(x)} \\ \hline 4 & \{ g[h(x)]\}' = g'(h) \cdot h'(x) \\ \hline \end{array} n1234公 式[u(x)±v(x)]′=u′(x)±v′(x)[u(x)⋅v(x)]′=u′(x)⋅v(x)+u(x)⋅v′(x)[v(x)u(x)]′=v2(x)u′(x)⋅v(x)−u(x)⋅v′(x){g[h(x)]}′=g′(h)⋅h′(x)
3、练习
$$
\begin {array}{ll}
- & y=x3-2x2+sinx,求f(x)\
- & (e^x+4lnx)'\
- & (sinx * lnx)'\
- & (\frac {e^x} {cosx})'\
- & y=sin2x,求\frac {dy} {dx}\
\end{array}
$$
答案:
-
y ′ = ( x 3 − 2 x 2 + s i n x ) ′ = ( x 3 ) ′ − ( 2 x 2 ) ′ + ( s i n x ) ′ = 3 x 2 − 4 x + c o s x \begin{aligned} y' & =(x^3-2x^2+sinx)'\\ & =(x^3)'-(2x^2)'+(sinx)'\\ & =3x^2-4x+cosx\\ \end{aligned} y′=(x3−2x2+sinx)′=(x3)′−(2x2)′+(sinx)′=3x2−4x+cosx
-
( e x + 4 l n x ) ′ = ( e x ) ′ + ( 4 l n x ) ′ = e x + 4 x (e^x+4lnx)'=(e^x)'+(4lnx)'=e^x+\frac {4} {x} (ex+4lnx)′=(ex)′+(4lnx)′=ex+x4
-
( s i n x ⋅ l n x ) ′ = ( s i n x ) ′ ⋅ l n x + s i n x ⋅ ( l n x ) ′ = c o s x ⋅ l n x + s i n x ⋅ 1 x \begin{aligned} (sinx \cdot lnx)'& =(sinx)' \cdot lnx + sinx \cdot (lnx)'\\& =cosx \cdot lnx + sinx \cdot \frac {1} {x} \end{aligned} (sinx⋅lnx)′=(sinx)′⋅lnx+sinx⋅(lnx)′=cosx⋅lnx+sinx⋅x1
( e x c o s x ) ′ = ( e x ) ′ ⋅ c o s x − e x ⋅ ( c o s x ) ′ c o s 2 ( x ) = e x ⋅ c o s x − e x ⋅ ( − s i n x ) c o s 2 ( x ) (\frac {e^x} {cosx})'=\frac {(e^x)'\cdot cosx-e^x \cdot (cosx)' } {cos^2(x)}\\ =\frac {e^x \cdot cosx - e^x \cdot (-sinx)} {cos^2(x)} (cosxex)′=cos2(x)(ex)′⋅cosx−ex⋅(cosx)′=cos2(x)ex⋅cosx−ex⋅(−sinx)
( s i n 2 x ) ′ = c o s 2 x ⋅ ( 2 x ) ′ = 2 c o s 2 x (sin2x)'=cos2x \cdot (2x)' = 2cos2x (sin2x)′=cos2x⋅(2x)′=2cos2x
4、矩阵(向量)求导【了解】
参考连接:
https://handwiki.org/wiki/Matrix%20calculus#Matrix-by-scalar
2.4线性回归的损失和优化
1、损失函数
总损失函数定义为:
J
(
w
)
=
(
h
(
x
1
)
−
y
1
)
2
+
(
h
(
x
2
)
−
y
2
)
2
+
.
.
.
+
(
h
(
x
m
)
−
y
m
)
2
=
∑
i
=
1
m
(
h
(
x
i
)
−
y
i
)
2
\begin {aligned} J(w)&=(h(x_1)-y_1)^2+(h(x_2)-y_2)^2+...+(h(x_m)-y_m)^2\\ &=\sum_{i=1}^m(h(x_i)-y_i)^2 \end {aligned}
J(w)=(h(x1)−y1)2+(h(x2)−y2)2+...+(h(xm)−ym)2=i=1∑m(h(xi)−yi)2
. y i 为第 i 个训练样本的真实值 . h ( x i ) 为第 i 个训练样本特征值组合预测函数 . 又称为最少二乘法 \begin {array} {l} . y_i为第i个训练样本的真实值\\ . h(x_i)为第i个训练样本特征值组合预测函数\\ . 又称为最少二乘法 \end{array} .yi为第i个训练样本的真实值.h(xi)为第i个训练样本特征值组合预测函数.又称为最少二乘法
2、优化算法
如何区求模型当中的 W,使损失最小?(目的是找到最小损失对应的w值)
- 线性回归经常使用的两种算法
- 正规方程
- 梯度下降法
2.1 正规方程
2.1.1 什么是正规方程
W
=
(
X
T
X
)
−
1
X
T
y
W=(X^TX)^{-1}X^Ty
W=(XTX)−1XTy
理解:x为特征值矩阵,y为目标值矩阵。直接求到最好的结果
缺点:当特征过多过复杂时,求解速度太慢并且得不到结果
2.1.3 正规方程的推导
-
推导方式一:
把该损失函数换成矩阵写法:
J ( w ) = ( h ( x 1 ) 2 + ( h ( x 2 ) − y 2 ) 2 + . . . + ( h ( x m ) − y m ) 2 = ∑ i = 1 m ( h ( x i ) − y i ) 2 = ( X w − y ) 2 \begin{aligned} J(w) &=(h(x_1)^2+(h(x_2)-y_2)^2+...+(h(x_m)-y_m)2\\ &=\sum_{i=1}^m {}(h(x_i)-y_i)^2\\ &=(Xw-y)^2 \end{aligned} J(w)=(h(x1)2+(h(x2)−y2)2+...+(h(xm)−ym)2=i=1∑m(h(xi)−yi)2=(Xw−y)2
其中y是真实值矩阵,X是特征值矩阵,w是权重矩阵对其求解关于w的最小值,起止y,X均已知二次函数直接求导,导数为零的位置,即为最少值。
-
求导
2 ( X w − y ) ∗ X = 0 ⋯ ⋯ ( 1 ) 2 ( X w − y ) ∗ ( X X T ) = 0 X T ⋯ ⋯ ( 2 ) 2 ( X w − y ) ∗ ( X X T ) ( X X T ) − 1 = 0 X T ( X X T ) − 1 ⋯ ⋯ ( 3 ) 2 ( X w − y ) = 0 ⋯ ⋯ ( 4 ) X w = y ⋯ ⋯ ( 5 ) X T X w = X T y ⋯ ⋯ ( 6 ) ( X T X ) − 1 X T X w = ( X T X ) − 1 X T y ⋯ ⋯ ( 7 ) w = ( X T X ) − 1 X T y ⋯ ⋯ ( 8 ) \begin{aligned} 2(Xw-y)*X &=0 & \cdots \cdots(1)\\ 2(Xw-y)*(XX^T) &=0X^T& \cdots \cdots(2)\\ 2(Xw-y)*(XX^T)(XX^T)^{-1}&=0XT(XX^T)^{-1} & \cdots \cdots(3)\\ 2(Xw-y) &=0 &\cdots \cdots(4) \\ Xw &=y & \cdots \cdots(5)\\ X^TXw &= X^Ty & \cdots \cdots(6)\\ (X^TX)^{-1}X^TXw &= (X^TX)^{-1}X^Ty & \cdots \cdots(7)\\ w &= (X^TX)^{-1}X^Ty & \cdots \cdots(8)\\ \end{aligned} 2(Xw−y)∗X2(Xw−y)∗(XXT)2(Xw−y)∗(XXT)(XXT)−12(Xw−y)XwXTXw(XTX)−1XTXww=0=0XT=0XT(XXT)−1=0=y=XTy=(XTX)−1XTy=(XTX)−1XTy⋯⋯(1)⋯⋯(2)⋯⋯(3)⋯⋯(4)⋯⋯(5)⋯⋯(6)⋯⋯(7)⋯⋯(8)
注:式(1)到式(2)推导过程中,X是m行n列的矩阵,并不能保证其有逆矩阵,但是右乘X转置矩阵把其变为一个方阵。
- 推导方式二:
2.2 梯度下降(Gradient Descent)
2.2.1 什么是梯度下降
2.2.2 梯度的概念
梯度是微积分中一个很重要的概念
在单变量函数中,梯度其实就是函数的微分,代表函数在某个给定点的斜率
在多变量函数中,梯度是一个向量,向量有方向,梯度的方向指出了函数在给定点的上升最快的方向,梯度的反方向是函数在给定点下降最快的方向。
2.2.4 梯度下降(Gradient Descent)公式
θ
i
+
1
=
θ
i
−
a
ϑ
ϑ
θ
i
J
(
θ
)
\theta_{i+1}=\theta_i - a \frac{\vartheta}{\vartheta\theta_i}J(\theta)
θi+1=θi−aϑθiϑJ(θ)
-
a 是什么含义?
a在梯度下降算法中称作为学习率或者步长,意味着我们可以通过a来控制每一步走的距离,以保证不要步子太大,错过了最低点。同时也要保证不要走得太慢,导致迟迟不能到最低点。
-
为什么梯度要乘以一个负号
梯度前加一个负号,就意味朝着梯度相反的方向前进。
-
梯度下降和正规方程的对比
梯度下降 正规方程 需要选择学习率bu 不需要 需要迭代求解 一次运算得出 特征数量较大可以使用 需要计算方程,时间复杂度高O(n3) 3.1 算法选择依据
-
最小规模数据
- 正规方程:LinearRegression(不能解决拟合问题)
- 岭回归
-
大规模数据:
- 梯度下降法:SGDRegressor
4、小结
-
损失函数【知道】
- 最小二乘法
-
线性回归优化方法【知道】
- 正规方法
- 梯度下降法
-
正规方程–一蹴而就
- 利用矩阵的逆,转置进行一步求解
- 知识适合样本和特征比较少的情况
-
梯度下降法–循序渐进
-
梯度的概念
- 单变量-切线
- 多变量-向量
-
梯度下降法中关注的两个参数
-
a-步长
-
为何要加负号
-
-
2.5 梯度下降方法介绍
1、详解梯度下降算法
1.1 梯度下降的相关概念复习
-
步长(Learning rate)
-
特征(feature)
-
假设函数(hypothesis function)
-
损失函数(loss function)
-
为了评估模型拟合的好坏,通常用损失函数来度量拟合的程度。损失函数极小化,意味着拟合程度最好,对应的模型参数即为最优参数。
-
在线性回归中,损失函数通常为样本输出和假设函数的差的平方。比如对于m个样本(xi,yi)(i=1,2,…m),采用线性回归,损失函数为:
J ( θ 0 , θ 1 ) = ∑ i = 1 m ( h θ ( x i ) − y i ) 2 J(\theta_0,\theta_1)=\sum_{i=1}^{m}(h_\theta(x_i)-y_i)^2 J(θ0,θ1)=i=1∑m(hθ(xi)−yi)2$$
$$
其中 x i 表示第 i 个样本特征, y i 表示第 i 个样本对应的输出, h θ ( x i ) 为假设函数 . 其中x_i表示第i个样本特征,y_i表示第i个样本对应的输出,h\theta(x_i)为假设函数. 其中xi表示第i个样本特征,yi表示第i个样本对应的输出,hθ(xi)为假设函数.
1.2 梯度下降法的推导流程
1)先决条件:确认优化模型的假设函数和损失函数
2)算法相关参数初始化
3)算法过程
4)更新所有theta
-
2、梯度下降法大家族
- 全梯度下降算法(Full gradient descent)
- 随即梯度下降算法(Stochastic gradient descent)
- 小批量梯度下降算啊(Mini-batch gradient descent)
- 随机平均梯度下降算法(Stochastic average gradient descent)
2.6 线性回归api再介绍
- sklearn.linear_model.LinearRegression(fit_intercept=True)
- 通过正规方程优化
- 参数
- fit_intercept:是否计算偏差(截距)
- 属性
- LinearRegression.coef_:回归系数
- LinearRegression。intercept_:偏差(截距)
- sklearn.linear_model.SGDRegressor(loss=“squared_loss”,fit_intercept=True,learning_rate=‘invscaling’,eta0=0.01)
- SDGRegressor类实现了随即梯度下降学习,它支持不同的loss函数和正则化惩罚项来拟合线性回归模型
- 参数:
- loss:损失类型
- loss=“squared_loss":普通最小二乘法
- fit——intercept:是否计算偏差
- learning_rate:string,optional
- 学习率填充
- ‘constant’:eta=eta0
- ‘optimal’:eta=1.0/(alpha*(t+t0) ) [default]
- power_t=0.25:存在父类当中
- 对于一个常数值的学习率来说,可以使用learning_rate=‘constant’,并使用eta0来指定学习率
- 属性:
- SDGRegressor.coef_:回归系数
- SDGRegressor.intercept_: 偏差
- loss:损失类型
2.7 案例:波士顿房价预测
3、回归性能评估
均方误差(Mean Squared Error)(MSE)评价机制:
M
S
E
=
1
m
∑
i
=
1
m
(
y
i
−
y
‾
)
2
注:
y
i
为预测值,
y
‾
为真实值
MSE=\frac{1}{m}\sum_{i=1}^{m}(y^i-\overline y )^2\\ 注:y^i为预测值,\overline y为真实值
MSE=m1i=1∑m(yi−y)2注:yi为预测值,y为真实值
- sklearn.metrics.mean_squared_error(y_true,y_pred)
- 均方差回归损失
- y_true:真实值
- y_pred:预测值
- return:浮点数结果
4、代码实现
4.1正规方程
# coding:utf-8
"""
# 1、获取数据
# 2、数据基本处理
# 2.1 分割数据
# 3、特征工程-标准化
# 4、机器学习-线性回归
# 5、模型评估
"""
# def load_boston():
import pandas as pd
import numpy as np
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]
# boston = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :3]])
# print(d.shape)
# return (data,target)
#导入波士顿数据集
# 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
from sklearn.metrics import mean_squared_error
# 1、获取数据
def linear_model():
# 1、获取数据
# boston = load_boston()
# print(boston)
# 2、数据基本处理
# 2.1 分割数据
x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2)
# 3、特征工程-标准化
transfer= StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4、机器学习-线性回归
estimator = LinearRegression()
estimator.fit(x_train, y_train)
print("这个模型的偏置是:\n",estimator.intercept_)
print("这个模型的系数是:\n",estimator.coef_)
# 5、模型评估
# 5.1 预测值
y_pre = estimator.predict(x_test)
print("预测值是:\n",y_pre)
#5.2 均方误差
ret = mean_squared_error(y_test, y_pre)
print("均方误差:\n",ret)
# 2、数据基本处理
# 2.1 分割数据
# 3、特征工程-标准化
# 4、机器学习-线性回归
# 5、模型评估
linear_model()
4.2梯度下降法
# coding:utf-8
"""
# 1、获取数据
# 2、数据基本处理
# 2.1 分割数据
# 3、特征工程-标准化
# 4、机器学习-线性回归
# 5、模型评估
"""
#导入波士顿数据集
# from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import SGDRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
# def load_boston():
import pandas as pd
import numpy as np
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]
# boston = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :3]])
# print(d.shape)
# return (data,target)
#正规方程
def linear_model1():
# 1、获取数据
# boston = load_boston()
# print(boston)
# 2、数据基本处理
# 2.1 分割数据
x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2)
# 3、特征工程-标准化
transfer= StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4、机器学习-线性回归
estimator = LinearRegression()
estimator.fit(x_train, y_train)
print("这个模型的偏置是:\n",estimator.intercept_)
print("这个模型的系数是:\n",estimator.coef_)
# 5、模型评估
# 5.1 预测值
y_pre = estimator.predict(x_test)
print("预测值是:\n",y_pre)
#5.2 均方误差
ret = mean_squared_error(y_test, y_pre)
print("均方误差:\n",ret)
#梯度下降法
def linear_model2():
# 1、获取数据
# boston = load_boston()
# print(boston)
# 2、数据基本处理
# 2.1 分割数据
x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2)
# 3、特征工程-标准化
transfer= StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4、机器学习-线性回归
# estimator = LinearRegression()
estimator = SGDRegressor(max_iter=1000)
estimator.fit(x_train, y_train)
print("这个模型的偏置是:\n",estimator.intercept_)
print("这个模型的系数是:\n",estimator.coef_)
# 5、模型评估
# 5.1 预测值
y_pre = estimator.predict(x_test)
print("预测值是:\n",y_pre)
#5.2 均方误差
ret = mean_squared_error(y_test, y_pre)
print("均方误差:\n",ret)
# linear_model1()
linear_model2()
我们尝试修改学习率
estimator = SGDRegressor(max_iter=1000, learning_rate="constant", eta0=0.001)
此时我们可以通过调整参数,找到学习率更好的值。
2.8 欠拟合和过拟合
1、定义
- 过拟合:一个假设在训练数据上能够获得比其他假设更好的拟合,但是在测试数据集上却不能很好地拟合数据,此时认为这个假设出现了过拟合的现象.(模型过于复杂)
- 欠拟合:一个假设在训练数据上不能获得更好的拟合,并且在测试数据集上也不能很好地拟合数据,此时认为这个假设出现了欠拟合的现象.(模型过于简单)
2、原因以及解决办法
- 欠拟合原因以及解决办法
- 原因:学习到数据的特征过少
- 解决办法:
- 1)添加其他特征项
- 2)添加多项式特征
- 过拟合原因以及解决办法
- 原因:原因特征过多,存在一些嘈杂特征,模型过于复杂是因为模型尝试去兼顾各个测试数据点
- 解决办法:
- 1)重新清洗数据,导致过拟合的一个原因也有可能是数据不纯导致
- 2)增大数据的训练量,还有一个原因是训练的数量太少,训练数据占总数的比例过少
- 3)正则化
- 4)减少特征维度,放置维灾难
3、正则化
3.1 什么是正则化
在解决回归过拟合中,我们选择正则化。但是对于机器学习算法如分类算法来说也会出现这样的问题,除了一些算法本身之外(决策树、神经网络),我们更多的也是去自己做特征选择,包括之前说的删除、合并一些特征。
3.2 正则化类别
- L2正则化
- 作用:可以使其中一些W的值都很少,都接近于0,削弱某个特征的影像
- 优点:越少的参数说明模型越简单,越简单的模型则越不容易产生过拟合现象
- Ridge回归
- L1正则化
- 作用:可以使得其中一些w的值直接维0,删除这个特征的影像
- LASSO回归
2.9 正则化线性模型
1、Ridge Regression(岭回归,又名Tikhonov regularization)
岭回归是线性回归的正则版本,即在原来的线性回归的cost function中添加正则项(regularization term)
a
∑
i
=
1
n
θ
i
2
a\sum_{i=1}^n\theta_i^2
ai=1∑nθi2
已达到在拟合数据的同时,使模型权重尽可能小的目的,岭回归代价函数:
J
(
θ
)
=
M
S
E
(
θ
)
+
a
∑
i
=
1
n
θ
i
2
J(\theta)=MSE(\theta)+a\sum_{i=1}^n\theta_i^2
J(θ)=MSE(θ)+ai=1∑nθi2
即
J
(
θ
)
=
1
m
∑
i
=
1
m
(
θ
T
⋅
x
(
i
)
−
y
i
)
2
+
a
∑
i
=
1
n
θ
i
2
J(\theta)=\frac{1}{m}\sum_{i=1}^m(\theta^T \cdot x^{(i)}-y^{i})^2+a\sum_{i=1}^n\theta_i^2
J(θ)=m1i=1∑m(θT⋅x(i)−yi)2+ai=1∑nθi2
- a=0: 岭回归退化为线性回归
2、Lasso Regression(Lasso 回归)
Lasso 回归是线性回归的另一种正则化版本,正则项为权值向量的1范数。
Lasso回归的代价函数:
J
(
θ
)
=
M
S
E
(
θ
)
+
a
∑
i
=
1
n
∣
θ
i
∣
J(\theta)=MSE(\theta)+a\sum_{i=1}^n|\theta_i|
J(θ)=MSE(θ)+ai=1∑n∣θi∣
$$
\begin {array}{l}
[注意] \
. Lasso\ Regression的代价函数在\theta_i=0处是不可导的。\
. 解决方法:在\theta_i=0处用一个次梯度向量(subgradient\ vector)代替梯度,如下式\
. Lasso\ Regression 的次梯度向量
\end {array}
$$
g ( θ , J ) = ∇ θ M S E ( θ ) + a ( s i g n ( θ 1 ) s i g n ( θ 2 ) ⋮ s i g n ( θ n ) ) w h e r e s i g n ( θ i ) = { − 1 i f θ i < 0 0 i f θ i = 0 + 1 i f θ i > 0 g(\theta,J)=\nabla_\theta MSE(\theta)+a\begin{pmatrix}sign(\theta_1) \\ sign(\theta_2)\\ \vdots\\ sign(\theta_n) \end{pmatrix}\ where\ sign(\theta_i)=\begin{cases} -1& if& \theta _i<0\\ 0& if& \theta_i=0\\ +1& if& \theta_i>0\\ \end{cases} g(θ,J)=∇θMSE(θ)+a sign(θ1)sign(θ2)⋮sign(θn) where sign(θi)=⎩ ⎨ ⎧−10+1ifififθi<0θi=0θi>0
Lasso Regression 有一个重要的性质是:倾向于完全消除不重要的权重。
3、Elastic Net(弹性网络)
弹性网络在岭回归中进行了折中,通过混合比(mix ratio)r进行控制:
- r=0:弹性网络变为岭回归
- r=1:弹性网络变为Lasso回归
弹性网络的代价函数:
J
(
θ
)
=
M
S
E
(
θ
)
+
r
a
∑
i
=
1
n
∣
θ
i
∣
+
1
−
r
2
a
∑
i
=
1
n
θ
i
2
J(\theta)=MSE(\theta)+ra\sum_{i=1}^n|\theta_i|+\frac{1-r}{2}a\sum_{i=1}^n\theta_i^2
J(θ)=MSE(θ)+rai=1∑n∣θi∣+21−rai=1∑nθi2
一般来说,我们应该避免使用朴素线性回归,而应对模型进行一定的正则化处理。
小结:
- 常用:岭回归
- 假设只有少部分特征有用的:
- 弹性网络
- Lasso
- 一般来说,弹性网络的使用更为广泛。因为在特征维度高于训练样本数,或者特征是强相关的情况下,Lasso回归的表现不太稳定。
- api:
from sklearn.linear_model impmort Ridge, ElasticNet,Lasso
4、Early Stopping
Earling Stopping也是正则化迭代学习的方法之一。
其做法为:在验证错误率达到最小值的时候停止训练。
2.10 线性回归的改进-岭回归
波士顿房价预测实例
code
# coding:utf-8
"""
# 1、获取数据
# 2、数据基本处理
# 2.1 分割数据
# 3、特征工程-标准化
# 4、机器学习-线性回归
# 5、模型评估
"""
#导入波士顿数据集
# from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import SGDRegressor,Ridge
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
# def load_boston():
import pandas as pd
import numpy as np
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]
# boston = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :3]])
# print(d.shape)
# return (data,target)
#正规方程
def linear_model1():
# 1、获取数据
# boston = load_boston()
# print(boston)
# 2、数据基本处理
# 2.1 分割数据
x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2)
# 3、特征工程-标准化
transfer= StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4、机器学习-线性回归
estimator = LinearRegression()
estimator.fit(x_train, y_train)
print("这个模型的偏置是:\n",estimator.intercept_)
print("这个模型的系数是:\n",estimator.coef_)
# 5、模型评估
# 5.1 预测值
y_pre = estimator.predict(x_test)
print("预测值是:\n",y_pre)
#5.2 均方误差
ret = mean_squared_error(y_test, y_pre)
print("均方误差:\n",ret)
#梯度下降法
def linear_model2():
# 1、获取数据
# boston = load_boston()
# print(boston)
# 2、数据基本处理
# 2.1 分割数据
x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2)
# 3、特征工程-标准化
transfer= StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4、机器学习-线性回归
# estimator = LinearRegression()
# estimator = SGDRegressor(max_iter=1000)
estimator = SGDRegressor(max_iter=1000, learning_rate="constant", eta0=0.001)
estimator.fit(x_train, y_train)
print("这个模型的偏置是:\n",estimator.intercept_)
print("这个模型的系数是:\n",estimator.coef_)
# 5、模型评估
# 5.1 预测值
y_pre = estimator.predict(x_test)
print("预测值是:\n",y_pre)
#5.2 均方误差
ret = mean_squared_error(y_test, y_pre)
print("均方误差:\n",ret)
#岭回归
def linear_model3():
# 1、获取数据
# boston = load_boston()
# print(boston)
# 2、数据基本处理
# 2.1 分割数据
x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2)
# 3、特征工程-标准化
transfer= StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4、机器学习-线性回归
# estimator = LinearRegression()
# estimator = SGDRegressor(max_iter=1000)
# estimator = SGDRegressor(max_iter=1000, learning_rate="constant", eta0=0.001)
estimator = Ridge(alpha=1)
#estimator=RidgeCV(alphas=(0.1,1,10)
estimator.fit(x_train, y_train)
print("这个模型的偏置是:\n",estimator.intercept_)
print("这个模型的系数是:\n",estimator.coef_)
# 5、模型评估
# 5.1 预测值
y_pre = estimator.predict(x_test)
print("预测值是:\n",y_pre)
#5.2 均方误差
ret = mean_squared_error(y_test, y_pre)
print("均方误差:\n",ret)
# linear_model1()
# linear_model2()
linear_model3()
2.11 模型的保存和加载
code
# coding:utf-8
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import SGDRegressor,Ridge
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
# from sklearn.externals import joblib
from sklearn.utils import _joblib
import pandas as pd
import numpy as np
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]
#岭回归
def dump_load():
# 2、数据基本处理
# 2.1 分割数据
x_train, x_test, y_train, y_test = train_test_split(data, target,random_state=10, test_size=0.2)
# 3、特征工程-标准化
transfer= StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4、机器学习-线性回归
# estimator = LinearRegression()
# estimator = SGDRegressor(max_iter=1000)
# estimator = SGDRegressor(max_iter=1000, learning_rate="constant", eta0=0.001)
#
# estimator = Ridge(alpha=1)
# #estimator=RidgeCV(alphas=(0.1,1,10)
# estimator.fit(x_train, y_train)
# 4.2 模型保存
# _joblib.dump(estimator,"./test.pkl")
# # 4.3 模型训练
estimator = _joblib.load("./test.pkl")
print("这个模型的偏置是:\n",estimator.intercept_)
print("这个模型的系数是:\n",estimator.coef_)
# 5、模型评估
# 5.1 预测值
y_pre = estimator.predict(x_test)
print("预测值是:\n",y_pre)
#5.2 均方误差
ret = mean_squared_error(y_test, y_pre)
print("均方误差:\n",ret)
# linear_model1()
# linear_model2()
dump_load()