理论
- 线性回归算法用于解决回归问题,而前述的knn算法用于解决分类问题
- 目的是寻找一条直线,最大程度上拟合样本特征和样本输出标记之间的关系
-
样本特征只有一个时称为简单线性回归,样本特征具有多个时称为多元线性回归
简单线性回归 - 目的在于,找到拟合程度最好的那个a,b
使得预测值和样本值的差别尽可能小 -
损失函数尽可能小
损失函数 -
这是一个典型的最小二乘法问题
ab其结果如图
最小化误差的平方
简单的实现
首先我们传入一组特征还算明显的数据
import numpy as np
import matplotlib.pyplot as plt
x=np.array([1.,2.,3.,4.,5.])
y=np.array([1.,3.,2.,3.,5.])
我们先绘图观察
plt.scatter(x,y)
plt.axis([0,6,0,6])
原始数据
进行最小二乘法求出ab的过程
x_mean=np.mean(x)
y_mean=np.mean(y)
num=0.0
d=0.0
for x_i,y_i in zip(x,y):
num+=(x_i-x_mean)*(y_i-y_mean)#分子
d+=(x_i-x_mean)**2#分母
a=num/d
b=y_mean-a*x_mean
y_hat=a*x+b
这时分别将散点图和预测直线画出
plt.scatter(x,y)
plt.plot(x,y_hat,color='r')
plt.axis([0,6,0,6])
拟合图
这样一个简单的简单线性回归程序基本完成了!
向量化
上面的算法实现有一个很明显的问题,便是使用了for循环计算a值,效率较低
实际上,吴恩达的ML教程中直接选用了向量化运算,完全没有考虑for循环的实现,因为向量化运算实现显然要更加高效一些。
-
我们观察到
a的表达式
分子分母都可以视为向量相乘
(注意到这里因为是简单线性回归,每个w(i)其实只是单个的值,实际上这也是简单线性回归便于理解的地方)
分解过程
于是对上述程序中a的计算过程进行如下改动
a=(x_train - x_mean).dot(y_train - y_mean) / (x_train - x_mean).dot(x_train - x_mean)
算法的评价
和knn算法相同的,我们也需要去评价我们的模型效率如何。
-
均方误差MSE
均方误差 -
均方根误差RMSE
均方根误差 -
平均绝对误差MAE
平均绝对误差 -
Rsquared: 最好的衡量线性回归法的指标
Rsquared
和knn类似的,下面以一个实例来说明(这时我们便需要采用sklearn的官方数据集了)
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
boston=datasets.load_boston()
#波士顿房产数据
#print(boston.DESCR)可以获取详细信息
#由于是简单线性回归,故只取一个特征
x=boston.data[:,5]#房间数量
y=boston.target
这里我们观察一下数据的个数以及在散点图上的分布
数据个数
数据分布
我们注意到有一些点处于表格上面或者右边,这是一些最值点,为了线性回归的准确性我们应该将其删掉
x=x[y<np.max(y)]
y=y[y<np.max(y)]
plt.scatter(x,y)
处理后的原始数据
我们开始数据处理
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=6)
#实际上这里size默认是0.2
这时
新的训练集
下面开始训练简单线性回归的模型
x_mean=np.mean(x_train)
y_mean=np.mean(y_train)
a=(x_train - x_mean).dot(y_train - y_mean) / (x_train - x_mean).dot(x_train - x_mean)
b=y_mean-a*x_mean
y_hat=a*x_train+b
a,b值
在散点图上绘制出来
结果
下面开始进行模型的评价
y_predict=a*x_test+b
mse_test=np.sum((y_predict-y_test)**2)/len(y_test)
from math import sqrt
rmse_test=sqrt(mse_test)
mae_test=np.sum(np.absolute(y_predict-y_test))/len(y_test)
mse_test/np.var(y_test)#Rsquared值
#sklearn中也有直接计算Rsquared值的函数,
#from sklearn.metrics import r2_score
#r2_score(y_test,y_predicted)
RMSE
MAE
-
为何MAE的值要比RMSE值要小呢?
公式比较
不难看出,分母里m值是否开更号,导致了这一结果!
总结
简单线性回归到这里内容基本上已经结束了,其数学知识需求也是比较小的,所以适合用作回归的最先学习算法,后面如果还会有其他需要补充的点我也会再加进来!
多希望能早日回去学校啊,虽然在家码一下博客也确实可以打发打发时间,不过想到去年这时候正在武大吐槽着人比樱花多,等个烧烤等到半夜,眼前的事情顿时就不香了。
网友评论