Skip to content

案例:波士顿房价预测

通过案例掌握正规方程和梯度下降法 API 的使用

本节使用 scikit-learn 自带的波士顿房价数据集来训练模型,然后用模型来测算房价。

输入特征

房价和哪些因素有关?很多人可能对这个问题特别敏感,随时可以列出很多,如房子面积、房子地理位置、周边教育资源、周边商业资源、房子朝向、年限、小区情况等。在 scikit-learn 的波士顿房价数据集里,它总共收集了 13 个特征,具体如下。

属性名解释类型
CRIM该镇的人均犯罪率连续值
ZN占地面积超过 25,000 平方吸的住宅用地比例连续值
INDUS非零售商业用地比例连续值
CHAS是否邻近 Charles River离散值,1=邻近;0=不令
NOx一氧化氮浓度连续值
RM每栋房屋的平均客房数连续值
AGE1940 年之前建成的自用单位比例连续值
DIS到波士顿 5 个就业中心的加权距离连续值
RAD到径向公路的可达性指数连续值
TAX全值财产税率连续值
PTRATIO学生与教师的比例连续值
B1000(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 来指定学习率。
    • 属性:
      • SGDRegressor.coef_:回归系数
      • SGDRegressor.intercept_:偏置

sklearn 提供给我们两种实现的 API,可以根据选择使用

小结

  • 正规方程
    • sklearn.linear_model.LinearRegression()
  • 梯度下降法
    • sklearn.linear_model.SGDRegressor()

代码实现

正规方程

python
# 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)

梯度下降法

python
"""
梯度下降法
    举例
        山 -- 可微分的函数
        山低 -- 函数的最小值
    梯度
        单变量 -- 切线
        多变量 -- 向量
    梯度下降法中需要关注的两个参数
        α -- 就是步长
            步长太小 -- 下山太慢
            步长太大 -- 容易跳过极小值
        为什么梯度要加一个负号
            梯度方向是上升最快的方向,负号就是下降最快的方向
"""
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)

我们也可以尝试去修改学习率

python
estimator = SGDRegressor(max_iter=1000,learning_rate="constant",eta0=0.1)

此时我们可以通过调参数,找到学习率效果更好的值。

回归性能评估

给定的这些特征,是专家们得出的影响房价的结果属性。我们此阶段不需要自己去探究特征是否有用,只需要使用这些特征。到后面量化很多特征需要我们自己去寻找

假设刚才的房子例子,真实的数据之间存在这样的关系:

python
真实关系:真实房子价格 = 0.02×中心区域的距离 + 0.04×城市一氧化氮浓度 + (-0.12×自住房平均房价) + 0.254×城镇犯罪率

那么现在呢,我们随意指定一个关系(猜测)

python
随机指定关系:预测房子价格 = 0.25×中心区域的距离 + 0.14×城市一氧化氮浓度 + 0.42×自住房平均房价 + 0.34×城镇犯罪率

请问这样的话,会发生什么?真实结果与我们预测的结果之间是不是存在一定的误差呢?类似这样样子

![image-20190221093806586](assets/03_case01/房屋价格回归举例 .png)

既然存在这个误差,那我们就将这个误差给衡量出来

均方误差 (Mean Squared Error)MSE) 评价机制:

![线性回归评估](assets/03_case01/线性回归评估 .png)

注:y^i^ 为预测值,y 为真实值

思考:MSE 和最小二乘法的区别是?

  • sklearn.metrics.mean_squared_error(y_true, y_pred)
    • 均方误差回归损失
    • y_true:真实值
    • y_pred:预测值
    • return:浮点数结果

大家可以思考一下,如果要在中国测算房价,你会收集哪些特征数据?这些特征数据的可获得性如何?收集成本多高?