线性回归(Linear regression)是利⽤回归⽅程(函数)对⼀个或多个⾃变量(特征值)和因变量(⽬标值)之间关系进⾏建模的 ⼀种分析⽅式。
那么怎么理解呢?我们来看⼏个例⼦
上⾯两个例⼦,我们看到特征值与⽬标值之间建⽴了⼀个关系,这个关系可以理解为线性模型。
线性回归当中主要有两种模型,⼀种是线性关系,另⼀种是⾮线性关系。在这⾥我们只能画⼀个平⾯更好去理解,所以都⽤单个特征或两个特征举例⼦。
from sklearn.linear_model import LinearRegression
# 1. 获取数据
x = [[80, 86],
[82, 80],
[85, 78],
[90, 90],
[86, 82],
[82, 90],
[78, 80],
[92, 94]]
y = [84.2, 80.6, 80.1, 90, 83.2, 87.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]]))
假设刚才的房⼦例⼦,真实的数据之间存在这样的关系:
真实关系:真实房⼦价格 = 0.02×中⼼区域的距离 + 0.04×城市⼀氧化氮浓度 + (-0.12×⾃住房平均房价) + 0.254×城镇犯罪率
我们随意指定⼀个关系(猜测)
随机指定关系:预测房⼦价格 = 0.25×中⼼区域的距离 + 0.14×城市⼀氧化氮浓度 + 0.42×⾃住房平均房价 + 0.34×城镇犯罪率
如何去求模型当中的W,使得损失最⼩?(⽬的是找到最⼩损失对应的W值)
理解:X为特征值矩阵,y为⽬标值矩阵。直接求到最好的结果
缺点:当特征过多过复杂时,求解速度太慢并且得不到结果
把该损失函数转换成矩阵写法
其中y是真实值矩阵,X是特征值矩阵,w是权重矩阵
对其求解关于w的最⼩值,起⽌y,X 均已知⼆次函数直接求导,导数为零的位置,即为最⼩值。
梯度下降法的基本思想可以类⽐为⼀个下⼭的过程。
假设这样⼀个场景:
⼀个⼈被困在⼭上,需要从⼭上下来(i.e. 找到⼭的最低点,也就是⼭⾕)。但此时⼭上的浓雾很⼤,导致可视度很低。 因此,下⼭的路径就⽆法确定,他必须利⽤⾃⼰周围的信息去找到下⼭的路径。这个时候,他就可以利⽤梯度下降算法 来帮助⾃⼰下⼭。
具体来说就是,以他当前的所处的位置为基准,寻找这个位置最陡峭的地⽅,然后朝着⼭的⾼度下降的地⽅⾛,(同 理,如果我们的⽬标是上⼭,也就是爬到⼭顶,那么此时应该是朝着最陡峭的⽅向往上⾛)。然后每⾛⼀段距离,都反 复采⽤同⼀个⽅法,最后就能成功的抵达⼭⾕。
梯度下降的基本过程就和下⼭的场景很类似。
⾸先,我们有⼀个可微分的函数。这个函数就代表着⼀座⼭。
我们的⽬标就是找到这个函数的最⼩值,也就是⼭底。
根据之前的场景假设,最快的下⼭的⽅式就是找到当前位置最陡峭的⽅向,然后沿着此⽅向向下⾛,对应到函数中,就是找到给定点的梯度 ,然后朝着梯度相反的⽅向,就能让函数值下降的最快!因为梯度的⽅向就是函数值变化最快的 ⽅向。 所以,我们重复利⽤这个⽅法,反复求取梯度,最后就能到达局部的最⼩值,这就类似于我们下⼭的过程。⽽ 求取梯度就确定了最陡峭的⽅向,也就是场景中测量⽅向的⼿段。
梯度是微积分中⼀个很重要的概念
在微积分⾥⾯,对多元函数的参数求∂偏导数,把求得的各个参数的偏导数以向量的形式写出来,就是 梯度。
α在梯度下降算法中被称作为学习率或者步⻓,意味着我们可以通过α来控制每⼀步⾛的距离,以保证不要步⼦跨的 太⼤扯着蛋,哈哈,其实就是不要⾛太快,错过了最低点。同时也要保证不要⾛的太慢,导致太阳下⼭了,还没有 ⾛到⼭下。所以α的选择在梯度下降法中往往是很重要的!α不能太⼤也不能太⼩,太⼩的话,可能导致迟迟⾛不到 最低点,太⼤的话,会导致错过最低点!
2) 为什么梯度要乘以⼀个负号?
梯度前加⼀个负号,就意味着朝着梯度相反的⽅向前进!我们在前⽂提到,梯度的⽅向实际就是函数在此点上升最快的 ⽅向!⽽我们需要朝着下降最快的⽅向⾛,⾃然就是负的梯度的⽅向,所以此处需要加上负号
经过前⾯的介绍,我们发现最⼩⼆乘法适⽤简洁⾼效,⽐梯度下降这样的迭代法似乎⽅便很多。但是这⾥我们就聊聊最 ⼩⼆乘法的局限性。
https://blog.csdn.net/qq_39759664/article/details/123503129
https://blog.csdn.net/qq_39759664/article/details/123560519
https://blog.csdn.net/qq_39759664/article/details/123564346
https://blog.csdn.net/qq_39759664/article/details/123564476
import joblib
保存:joblib.dump(estimator, ‘test.pkl’)
加载:estimator = joblib.load(‘test.pkl’)
线性回归的模型保存加载案例
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression,SGDRegressor,RidgeCV,Ridge
from sklearn.metrics import mean_squared_error
import joblib
import warnings
warnings.filterwarnings("ignore")
def linear_model3():
"""
线性回归:岭回归
:return:
"""
# 1.获取数据
boston=load_boston()
# 2.数据基本数据
# 2.1 分割数据
x_train,x_test,y_train,y_test=train_test_split(boston.data,boston.target,random_state=22,test_size=0.2)
# 3.特征工程--标准化
transfer=StandardScaler()
x_train=transfer.fit_transform(x_train)
x_test=transfer.fit_transform(x_test)
# 4.机器学习---线性回归
# 4.1 模型训练
#estimator=SGDRegressor(max_iter=1000,learning_rate="constant",eta0=0.001)
# estimator=Ridge(alpha=1.0)
# estimator=RidgeCV(alphas=(0.001,0.01,0.1,1,10,100))
# estimator.fit(x_train,y_train)
#
# print("这个模型的偏置是:\n",estimator.intercept_)
# print("这个模型的系数是:\n",estimator.coef_)
#
# # 4.2 保存模型
# joblib.dump(estimator,"./data/test.pkl")
## 4.3 模型加载
estimator=joblib.load("./data/test.pkl")
# 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)
if __name__ == '__main__':
linear_model3()
注意:
1.保存⽂件,后缀名是**.pkl
2.加载模型是需要通过⼀个变量进⾏承接