线性回归算法的特点
- 用于解决回归问题
- 思想简单,容易实现
- 许多强大的非线性模型的基础
- 结果具有很好的解释性
- 蕴含机器学习中很多重要的思想
如图,假设横轴代表房屋的居住面积,纵轴代表房屋的价格,那么线性回归即为寻找一条直线,这条直线最大程度的拟合特征点,
y = ax + b
当有新的特征点X(i)时,对应在曲线上的值为 y^(i),实际X(i)对应的值为y(i),实际值和预测值之间有一个差值。我们的最佳拟合方程就是希望y(i)和y^(i)的差距足够小。两者的差距用下面的式子表示
考虑所有的样本差值即为,
将原来的拟合方程带入上面的式子,
可得
我们最终的目标就是找到a和b使得上面的式子得到的结果足够小。通过最小二乘法,可以得出,a和b对应的方程如下:
其实上面这个函数我也看不懂,都怪我大学没有好好听高数,已经基本全忘光了,大家先记下来吧~
简单线性回归的
准备数据集
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])
用代码实现上面的公式
import numpy as np
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
通过计算得到的a,和b绘制对应的拟合方程
plt.scatter(x,y)
y_hat = a * x + b
plt.plot(x,y_hat,color = 'red')
plt.axis([0,6,0,6])
plt.show()
向量化
上面的for循环可以优化成矩阵相乘,以提高算法速度
import numpy as np
x_mean = np.mean(x)
y_mean = np.mean(y)
num = 0.0
d = 0.0
num = (x_i - x_mean).dot(y_i - y_mean)
d = (x_i - x_mean).dot(x_i - x_mean)
a = num / d
b = y_mean - a * x_mean
衡量线性回归法的指标
MSE
所有样本的误差相加再平方得到的结果除以样本数量得到的结果称为均方误差即:MSE
RMSE
上文中得到的结果进行开根号,得到的误差值称为:均方根误差
MAE
所有样本的误差相加得到的结果除以样本数量得到的结果称为均方误差即:MAE
R Squared
这个指标只通过预测结果来衡量预测的准确度。
- SS_residual: 预测结果减掉真值得到结果的平方再求和
- SS_total: 平均值减去每一个值,得到的结果平方再求和。
R Squared指标的特点
- R^2 <= 1
- R^2 越大越好,当我们的模型不犯任何错误时,R^2得到最大值 1
- 当我们的模型等于基准模型时,R^2 = 0
- 如果R^2小于0,说明我们的预测模型还不如基准模型,此时,我们的数据很可能不存在线性关系。
R^2分子和分母同时乘以M,得到如下结果
分子为我们上文提到的
MSE
,分子为我们学过的方差
,于是,公式和下面这个公式等价:
多元线性回归
多远线性方程
目标
多元线性方程
- 将所有的θ提出来,作为一个列向量
-
为了后续操作我们将这个多元线性方程的θ0也加上一个X_0,这个X_0恒等于1
-
提取该方程式中X的变量作为一列特征
- 将所有的X的特征提取出来,表示为如下:
- 那么对应的多元线性方程可表示为
7. 我们的目标是
该式子转换成矩阵运算
多元线性回归的正规方程解
计算多元线性方程的每个θ的值,公式如下:
这个公式没有必要背下来,我也不会,如果想了解推导过程,可以去互联网搜索下~~~
编程实现
import numpy as np
class LinearRegression:
def __init__(self):
self.coef_ = None
self.interception_ = None
self._theta = None
def fit_normal(self, X_train, y_train):
assert X_train.shape[0] == y_train.shape[0], \
"the size of X_train must be equals to y_train"
X_b = np.hstack([np.ones(len(X_train), 1), X_train])
self._theta = np.linalg.inv(X_b.T.dot(X_b))
self.interception_ = self._theta[0]
self.coef_ = self._theta[1:]
return self
def predict(self, X_predict):
assert self.interception_ is not None and self.coef_ is not None, \
"must fit before predict"
assert X_predict.shape[1] == len(self.coef_), \
"the feature number of X_predict len must be equals to X_train"
X_b = np.stack([np.ones(len(X_predict), 1), X_predict])
return X_b.dot(self._theta)
sk-learn 中使用线性回归法预测波士顿房价
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
boston = datasets.load_boston()
x = boston.data
y = boston.target
# 去掉最值
X = x[y<50.0]
Y = y[y<50.0]
X.shape
X_train,X_test,y_train,y_test = train_test_split(X,Y,random_state = 666)
lin_reg = LinearRegression()
# 训练数据
lin_reg.fit(X_train,y_train)
# 得到训练的精准度
lin_reg.score(X_test,y_test)