AdaBoost之房价预测

时间:2024-03-03 13:51:11

AdaBoost 不仅可以用于分类问题,还可以用于回归分析。

我们先做个简单回忆,什么是分类,什么是回归呢?实际上分类和回归的本质是一样的,都是对未知事物做预测。不同之处在于输出结果的类型,分类输出的是一个离散值,因为物体的分类数有限的,而回归输出的是连续值,也就是在一个区间范围内任何取值都有可能。

如何使用 AdaBoost 工具

from sklearn.ensemble import AdaBoostClassifier       # 分类
from sklearn.ensemble import AdaBoostRegressor       # 回归

如何在 sklearn 中创建 AdaBoost 分类器:

如何创建 AdaBoost 回归呢?

如何用 AdaBoost 对房价进行预测

我们看下 sklearn 中自带的波士顿房价数据集。这个数据集一共包括了 506 条房屋信息数据,每一条数据都包括了 13 个指标,以及一个房屋价位。

13 个指标的含义,可以参考下面的表格:

首先加载数据,将数据分割成训练集和测试集,然后创建 AdaBoost 回归模型,传入训练集数据进行拟合,再传入测试集数据进行预测,就可以得到预测结果。最后将预测的结果与实际结果进行对比,得到两者之间的误差。具体代码如下:

from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.datasets import load_boston
from sklearn.ensemble import AdaBoostRegressor
# 加载数据
data=load_boston()
# 分割数据
train_x, test_x, train_y, test_y = train_test_split(data.data, data.target, test_size=0.25, random_state=33)
# 使用 AdaBoost 回归模型
regressor=AdaBoostRegressor()
regressor.fit(train_x,train_y)
pred_y = regressor.predict(test_x)
mse = mean_squared_error(test_y, pred_y)
print(" 房价预测结果 ", pred_y)
print(" 均方误差 = ",round(mse,2))

运行结果:

房价预测结果  [20.2        10.4137931  14.63820225 17.80322581 24.58931298 21.25076923
 27.52222222 17.8372093  31.79642857 20.86428571 27.87431694 31.09142857
 12.81666667 24.13131313 12.81666667 24.58931298 17.80322581 17.66333333
 27.83       24.58931298 17.66333333 20.90823529 20.10555556 20.90823529
 28.20877193 20.10555556 21.16882129 24.58931298 13.27619048 31.09142857
 17.08095238 26.19217391  9.975      21.03404255 26.74583333 31.09142857
 25.83960396 11.859375   13.38235294 24.58931298 14.97931034 14.46699029
 30.12777778 17.66333333 26.19217391 20.10206186 17.70540541 18.45909091
 26.19217391 20.10555556 17.66333333 33.31025641 14.97931034 17.70540541
 24.64421053 20.90823529 25.83960396 17.08095238 24.58931298 21.43571429
 19.31617647 16.33733333 46.04888889 21.25076923 17.08095238 25.83960396
 24.64421053 11.81470588 17.80322581 27.63636364 23.59731183 17.94444444
 17.66333333 27.7253886  20.21465517 46.04888889 14.97931034  9.975
 17.08095238 24.13131313 21.03404255 13.4        11.859375   26.19214286
 21.25076923 21.03404255 47.11395349 16.33733333 43.21111111 31.65730337
 30.12777778 20.10555556 17.8372093  18.40833333 14.97931034 33.31025641
 24.58931298 22.88813559 18.27179487 17.80322581 14.63820225 21.16882129
 26.91538462 24.64421053 13.05       14.97931034  9.975      26.19217391
 12.81666667 26.19214286 49.46511628 13.27619048 17.70540541 25.83960396
 31.09142857 24.13131313 21.25076923 21.03404255 26.91538462 21.03404255
 21.16882129 17.8372093  12.81666667 21.03404255 21.03404255 17.08095238
 45.16666667]
均方误差 =  18.05

同样,我们可以使用不同的回归分析模型分析这个数据集,比如使用决策树回归和 KNN 回归。

# 使用决策树回归模型
dec_regressor=DecisionTreeRegressor()
dec_regressor.fit(train_x,train_y)
pred_y = dec_regressor.predict(test_x)
mse = mean_squared_error(test_y, pred_y)
print(" 决策树均方误差 = ",round(mse,2))
# 使用 KNN 回归模型
knn_regressor=KNeighborsRegressor()
knn_regressor.fit(train_x,train_y)
pred_y = knn_regressor.predict(test_x)
mse = mean_squared_error(test_y, pred_y)
print("KNN 均方误差 = ",round(mse,2))


#运行结果:
决策树均方误差 =  23.84
KNN 均方误差 =  27.87

相比之下,AdaBoost 的均方误差更小,也就是结果更优。虽然 AdaBoost 使用了弱分类器,但是通过 50 个甚至更多的弱分类器组合起来而形成的强分类器,在很多情况下结果都优于其他算法。因此 AdaBoost 也是常用的分类和回归算法之一。

AdaBoost 与决策树模型的比较

在 sklearn 中 AdaBoost 默认采用的是决策树模型,我们可以随机生成一些数据,然后对比下 AdaBoost 中的弱分类器(也就是决策树弱分类器)、决策树分类器和 AdaBoost 模型在分类准确率上的表现。

如果想要随机生成数据,我们可以使用 sklearn 中的 make_hastie_10_2 函数生成二分类数据。假设我们生成 12000 个数据,取前 2000 个作为测试集,其余作为训练集。

我设置了 AdaBoost 的迭代次数为 200,代表 AdaBoost 由 200 个弱分类器组成。针对训练集,我们用三种模型分别进行训练,然后用测试集进行预测,并将三个分类器的错误率进行可视化对比,可以看到这三者之间的区别:

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.metrics import zero_one_loss
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import  AdaBoostClassifier
# 设置 AdaBoost 迭代次数
n_estimators=200
# 使用
X,y=datasets.make_hastie_10_2(n_samples=12000,random_state=1)
# 从 12000 个数据中取前 2000 行作为测试集,其余作为训练集
test_x, test_y = X[2000:],y[2000:]
train_x, train_y = X[:2000],y[:2000]
# 弱分类器
dt_stump = DecisionTreeClassifier(max_depth=1,min_samples_leaf=1)
dt_stump.fit(train_x, train_y)
dt_stump_err = 1.0-dt_stump.score(test_x, test_y)
# 决策树分类器
dt = DecisionTreeClassifier()
dt.fit(train_x,  train_y)
dt_err = 1.0-dt.score(test_x, test_y)
# AdaBoost 分类器
ada = AdaBoostClassifier(base_estimator=dt_stump,n_estimators=n_estimators)
ada.fit(train_x,  train_y)
# 三个分类器的错误率可视化
fig = plt.figure()
# 设置 plt 正确显示中文
plt.rcParams[\'font.sans-serif\'] = [\'SimHei\']
ax = fig.add_subplot(111)
ax.plot([1,n_estimators],[dt_stump_err]*2, \'k-\', label=u\'决策树弱分类器 错误率\')     
ax.plot([1,n_estimators],[dt_err]*2,\'k--\', label=u\'决策树模型 错误率\')
ada_err = np.zeros((n_estimators,))
# 遍历每次迭代的结果 i 为迭代次数, pred_y 为预测结果
for i,pred_y in enumerate(ada.staged_predict(test_x)):    # 预测每一轮迭代后输入样本的预测值
     # 统计错误率
    ada_err[i]=zero_one_loss(pred_y, test_y)         # 返回0-1损失
# 绘制每次迭代的 AdaBoost 错误率 
ax.plot(np.arange(n_estimators)+1, ada_err, label=\'AdaBoost Test 错误率\', color=\'orange\')
ax.set_xlabel(\'迭代次数\')
ax.set_ylabel(\'错误率\')
leg=ax.legend(loc=\'upper right\',fancybox=True)
plt.show()

运行结果:

从图中你能看出来,弱分类器的错误率最高,只比随机分类结果略好,准确率稍微大于 50%。决策树模型的错误率明显要低很多。而AdaBoost 模型在迭代次数超过 25 次之后,错误率有了明显下降,经过 125 次迭代之后错误率的变化形势趋于平缓。

因此我们能看出,虽然单独的一个决策树弱分类器效果不好,但是多个决策树弱分类器组合起来形成的 AdaBoost 分类器,分类效果要好于决策树模型。

总结: