4. 北京市住房价格预测#

4.1. 介绍#

关于线性回归的实验中,我们以预测波士顿地区房价举例,详细讨论了其实现过程。本次挑战中,你需要运用从线性回归中学习到的相关知识,来预测北京市的住房价格。

4.2. 知识点#

  • 数据集读取与划分

  • 模型训练及预测

  • 模型评价

4.3. 数据集读取与划分#

挑战需要下载北京市部分小区的房价数据集,该数据集的名字为 challenge-1-beijing.csv

# 数据集下载链接
https://cdn.huhuhang.com/hands-on-ai/files/challenge-1-beijing.csv

北京市住房价格数据集来源于开源项目:PENGZhaoqing/scrapy-HousePricing

Exercise 4.1

挑战:使用 Pandas 加载数据集 CSV 文件,并预览前 5 行数据。

规定:使用 pd.read_csv() 读取 CSV 文件。

import pandas as pd

## 代码开始 ### (≈ 2 行代码)
df = None
## 代码结束 ###

期望输出

公交 写字楼 医院 商场 地铁 学校 小区名字 建造时间 房型 楼层 每平米价格 面积
0 18 18 10 0 2 49 远洋山水 2006 2室1厅 26 60937 96
1 17 42 10 0 4 37 椿树园 1998 3室1厅 14 88686 130
2 18 36 9 0 1 24 永乐小区 1989 3室1厅 18 46621 74
3 15 49 13 0 2 45 主语家园 2007 4室3厅 2 86147 462
4 6 0 0 0 0 0 天伦锦城 2007 1室1厅 13 42500 64

可以看到,该数据集中共包含有 12 列。由于线性回归需要输入数值型数据,所以我们选用的特征包括「公交,写字楼,医院,商场,地铁,学校,建造时间,楼层,面积」等 9 项,而「每平米价格」则是预测目标值。

Exercise 4.2

挑战:对加载完成的数据集进行划分,分割为特征值 features 数据集和目标值 target 数据集。

规定:使用 Pandas 选择数据列。

## 代码开始 ### (≈ 1 行代码)
features = None
target = df['每平米价格']
## 代码结束 ###

运行测试

pd.concat([features, target], axis=1).head()

期望输出

公交 写字楼 医院 商场 地铁 学校 建造时间 楼层 面积 每平米价格
0 18 18 10 0 2 49 2006 26 96 60937
1 17 42 10 0 4 37 1998 14 130 88686
2 18 36 9 0 1 24 1989 18 74 46621
3 15 49 13 0 2 45 2007 2 462 86147
4 6 0 0 0 0 0 2007 13 64 42500

将原始 DataFrame 分割为特征值 features 和目标值 target 之后。我们还需要将这两个 DataFrame 划分为 70% 和 30% 的训练集和测试集。其中,训练集特征、训练集目标、测试集特征和测试集目标分别定义为:X_train, y_train, X_test, y_test

Exercise 4.3

挑战:将 featurestarget 两个 DataFrame 各划分为 70% 和 30% 的训练集和测试集。

规定:这里使用 Pandas 按 70% 分割数进行 DataFrame 切片的方法分割数据。

split_num = int(len(df)*0.7) # 70% 分割数

## 代码开始 ### (≈ 4 行代码)
X_train = None
y_train = None
X_test = None
y_test = None
## 代码结束 ###

运行测试

len(X_train), len(y_train), len(X_test), len(y_test)

期望输出

(2100, 2100, 900, 900)

可以看到,训练集包含 2100 条数据,而测试集包含 900 条数据。

4.4. 模型训练及预测#

有了训练和测试数据,下面就可以开始构建机器学习模型。这里直接使用 scikit-learn 中的线性回归方法建立模型。

Exercise 4.4

挑战:使用 scikit-learn 建立并训练线性回归模型。

规定:model.fit() 方法可以用于训练模型。

from sklearn.linear_model import LinearRegression

## 代码开始 ### (≈ 2 行代码)
model = None

## 代码结束 ###

运行测试

model.coef_[:3], len(model.coef_)

期望输出

(array([6.59398431, 299.47265083, 371.60427218]), 9)

4.5. 模型评价#

在线性回归实验中,我们提供了两种回归预测结果的评价指标,分别是平均绝对误差 MAE 和均方误差 MSE。本次挑战中,我们另介绍一种评价指标,那就是平均绝对百分比误差 MAPE。

MAPE 是一个百分比值,因此比其他统计量更容易理解。例如,如果 MAPE 为 \(5\),则表示预测结果较真实结果平均偏离 \(5\%\)。MAPE 的计算公式如下:

\[ \textrm{MAPE}(y, \hat{y} ) = \frac{\sum_{i=1}^{n}{|\frac{y_{i}-\hat y_{i}}{y_{i}}|}}{n} \times 100 \tag{1} \]

其中,\(y_{i}\) 表示真实值,\(\hat y_{i}\) 表示预测值,\(n\) 则表示值的个数。MAPE 的值越小,说明预测模型拥有更好的精确度。

Exercise 4.5

挑战:model.fit() 方法可以用于训练模型。

规定:np.abs() 方法可以用于计算绝对值。

import numpy as np

def mape(y_true, y_pred):
    """
    参数:
    y_true -- 测试集目标真实值
    y_pred -- 测试集目标预测值
    
    返回:
    mape -- MAPE 评价指标
    """
    
    ### 代码开始 ### (≈ 2 行代码)
    
    mape = None
    ### 代码结束 ###
    
    return mape

运行测试

y_true = y_test.values
y_pred = model.predict(X_test)
mape(y_true, y_pred)

期望输出

45.5%

可以看到,最终得到的 MAPE 值较大,意味着预测的偏移量较大。在线性回归实验中,我们提到预测结果较差的一个原因可能是数据没有经过预处理。除此之外,线性回归本身就是一种非常基础简单的预测方法。对于房价这种包含多个特征的预测问题,我们往往要使用更复杂的方法来进行回归预测才能得到更好的结果。这也就是后面要学习到的内容。