案例:波士顿房价预测
通过案例掌握正规方程和梯度下降法 API 的使用
本节使用 scikit-learn 自带的波士顿房价数据集来训练模型,然后用模型来测算房价。
输入特征
房价和哪些因素有关?很多人可能对这个问题特别敏感,随时可以列出很多,如房子面积、房子地理位置、周边教育资源、周边商业资源、房子朝向、年限、小区情况等。在 scikit-learn 的波士顿房价数据集里,它总共收集了 13 个特征,具体如下。
属性名 | 解释 | 类型 |
---|---|---|
CRIM | 该镇的人均犯罪率 | 连续值 |
ZN | 占地面积超过 25,000 平方吸的住宅用地比例 | 连续值 |
INDUS | 非零售商业用地比例 | 连续值 |
CHAS | 是否邻近 Charles River | 离散值,1=邻近;0=不令 |
NOx | 一氧化氮浓度 | 连续值 |
RM | 每栋房屋的平均客房数 | 连续值 |
AGE | 1940 年之前建成的自用单位比例 | 连续值 |
DIS | 到波士顿 5 个就业中心的加权距离 | 连续值 |
RAD | 到径向公路的可达性指数 | 连续值 |
TAX | 全值财产税率 | 连续值 |
PTRATIO | 学生与教师的比例 | 连续值 |
B | 1000(BK - 0.63) 个 2,其中 BK 为黑人占比 | 连续值 |
LSTAT | 低收入人群占比 | 连续值 |
MEDV | 同类房屋价格的中位数 | 连续值 |
从这些指标里可以看到中美文化的一些差异。当然,这个数据是在 1993 年之前收集的,可能和现在会有差异。不要小看了这些指标,实际上一个模型的好坏和输入特征的选择关系密切。
线性回归 API 再介绍
sklearn.linear_model.LinearRegression(fit_intercept=True)
通过正规方程优化
参数
- fit_intercept:是否计算偏置
属性
- LinearRegression.coef_:回归系数
- LinearRegression.intercept_:偏置
sklearn.linear_model.SGDRegressor(loss="squared_loss", fit_intercept=True, learning_rate ='invscaling', eta0=0.01)
- SGDRegressor 类实现了随机梯度下降学习,它支持不同的loss 函数和正则化惩罚项来拟合线性回归模型。
- 参数:
- loss:损失类型
- loss=”squared_loss”: 普通最小二乘法
- fit_intercept:是否计算偏置
- learning_rate : string, optional
- 学习率填充
- 'constant': eta = eta0
- 'optimal': eta = 1.0 / (alpha * (t + t0)) [default]
- 'invscaling': eta = eta0 / pow(t, power_t)
- power_t=0.25:存在父类当中
- 对于一个常数值的学习率来说,可以使用 learning_rate=’constant’ ,并使用 eta0 来指定学习率。
- loss:损失类型
- 属性:
- SGDRegressor.coef_:回归系数
- SGDRegressor.intercept_:偏置
sklearn 提供给我们两种实现的 API,可以根据选择使用
小结
- 正规方程
- sklearn.linear_model.LinearRegression()
- 梯度下降法
- sklearn.linear_model.SGDRegressor()
代码实现
正规方程
# coding:utf-8
"""
1. 获取数据
2. 数据基本处理
2.1 数据集划分
3. 特征工程 --标准化
4. 机器学习 (线性回归)
5. 模型评估
"""
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
"""
正规方程
"""
# 1. 获取数据
boston = load_boston()
# 2. 数据基本处理
# 2.1 数据集划分
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, test_size=0.2)
# 3. 特征工程 --标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4. 机器学习 (线性回归)
estimator = LinearRegression()
estimator.fit(x_train, y_train)
print("这个模型的偏置是:\n", estimator.intercept_)
# 5. 模型评估
# 5.1 预测值和准确率
y_pre = estimator.predict(x_test)
print("预测值是:\n", y_pre)
score = estimator.score(x_test, y_test)
print("准确率是:\n", score)
# 5.2 均方误差
ret = mean_squared_error(y_test, y_pre)
print("均方误差是:\n", ret)
梯度下降法
"""
梯度下降法
举例
山 -- 可微分的函数
山低 -- 函数的最小值
梯度
单变量 -- 切线
多变量 -- 向量
梯度下降法中需要关注的两个参数
α -- 就是步长
步长太小 -- 下山太慢
步长太大 -- 容易跳过极小值
为什么梯度要加一个负号
梯度方向是上升最快的方向,负号就是下降最快的方向
"""
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, SGDRegressor
from sklearn.metrics import mean_squared_error
"""梯度下降法"""
# 1. 获取数据
boston = load_boston()
# 2. 数据基本处理
# 2.1 数据集划分
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, test_size=0.2)
# 3. 特征工程 --标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4. 机器学习 (线性回归)
estimator = SGDRegressor(max_iter=1000, learning_rate="constant", eta0=0.001)
estimator.fit(x_train, y_train)
print("这个模型的偏置是:\n", estimator.intercept_)
# 5. 模型评估
# 5.1 预测值和准确率
y_pre = estimator.predict(x_test)
print("预测值是:\n", y_pre)
score = estimator.score(x_test, y_test)
print("准确率是:\n", score)
# 5.2 均方误差
ret = mean_squared_error(y_test, y_pre)
print("均方误差是:\n", ret)
我们也可以尝试去修改学习率
estimator = SGDRegressor(max_iter=1000,learning_rate="constant",eta0=0.1)
此时我们可以通过调参数,找到学习率效果更好的值。
回归性能评估
给定的这些特征,是专家们得出的影响房价的结果属性。我们此阶段不需要自己去探究特征是否有用,只需要使用这些特征。到后面量化很多特征需要我们自己去寻找
假设刚才的房子例子,真实的数据之间存在这样的关系:
真实关系:真实房子价格 = 0.02×中心区域的距离 + 0.04×城市一氧化氮浓度 + (-0.12×自住房平均房价) + 0.254×城镇犯罪率
那么现在呢,我们随意指定一个关系(猜测)
随机指定关系:预测房子价格 = 0.25×中心区域的距离 + 0.14×城市一氧化氮浓度 + 0.42×自住房平均房价 + 0.34×城镇犯罪率
请问这样的话,会发生什么?真实结果与我们预测的结果之间是不是存在一定的误差呢?类似这样样子

既然存在这个误差,那我们就将这个误差给衡量出来
均方误差 (Mean Squared Error)MSE) 评价机制:

注:y^i^ 为预测值,
思考:MSE 和最小二乘法的区别是?
- sklearn.metrics.mean_squared_error(y_true, y_pred)
- 均方误差回归损失
- y_true:真实值
- y_pred:预测值
- return:浮点数结果
大家可以思考一下,如果要在中国测算房价,你会收集哪些特征数据?这些特征数据的可获得性如何?收集成本多高?