这次讲线性回归,之前有说逻辑回归(Logistic Regression),虽然逻辑回归负责分类,可是在数据到达二值函数之前的逻辑都是线性回归的逻辑,所以这两个回归是十分相似的。这篇文章的顺序是:1、线性回归算法原理 2、最小二乘法和算法评估标准 3、案例1-简单数据集标准线性回归 4、案例2-简单数据集局部加权线性回归 5、案例3-鲍鱼年龄预测。
在学习scikitlearn的时候会有一个经典案例,就是Boston房价预测,就是用回归去做的,当然也可以使用其他方法但是这次讲回归。那么再线性回归里如何去预测房价?那么我们要得到房子各方面数据如:房产证上的面积、实际居住面积、物业费、位置、周围的超商、幼儿园、小学等等。
那么对这些指标经过加权最终得到一个公式就是:
y_predict = w1*房产证上的面积+w2*实际居住面积+w3*物业费+....
这就是所谓的回归方程了,而w1、w2…都是回归系数,回归系数是对与其相关的特征对结果影响强弱的参数体现,当然这里对数据的要求都是数值型的数据,即能够参与运算的数据。而针对无法运算的标称型数据后面也会给出解决方案。
普通最小二乘法的推导证明,这篇文章里第一点说的很清楚,最小二乘法的思想就是要使得真实值与预测值间的距离的平方达到最小。即真实值与预测值越贴合就证明预测的准嘛。
那么用数学公式表达出来就是:
假设我们的数据集是这样的:
x0 x1 y
1.000000 0.067732 3.176513
1.000000 0.427810 3.816464
1.000000 0.995731 4.550095
1.000000 0.738336 4.256571
这个数据集每行代表一个实例(房子、车等等需要预测的目标),x0、x1代表的是这个实例的两个特征。上面这个公式的y_i表示的是每一个实例的y_true(第一行就是3.176513),而x_i表示的是每个实例的所有特征的值的一个向量,x_1表示[1.0 0.067732],而w表示的是每个特征前的回归系数。那么x_i*w就是y_predict。
用另外一种表示方法就是:
那么接下来还是要对w求偏导通过一个例子快速上手矩阵求导,这篇博客同样也讲解了整个求导过程,当然最主要看的是各个部分对w求偏导。那么最终得到偏导结果就是:
既然x,y向量我们都知道了,那么令等式为0就可以求出w,显然我们只需要乘x转置x的逆到右边就可以了:
那么到这里,w向量的求解过程就全部讲清楚了,这也就是通过最小二乘法求解w向量的过程。当然,**这种方法在面对大型矩阵时会产生大量的计算从而导致计算量激增,所以更常用的是梯度下降法来求w向量。**梯度下降在逻辑回归(LogisticRegression)算法及简单案例里有讲,感兴趣的可以看一下。
算法的好坏需要有一些标准来做评判的,这也是在做科研的时候常用到的东西。Python实现回归算法的衡量指标计算:MSE/RMSE/MAE/R^2,这篇博客里也介绍了几种不同的回归算法评价指标。
所以,在我们模型做出来之后就会从中选择几种指标来对模型做评价。
这篇文章所有的数据集我都会打包上传到github上面,大家不用担心,因为我也是体会过到处找数据集来做测试的那种心累=。=
每次做东西之前都需要先看一看数据集:
print(df)
x0 x1 y
0 1.0 0.427810 3.816464
1 1.0 0.995731 4.550095
2 1.0 0.738336 4.256571
3 1.0 0.981083 4.560815
4 1.0 0.526171 3.929515
.. ... ... ...
194 1.0 0.257017 3.585821
195 1.0 0.833735 4.374394
196 1.0 0.070095 3.213817
197 1.0 0.527070 3.952681
198 1.0 0.116163 3.129283
显然这个数据集很小,2个特征,200行不到,y就是我们需要predict的值。
再查看有无缺失值:
print(df.describe())
x0 x1 y
count 199.0 199.000000 199.000000
mean 1.0 0.490433 3.838914
std 0.0 0.292149 0.502523
min 1.0 0.014855 3.078132
25% 1.0 0.236126 3.465190
50% 1.0 0.466776 3.844426
75% 1.0 0.730878 4.249712
max 1.0 0.995731 4.692514
没有缺失值,均值、标准差等等都出来了,很方便。
再看一看数据实际分布怎么样,因为x0全是1,所以直接用x1来画:
导包先,这次需要用到的包:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from numpy.linalg import linalg
读数据代码,没什么好解释的了,使用pandas来做处理,然后用numpy矩阵来计算很方便,相较于python数组一行行的写好多了:
def load_data(file_path):
"""
加载数据集
:param file_path: 路径
:return:
"""
df = pd.read_csv(file_path)
# [n,m-1]
data_matrix = np.mat(df.iloc[:, :-1])
# [n,1]
label_matrix = np.mat(df.iloc[:, -1]).T
# print(np.shape(data_matrix), "\n")
# print(np.shape(label_matrix), "\n")
# print(data_matrix, "\n")
# print(label_matrix)
return data_matrix, label_matrix
这里需要解释一下,因为pandas读csv后我把y_true放到了label_matrix里,所以data_matrix就只有特征值没有目标值了。
那么转为numpy矩阵后可以安心计算了,因为w的公式里有求逆的过程,所以需要对XTX进行行列式判断,这个大家需要理解。
最后只需要按照公式算出w向量就可以了。
def standRegress(data_matrix, label_matrix):
"""
标准回归
:param data_matrix:
:param label_matrix:
:return:
"""
# 准备xTx 即x的转置乘x阵,用于求行列式从而判断是否可逆 [m-1,m-1] = [m-1,n] * [n,m-1]
xTx = data_matrix.T * data_matrix
# print(xTx)
# 判断行列式
if linalg.det(xTx) == 0:
print("该矩阵不可逆")
return
# 若矩阵可逆 直接使用最小二乘法(即公式法)来算系数矩阵w w = [m-1,m-1] * [m-1,n] * [n,1] = [m-1,1]
w = xTx.I * data_matrix.T * label_matrix
print("W阵:", w)
return w
其实到刚才两个函数整个标准回归已经做完了,但是为了直观体现出来需要画张图看一看回归曲线:
def my_paint(w, data_matrix, label_matrix):
"""
画图
:param w:
:param data_matrix:
:param label_matrix:
:return:
"""
fig = plt.figure(figsize=(10, 10), dpi=200)
# 对数据有疑问的可以打开下面几行注释查看数据
# print(data_matrix[:, 1])
# print(data_matrix[:, 1].flatten())
# print(label_matrix.T)
# print(label_matrix.T.flatten())
# print(label_matrix.T.flatten().A[0])
plt.scatter(x=data_matrix[:, 1].flatten().A[0], y=label_matrix.T.flatten().A[0])
data_matrix_copied = data_matrix.copy()
data_matrix_copied.sort(0)
# print(data_matrix_copied)
y_predict = data_matrix_copied * w
plt.plot(data_matrix_copied[:, 1], y_predict)
plt.show()
在案例1可以看到曲线拟合的不错,但是还有点欠拟合,还有没有更好的拟合情况呢?还真有,这就是局部加权线性回归。 这篇文应该很长了,我决定分两期,详情见下期
点击进入github