scikit-learn机器学习第2版:第 2章 简单线性回归

2.1 简单线性回归

简单线性回归:一个解释变量和一个响应变量.

训练集的观测值:

训练实例 披萨直径(单位:英寸) 价格(单位:美元)
1 6 7
2 8 9
3 10 13
4 14 17.5
5 18 18

可视化观测值:

import numpy as np
import matplotlib.pyplot as plt
# 中文字体设置参考: https://yinhe.co/archives/20201023_miniconda.html
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

# sklearn 中 大写X表示矩阵, 小写x表示向量
# reshape中, 数组新的shape属性应该要与原来的配套,如果等于-1的话,那么Numpy会根据剩下的维度计算出数组的另外一个shape属性值
# 解释变量可能是多维的,一维只是特殊情形
X = np.array([[6],[8],[10],[14],[18]]).reshape(-1,1)
y = [7,9,13,17.5,18]

plt.figure()
plt.title("Pizza价格和尺寸")
plt.xlabel("直径")
plt.ylabel("价格")

plt.plot(X,y,'k.') # 'k.' 表示散点图
plt.axis([0,25,0,20]) # X,y 轴 在图形上的现实范围
plt.grid(True) # 显示网格
plt.show()

从图形可以看到尺寸和价格正相关.使用简单线性回归对这种关系进行建模.可视化是有助于建模的.

from sklearn.linear_model import LinearRegression

model = LinearRegression() # 创建一个估计器实例
model.fit(X,y) # 用训练数据拟合模型

# 预测新输入的输出
test_pizza = np.array([[12]])
predicted_price = model.predict(test_pizza)[0]

print(round(predicted_price,2)) # 13.68

估计器基于观测值预测一个值.在 sklearn中, 所有的估计器都实现了fit和predict 方法.前者用于学习模型的参数, 后者用学习到的参数预测解释变量对应的预测变量.

LinearRegression 的fit方法学习了如下简单线性回归模型的参数:

$$y=\alpha + \beta x$$

利用训练数据学习产生最佳拟合模型的简单线性回归模型的参数称为普通最小二乘法(Ordinary Lease Squares,OLS)或线性最小二乘法.

2.1.1 用代价函数评价模型的拟合性

代价函数, 也称为损失函数, 用于定义和衡量一个模型的误差.

训练集预测值和观测值之间的差值称为残差或训练误差.

测试集预测值和观测值之间的差值称为预测误差或测试误差.

可以通过求取最小残差平方和来生成最佳预测器.如果模型预测的响应变量都接近观测值, 那么模型就是拟合的,这种衡量模型拟合的方法叫做残差平方和

残差平方和:residual sum of squares/sum squared residual,简称RSS/SSR

$$SS_{res}=\sum_{i=1}^n(y_i - f(x_i))^2$$

$y_i$ 为观测值, $f(x_i)$ 为预测值

我们有了损失函数(代价函数)后, 可以通过求这个函数的极小值来求得模型的参数.

2.1.2 求解简单线性回归的OLS

方差

方差计算公式:

$$var(x)=\frac{\sum_{i=1}^n(x_i - \overline{x})^2}{n-1}$$

$\overline{x}$ 为均值, $n$ 为训练集数据总量, $n-1$为自由度.

## 计算pizza直径的方差
pizza_diameter_mean = np.mean(X)
pizza_diameter_var = ((X-pizza_diameter_mean)**2).sum()/(X.shape[0]-1)

print(pizza_diameter_mean,pizza_diameter_var) # 11.2 23.2

## 使用 var函数直接计算方差, ddof参数用于设置贝塞尔校正, 用于纠正对样本总体方差估计的偏差

print(np.var(X,ddof=1)) # 23.2

## 使用 var函数直接计算方差, ddof参数用于设置贝塞尔校正, 用于纠正对样本总体方差估计的偏差

print(np.var(X,ddof=1)) # 23.2

协方差

协方差用来衡量两个变量如何一同变化:

  • 如果一同增加, 协方差为正
  • 如果一个变量增加,另一个变量减少, 协方差为负
  • 如果两个变量没有线性关系, 协方差为0.这两个变量线性无关, 但不一定是相互独立的.

协方差公式:

$$cov(x,y)=\frac{\sum_{i=1}^n(x_i - \overline{x})(y_i - \overline{y})}{n-1}$$

可以求如下公式中的 $\beta = \frac{cov(X,y)}{var(x)},\alpha = \overline{y}-\beta\overline{x}$:

$$y=\alpha + \beta x$$

## 计算协方差
x_mean = np.mean(X)
y_mean = np.mean(y)

# np.multipy() :行向量对应元素相乘
# X.transpose(): 转置为行向量
cov_X_y = np.multiply((X-x_mean).transpose(),(y-y_mean)).sum()/(X.shape[0]-1)
print('Cov of X,y:',cov_X_y) #  X.transpose()

## beta
beta = cov_X_y/pizza_diameter_var
print('beta:',round(beta,2)) # beta: 0.98

## alpha
alpha = y_mean - beta*x_mean
print('alpha:',round(alpha,2)) # alpha: 1.97

2.2 评价模型

测试集的观测值:

测试实例 披萨直径(单位:英寸) 真实价格(单位:美元) 预测价格(单位:美元)
1 8 11 9.7759
2 9 8.5 10.7522
3 11 15 12.7048
4 16 18 17.5863
5 12 11 13.6811

使用皮尔逊相关系数的平方,也称为决定系数$R^2$来评估模型的有效性.

测试集合:

$$残差平方和 RSS = \sum_{i=1}^n(y_i-f(x_i))^2$$

$$总的平方和 TSS = \sum_{i=1}^n(y_i-\overline{y})^2$$

$$R^2 = 1 - \frac{RSS}{TSS}$$

所以 $R^2$ 的值为除去残差外的模型所解释的响应变量的方差比例.R^2 介于0和1之间,越大越好.

R^2的局限性: 对异常值非常敏感.

## 计算决定系数 R2
X_test = np.array([8,9,11,16,12]).reshape(-1,1)
y_test = np.array([11,8.5,15,18,11]).reshape(-1,1)
y_predict = np.array([9.7759,10.7522,12.7048,17.5863,   13.6811]).reshape(-1,1)

y_test_mean = np.mean(y_test)
TSS = ((y_test - y_test_mean)**2).sum()
RSS = ((y_test - y_predict)**2).sum()
R2 = 1-RSS/TSS
print('R2:',round(R2,4)) # R2: 0.662

## 使用 LinearRegression 类的 score方法返回 R2
model = LinearRegression()
model.fit(X,y)
r2 = model.score(X_test,y_test)
print('r2:',round(r2,4)) # r2: 0.662

2.3 小结

简单线性回归模型:

解释变量:单个

响应变量: 单个连续变量

损失函数: 残差平方和 RSS

模型性能评估: $决定系数 R^2 = 1 - \frac{RSS}{TSS}$, 决定系数越大, 方差中残差平方和RSS占比越小, 模型所解释的方差占比越大, 模型拟合程度越好.

© Licensed under CC BY-NC-SA 4.0

没有人足够完美,以至可以未经别人同意就支配别人。 ——林肯

发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!