线性回归
本系列重点在浅显易懂,快速上手。不进行过多的理论讲解:也就是不去深究what,而是关注how。全文围绕以下三个问题展开:
1)长什么样?
2)解决什么问题?
3)怎么实现?
3.1)从数学讲,原理
3.2)从代码上讲,如何掉包实现
长什么样
通俗的说就是解方程,先来回忆初中的二元一次方程组:
{a∗x11+b∗x21=y1a∗x12+b∗x22=y2 \begin{cases} a*x_{11} + b*x_{21} = y_1 \\ a*x_{12} + b*x_{22} = y_2 \end{cases} {a∗x11+b∗x21=y1a∗x12+b∗x22=y2
已知两组数
(x11=1 x21=2 y1=3),(x12=3 x22=1 y2=4) (x_{11}=1\ x_{21}=2\ y_1=3),(x_{12}=3\ x_{22}=1\ y_2=4) (x11=1 x21=2 y1=3),(x12=3 x22=1 y2=4)
求解a和b,很容易求的a=1,b=1。
上面是一个二元一次方程的例子,只不过线性回归的方程更加复杂,是m元n次(一般都是一次,效果不好的可以考虑多项式融合,就是多次方的)的方程:
{a∗x11+b∗x21+...+z∗xm1+c=y1a∗x12+b∗x22+...+z∗xm2+c=y2 . . .a∗x1n+b∗x2n+...+z∗xmn+c=yn \begin{cases} a*x_{11} + b*x_{21} + ... + z*x_{m1} + c = y_1 \\ a*x_{12} + b*x_{22} + ... + z*x_{m2} + c = y_2\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .\\ a*x_{1n} + b*x_{2n} + ... + z*x_{mn} + c = y_n\\ \end{cases} ⎩⎨⎧a∗x11+b∗x21+...+z∗xm1+c=y1a∗x12+b∗x22+...+z∗xm2+c=y2 . . .a∗x1n+b∗x2n+...+z∗xmn+c=yn
解决什么问题
先看一组数据(一组sklearn中公开的数据集,波士顿的房价预测,共有13个特征,最后一列y是房价,这里只展示了5条数据,实际数据有506条):
采用线性回归建模,最终的目的就是为了找到一组θ_1,θ_2,…,θ_{13},θ_0(除了13个系数,还包含一个常数项θ_0),使得下式成立。
θ1∗x1+θ2∗x2+......+θ13∗x13+θ0=y θ_1*x1+θ_2*x2+......+θ_{13}*x13+θ_0=y θ1∗x1+θ2∗x2+......+θ13∗x13+θ0=y
怎么实现
其实就是如何求解θ1,θ2,...,θ13,θ0θ_1,θ_2,...,θ_{13},θ_0θ1,θ2,...,θ13,θ0,有两种方法:
1)最小二乘法(有缺陷,一般都是梯度下降法,具体看下文)
2)梯度下降法
最小二乘法
设
yi=θT∗xi+ξi y^i = θ^T*x^i+ξ^i yi=θT∗xi+ξi
python默认一个一维的向量,时列向量,xix^ixi的格式是(13,1), θTθ^TθT的格式是(1,13),(先不考虑常熟项),ξiξ^iξi表示yiy^iyi和θT∗xiθ^T*x^iθT∗xi之间的误差(机器学习不能求解到百分百准确的θ值,只能使得ξ^i值不断减小,也就是让预测值不断的逼近真实值y。
ξiξ^iξi,假设是独立同分布的,服从均值为0,方差为σ2σ^2σ2的高斯分布,即:
他的联合分布概率是:
L(θ)L(θ)L(θ)就是样本的似然函数,转化为数学中求解θ最大似然估计值的问题,即:最大似然估计法(这里有兴趣的可以去补习数学上这块的知识,不想学习,可以只看下面的求解过程能看懂就行)
首先向将似然函数L(θ)L(θ)L(θ)转换为对数似然函数log(L(θ))log(L(θ))log(L(θ)):
要求l(θ)l(θ)l(θ)的最大值,转化为求
12∑i=1m(yi−θTxi)2\frac{1}{2}\sum_{i=1}^{m}(y^i-θ^Tx^i)^221i=1∑m(yi−θTxi)2
的最小值,这就是目标函数(或者叫损失函数):
这就是最小二乘法的结果是一样的。
求解J(θ)的最小值,可以采用求解导函数,并使导函数为0的方式实现。
先将J(θ)转换为矩阵的形式:
具体的求解过程如下(这里需要用到矩阵求导的知识)直接维基百科有公式套用就行了,千万不要去过多的引入(学习一项新技能,最忌讳的就是,遇到一点不会的就恨不得把它祖宗三代都抛出来学习一边,一次性进行过于深入的学习,而深陷其中不能自拔,慢慢消磨殆尽学习的兴趣,应该是,就先学到会用的地步能解决当下的问题就赶紧停止,先学how怎么用,有机会了再去学what具体原理是怎么样的):
再求解:
XTXθ−XTY=0 X^TXθ-X^TY=0XTXθ−XTY=0 得:θ=(XTX)−1XTYθ=(X^TX)^{-1}X^TY θ=(XTX)−1XTY
到此最小二乘法,求解θ得过程讲解完毕,最小二乘法得缺陷也很明显了,首先要求X^TX是可逆的,为了防止不可逆,做如下更改,
θ=(XTX+λI)−1XTY θ=(X^TX+λI)^{-1}X^TY θ=(XTX+λI)−1XTY
最小二乘法直接求解的难处在于,逆矩阵的求解是个难点。
梯度下降法
1)确定目标函数,
2)初始化θ,(随机初始化或者初始化为0),
3)求解J(θ)的梯度,
∂J(θ)∂θ=XTXθ−XTY \frac{\partial J(θ)}{\partial θ} = X^TXθ-X^TY ∂θ∂J(θ)=XTXθ−XTY
4)沿着负梯度的方向更显θ,
θ=θ−α∗∂J(θ)∂θ,α是学利率 θ = θ -α*\frac{\partial J(θ)}{\partial θ},α是学利率 θ=θ−α∗∂θ∂J(θ),α是学利率
迭代一定的轮次,直到损失函数的值不在下降为止。
手动代码实现
#coding=utf8
import numpy as np
import pandas as pd
from sklearn import datasets
from tqdm import tqdm, trange
import matplotlib.pyplot as plt
'''原函数'''
def F(theta,X):
return np.dot(X, theta)
'''损失函数'''
def J(theta, X, Y):
return float(1/2*np.dot((np.dot(X,theta)-Y).T, (np.dot(X,theta)-Y))[0][0])/len(X)
'''偏导数'''
def H(theta, X, Y):
return np.dot(X.T, np.dot(X,theta)-Y)/X.shape[0]
'''标准化'''
def standard_scaler(X):
#mean_ = np.mean(X,axis=0)
#std_ = np.std(X,axis=0)
#X = (X-mean_)/std_
max_ = np.max(X,axis=0)
min_ = np.min(X,axis=0)
X = (X-min_)/(max_-min_)
return X
if __name__ == "__main__":
data = datasets.load_boston()
X = data.data
X = standard_scaler(X)
Y = data.target.reshape(-1,1)
loss_list = []
theta = np.random.rand(X.shape[1], 1) # 初始化参数
eta = 0.01
with trange(100000) as T:
for i in T:
loss = J(theta, X, Y)
loss_list.append(loss)
theta = theta - eta*H(theta, X, Y)
T.set_postfix(loss=loss)
print(theta)
plt.plot(loss_list)
plt.show()
sklearn调包实现
这里直接讲解,如何调用sklearn实现。
from sklearn.linear_model import LinearRegression #sklearn中,线性回归模型在linear_model模块中
# 调取sklearn中自带的数据集
from sklearn.datasets import load_boston #调用上文一开始提到大波士顿房价数据集
X, y = load_boston(return_X_y=True) #获取X,y数据
LR = LinearRegression() #初始化一个线性回归模型
LR.fit(X,y) #fit函数用于训练
LR.predict(X) #predict函数用于预测
LR.coef_ #coef_用于返回θ的值
LR.intercept_ #intercept_用于返回常数项的值(截距)
更多内容可以参考sklearn的官方文档
sklearn.linear_model.LinearRegression — scikit-learn 1.3.0 documentation
本文介绍了线性回归的基本概念,包括其数学形式、解决的问题(如波士顿房价预测),以及两种主要求解方法(最小二乘法和梯度下降)。通过Python示例展示了如何使用sklearn库实现线性回归模型。
1万+

被折叠的 条评论
为什么被折叠?



