什么是线性回归?
线性回归就是自变量和因变量之间为线性关系。比如你的存款和贷款额度,你有 1 万存款,可以贷款 999 元,10 万存款可以贷款 99998 元,20 万存款可以贷款 200001 元。那么,如果你作为一名金融公司工作人员,给客户发放贷款,这个客户的存款证明有 50 万,你应该批多少额度呢?
显然,你大概已经发现了规律,f(x) ≈ 0.1 x。实际上这个过程一般都是程序自动完成的。真实情况更加复杂,不仅仅要考虑你的存款,还包括固定资产、消费水平、消费方向、职业、芝麻信用分等等,多变量共同决定你的贷款额度。
如果要人工评估,一方面工作量过大,另一方面,评估带有很多主观因素,未必能够选择较为合适的方案。
线性回归定义
线性回归(Linear regression)是利用回归方程(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式。
只有一个自变量的情况称为一元回归,多于一个自变量情况的叫做多元回归。
损失函数
在预测过程中,结果几乎不会和真实数据完全匹配。
我们只考虑最简单情况,一元回归,预测曲线为 f(w) = wx+b。
那么,真实坐标点距离预测方程线的竖直距离便是误差,由于误差包括正负,因此,我们将其平方处理。
目标是找到模型中合适的 w,使得损失最小。其中 w 是矩阵。
正规方程
在多元回归中,使用正规方程可以直接得到最好的结果。
其中,X 为特征值矩阵,y 为目标值矩阵。缺点是,当特征过多时,求解速度会非常慢。
梯度下降法
基本思想是通过沿着损失函数梯度的反方向,逐步调整模型参数,使损失函数逐渐减小。梯度表示了函数变化最快的方向,而负梯度方向即是函数值下降最快的方向。
假设这样一个场景:一个人被困在山上,需要从山上下来(找到山的最低点,也就是山谷)。但此时山上的浓雾很大,导致可视度很低;因此,下山的路径就无法确定,必须利用自己周围的信息一步一步地找到下山的路。这个时候,便可利用梯度下降算法来帮助自己下山。怎么做呢,首先以他当前的所处的位置为基准,寻找这个位置最陡峭的地方,然后朝着下降方向走一步,然后又继续以当前位置为基准,再找最陡峭的地方,再走直到最后到达最低处。
Python程序实战
import numpy as np
import sklearn.linear_model as lm
import matplotlib.pyplot as plt
train_x = np.array([[0.5], [0.6], [0.8], [1.1], [1.4]])
train_y = np.array([5.0, 5.5, 6.0, 6.8, 7.1])
# 创建线性回归器
model = lm.LinearRegression()
# 训练回归器
model.fit(train_x, train_y)
pre_y = model.predict(train_x)
print(pre_y)
print("系数 coef_ =", model.coef_)
print("截距 intercept_=", model.intercept_)
plt.plot(train_x, pre_y)
plt.scatter(train_x, train_y)
plt.show()
输出:
[5.20072993 5.43211679 5.89489051 6.58905109 7.28321168]
系数 coef_ = [2.31386861]
截距 intercept_= 4.043795620437956
模型评价指标
1.平均绝对误差:单个观测值与预测值的偏差的绝对值的平均。
2.均方误差:单个样本到平均值差值的平方均值。
3.MAD中位数绝对偏差:与数据中值绝对偏差的中值。
4.R2决定系数:趋向于 1,模型越好;趋向于 0,模型越差。
import sklearn.metrics as sm # 模型评估
# 平均绝对误差
print(sm.mean_absolute_error(train_y, pre_y))
# 平均平方误差(均方误差)
print(sm.mean_squared_error(train_y, pre_y))
# 中位数绝对偏差
print(sm.median_absolute_error(train_y, pre_y))
# R2得分
print(sm.r2_score(train_y, pre_y))
输出:
0.15357664233576643
0.026802919708029154
0.18321167883211587
0.9563185793545809
保存和加载模型
保存模型:
import pickle
with open('catmodel.pickle','wb') as f:
pickle.dump(model, f)
加载模型:
import pickle
with open('./catmodel.pickle','rb') as f:
model = pickle.load(f)
print(model.predict([[1.1],[2.2]]))
输出:
[6.58905109 9.13430657]