从简单线性回归到多元线性回归
从简单线性回归到多元线性回归
之前,我们使用简单线性回归对一个解释变量和一个连续响应变量之间的关系进行建模,并使用披萨的直径去预测其价格。我们将讨论多元线性回归,它一种将一个连续响应变量在多个特征上进行回归的简单线性回归泛化形式。我们首先将出能将 RSS 代价函数极小化的参数值。接着介绍一种能预估多种代价函数极小值参数值强大的学习算法,称为梯度下降法。我们还将讨论另一种多元线性回归的特殊形式—项式回归,并了解增加模型的复杂度将增大模型泛化失败风险的原因。
回顾你个人吃披萨的经验,从直觉上你可能感到披萨的其他特征也和其价格相关联。我们在此不能使用简单线性回归进行处理,但是我们可以使用一种称为多元线性回归的简单线性回归的泛化形式,它可以使用多个解释变量。多元线性回归模型如下公式所示:
用矩阵表示为:
\(Y\) 是一个由训练实例响应变量组成的列向量。\(\beta\) 是一个由模型参数值组成的列向量。\(X\) 有时也被称为设计矩阵,是一个由训练实例解释变量组成的 \(m \times n\) 的矩阵。\(m\) 是训练实例的数量,\(n\) 是特征的数量。
很明显,如果 \(X\) 是方阵且可逆,那么可以求出 \(\beta\) 的解析解。矩阵 \(X\) 并不一定是方阵,而我们也不能用特征的数量来限制训练实例的数量。为了避开这个限制,我们需要将 \(X\) 乘以其转置来产出一个可以求逆的方阵。(尽管它并不一定存在逆矩阵)可以解出 \(\beta\) 的值:
下面是我们手动解出 \(\beta\) 的值:
>>> import numpy as np
>>>
>>> X = [[1, 6, 2], [1, 8, 1], [1, 10, 0], [1, 14, 2], [1, 18, 0]]
>>> y = [[7], [9], [13], [17.5], [18]]
>>>
>>> np.dot(np.linalg.inv(np.dot(np.transpose(X), X)), np.dot(np.transpose(X), y))
array([[1.1875 ],
[1.01041667],
[0.39583333]])
>>>
也可以使用 Numpy 内置的最小二乘函数来获得参数:
np.linalg.lstsq(X, y)[0]
新增 1 个解释变量来更新披萨价格预测代码,并在测试集上和简单线性回归模型比较性能。
>>> from sklearn.linear_model import LinearRegression
>>>
>>> X = [[6, 2], [8, 1], [10, 0], [14, 2], [18, 0]]
>>> y = [7, 9, 13, 17.5, 18]
>>> model = LinearRegression()
>>> model.fit(X, y)
LinearRegression()
>>> X_test = [[8, 2], [9, 0], [11, 2], [16, 2], [12, 0]]
>>> y_test = [11, 8.5, 15, 18, 11]
>>> predictions = model.predict(X_test)
>>> for prediction, target in zip(predictions, y):
... print(f"Predicted: {prediction:.2f}, Target: {target:.2f}")
...
Predicted: 10.06, Target: 7.00
Predicted: 10.28, Target: 9.00
Predicted: 13.09, Target: 13.00
Predicted: 18.15, Target: 17.50
Predicted: 13.31, Target: 18.00
>>> print(f"R^2: {model.score(X_test, y_test):.2f}")
R^2: 0.77
>>>
从评价指标中可以看出,模型的性能有提升,在简单线性回归中,\(R^2\) 只有 0.66,而多元回归到达了 0.77。
多项式回归
在前面的例子中,我们假设解释变量和响应变量之间的真实关系是线性的。这里,我们将使用多项式回归来对响应变量和多项式特征项之间的关系进行建模。真实世界的曲线关系通过对特征做变换获得,而这些特征与多元线性回归的特征一致。
二次回归,或者二阶多项式回归,由下面公式表示:
PolynomialFeatures
转换器可以用于为一个特征表示增加多项式特征。我们使用这些特征来拟合一个模型,并将其和简单线性回归模型做比较:
from sklearn.preprocessing import PolynomialFeatures
import matplotlib.pyplot as plt
X_train = [[6], [8], [10], [14], [18]]
y_train = [7, 9, 13, 17.5, 18]
X_test = [[6], [8], [11], [16]]
y_test = [8, 12, 15, 18]
regressor = LinearRegression()
regressor.fit(X_train, y_train)
xx = np.linspace(0, 26, 100)
yy = regressor.predict(xx.reshape(-1, 1))
plt.plot(xx, yy, label=f"{regressor.score(X_test, y_test):.2f}")
quadratic_featurizer = PolynomialFeatures(degree=2)
X_train_quadratic = quadratic_featurizer.fit_transform(X_train)
X_test_quadratic = quadratic_featurizer.transform(X_test)
regressor_quadratic = LinearRegression()
regressor_quadratic.fit(X_train_quadratic, y_train)
xx_quadratic = quadratic_featurizer.transform(xx.reshape(-1, 1))
yy_quadratic = regressor_quadratic.predict(xx_quadratic)
plt.plot(
xx,
yy_quadratic,
c="r",
linestyle="--",
label=f"{regressor_quadratic.score(X_test_quadratic, y_test):.2f}",
)
plt.title("Pizza price regressed on diameter")
plt.xlabel("Diameter in inches")
plt.ylabel("Price in dollars")
plt.axis([0, 25, 0, 25])
plt.grid(True)
plt.scatter(X_train, y_train)
plt.legend()
确实较好,但是很明显图中是不合逻辑的,如果披萨的尺寸变大,那么价格反而下跌,这个模型只是在训练数据上表现的性能还不错。
如果增加模型的阶数,那么基本上可以通过训练数据上的全部点,但是这个模型在测试数据上的作用基本为 0。
正则化
正则化是一个能用于防止过拟合的技巧的集合。正则化为一个问题增加信息,通常是用一个对抗复杂度惩罚项的形式。奥卡姆剃刀理论说做最少假定的假设是最优的。正因如此,正则化想要找到最简单的模型来解释数据。
scikit-learn 类库提供了几个正则化线性回归模型。岭回归也被称之为提克洛夫规范化,可以惩罚变大的模型参数。岭回归通过增加系数的 \(L^2\) 范数来修改 RSS 代价函数:
\(\lambda\) 是一个控制惩罚力度的超参数。随着 \(\lambda\) 的增加,惩罚力度也增加,代价函数的值也增加。当 \(\lambda\) 等于 0 时,岭回归等于线性回归。
scikit-learn 库也提供了最小绝对收缩和选择算子(LASSO)的一种实现。LASSO 算法通过对代价函数增加 \(L^1\) 范数来惩罚系数:
LASSO 回归产出系数的参数,大多数系数将变为 0,模型将依赖于特征的一个小型子集。与之相反,岭回归产出模型的大多数参数很小但都非 0。当解释变量相互关联时,LASSO 回归将一个变量的系数向 0 进行收缩,岭回归则将更一致地对系数进行收缩。
最后,scikit-learn 库提供了弹性网正则化的一种实现,它是 LASSO 回归的 \(L^1\) 惩罚项和岭回归的 \(L^2\) 惩罚项的线性组合。也就是说,LASSO 回归和岭回归都是弹性网方法的特殊形式,其中 \(L^1\) 或者 \(L^2\) 惩罚项对应的超参数分别等于 0。
我不理解为什么较小的回归系数就可以降低模型的过拟合
应用线性回归
加州大学机器学习库的酒数据集包含了 1599 种不同红酒的 11 种物理化学属性,包括 pH 值和酒精含量。每种酒的质量由真人评价来打分。分数范围从 0~10,0 代表质量最差,10 代表质量最好。我们将把该问题作为一个回归任务来解决,并在一个或多个物理化学属性上回归酒的质量。在这个问题中响应变量只会取 0~10 之间的整数,我们可以将这些值视作离散值,并将该问题作为一个多类别分类问题来解决。这里,我们将假定这些评分都是连续的。
探索数据
训练数据包含以下解释变量:非挥发性酸、挥发性酸、柠檬酸、剩余糖分、氯化物、单体硫、总二氧化硫、密度、pH 值、硫酸盐和酒精含量。对设计成功的机器学习系统来说相关领域的专家通常很重要。
非挥发性酸 | 挥发性酸 | 柠檬酸 | 剩余糖分 | 氯化物 | 单体硫 | 总二氧化硫 | 密度 | pH 值 | 硫酸盐 | 酒精含量 | 质量 |
---|---|---|---|---|---|---|---|---|---|---|---|
7.4 | 0.7 | 0 | 1.9 | 0.076 | 11 | 34 | 0.9978 | 3.51 | 0.56 | 9.45 | 5 |
7.8 | 0.88 | 0 | 2.6 | 0.098 | 25 | 67 | 0.9968 | 3.2 | 0.68 | 9.8 | 5 |
7.8 | 0.76 | 0.04 | 2.3 | 0.092 | 15 | 54 | 0.997 | 3.26 | 0.65 | 9.8 | 5 |
11.2 | 0.28 | 0.56 | 1.9 | 0.075 | 17 | 60 | 0.998 | 3.16 | 0.58 | 9.8 | 6 |