【火炉炼AI】机器学习006-用决策树回归器构建房价评估模型

【火炉炼AI】机器学习006-用决策树回归器构建房价评估模型

(本文所使用的Python库和版本号: Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )

最近几十年,房价一直是中国老百姓心中永远的痛,有人说,中国房价就像女人的无肩带文胸,一半人在疑惑:是什么支撑了它?另一半人在等待:什么时候掉下去? 而女人,永不可能让它掉下来。就算快掉下来了,提一提还是又上去了.....

虽然我们不能预测中国房价什么时候崩盘,但是却可以用机器学习来构建房价预测模型,下面我们使用波士顿房价数据集来建立一个房价评估模型,通过房子所在的地理位置,人口居住特性等因素来综合评估房价。

1. 分析数据集

本次模型所使用的数据集来自于波士顿房价数据集官方网站,地址为:(http://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html)。

这个数据集比较小,只有506个样本,每个样本有13个features, 1个label,关于这14个属性的说明如下图所示:

所以我们需要构建模型,使用前面的13个特征来评估最后的MEDV,即使用13个特征向量来计算房价,这是典型的多元回归问题。虽然可以从官网上直接下载这个数据集,但是sklearn中已经集成了该数据集,我们可以直接调用。如下代码

# 分析数据集
from sklearn import datasets # sklearn自带的datasets中就有Boston房价数据集
housing_data=datasets.load_boston()
dataset_X=housing_data.data # 获取影响房价的特征向量,作为feaure X
dataset_y=housing_data.target # 获取对应的房价,作为label y
# print(dataset_X.shape) # (506, 13) # 一共有506个样本,每个样本有13个features
# print(dataset_y.shape) # (506,)
# print(dataset_X[:5,:]) # 打印看看features的数值类型和大小,貌似已经normalize.

# 将整个数据集划分为train set 和test set两部分
from sklearn.utils import shuffle
dataset_X,dataset_y=shuffle(dataset_X,dataset_y)
# print(dataset_X[:5,:]) # 确认dataset_X 的确发生了shuffle
num_split=int(0.8*len(dataset_X))
train_X,train_y=dataset_X[:num_split],dataset_y[:num_split]
test_X,test_y=dataset_X[num_split:],dataset_y[num_split:]
# print(train_X.shape) # (404, 13)
# print(test_X.shape) # (102, 13)

# 上面的数据集划分也可以采用下面的方法:
# from sklearn.model_selection import train_test_split
# dataset_y=dataset_y[:,np.newaxis]
# dataset=np.hstack((dataset_X,dataset_y))
# print(dataset.shape)
# print(dataset[:,:3])
# train_set,test_set=train_test_split(dataset,test_size=0.2,random_state=37)
# print(train_set.shape) # (404, 14)
# print(test_set.shape) # (102, 14)

上述代码首先调用sklearn.load_boston()来获取波士顿房价数据集,然后将该数据集划分为两部分,其中train set占据80%(即404个样本),test set占据20%(102个样本)。在查看数据集中前面五行的结果时,发现整个数据集已经Normalize,故而此处我们没有必要进行归一化。

2. 构建决策树模型

决策树(DecisionTree, DT)是一种常见的用于分类和回归的非参数监督学习方法,目标是创建一个模型,通过从数据特性中推导出简单的决策规则来预测目标变量的值。

决策树模型的优点在于:1,简单容易理解,数结构可以可视化表达。2,需要很少的数据准备,其他技术通常需要数据标准化,需要创建虚拟变量,并删除空白值。3,能够处理多输出问题。4,相比于使用神经网络的模型,决策树是白盒模型,结果很容易解释。

决策树模型的缺点在于:1,决策树学习可能会生成过于复杂的数结构,不能代表普遍的规则,即模型容易过拟合,修剪机制,设置叶子节点所需的最小样本数目或设置数的最大深度是避免决策树过拟合的必要条件。2,决策树可能不稳定,因为数据中的小变化可能导致生成完全不同的树。这个问题可以通过在一个集合中使用多个决策树来减轻。3,实际的决策树学习算法是基于启发式算法的,例如在每个节点上进行局部最优决策的贪婪算法。这种算法不能保证返回全局最优决策树。通过在集合学习中训练多个树,可以减少这种情况,在这里,特征和样本是随机抽取的。4,有些概念很难学习,因为决策树无法很容易地表达它们,例如XOR、奇偶性或多路复用问题。

说了这么多废话,直接看代码吧。。。

# 构建决策树回归模型
from sklearn.tree import DecisionTreeRegressor
decision_regressor=DecisionTreeRegressor(max_depth=4) # 最大深度确定为4
decision_regressor.fit(train_X,train_y) # 对决策树回归模型进行训练

# 使用测试集来评价该决策树回归模型
predict_test_y=decision_regressor.predict(test_X)

import sklearn.metrics as metrics
print(‘决策树回归模型的评测结果----->>>‘)
print(‘均方误差MSE:{}‘.format(
    round(metrics.mean_squared_error(predict_test_y,test_y),2)))
print(‘解释方差分:{}‘.format(
    round(metrics.explained_variance_score(predict_test_y,test_y),2)))

-------------------------------------输---------出--------------------------------

决策树回归模型的评测结果----->>>

均方误差MSE:13.33

解释方差分:0.81

--------------------------------------------完-------------------------------------

########################小**********结###############################

1. 决策树回归模型的构建非常简单,和线性回归器的构建类似,使用DecisionTreeRegressor获取一个回归器对象即可,模型的训练使用fit函数,预测使用predict函数即可。

2. 简单的决策树回归模型得到的MSE比较大,解释方差分结果也不理想,说明这个模型还有很大的优化空间。

#################################################################

3. 决策树模型的优化

一般的,可以先从数据集上优化,但本项目的数据集是非常成熟的案例,进一步优化的空间不大,所以只能从模型上下手。此处我采用两种优化方法,第一种是优化决策树模型中的各种参数,比如优化max_depth,判断是否可以改进MSE,第二种方式是使用AdaBoost算法来增强模型的准确性。

# 第一种优化方法:改变max depth来降低MSE,提高解释方差分
for depth in range(2,12):
    decision_regressor_test=DecisionTreeRegressor(max_depth=depth)
    decision_regressor_test.fit(train_X,train_y)
    predict_test_y2=decision_regressor_test.predict(test_X)
    print(‘depth: {}, MSE: {:.2f}, EVS: {:.2f}‘.format(
        str(depth), metrics.mean_squared_error(predict_test_y2,test_y),
        metrics.explained_variance_score(predict_test_y2,test_y)))

-------------------------------------输---------出--------------------------------

depth: 2, MSE: 23.83, EVS: 0.62

depth: 3, MSE: 20.98, EVS: 0.68

depth: 4, MSE: 13.33, EVS: 0.81

depth: 5, MSE: 13.00, EVS: 0.83

depth: 6, MSE: 14.36, EVS: 0.83

depth: 7, MSE: 11.73, EVS: 0.86

depth: 8, MSE: 16.18, EVS: 0.83

depth: 9, MSE: 15.74, EVS: 0.83

depth: 10, MSE: 14.67, EVS: 0.83

depth: 11, MSE: 15.02, EVS: 0.84

--------------------------------------------完-------------------------------------

# 第二种优化方法:通过AdaBoost算法来提高模型准确度
from sklearn.ensemble import AdaBoostRegressor
ada_regressor=AdaBoostRegressor(DecisionTreeRegressor(max_depth=7),n_estimators=400)
ada_regressor.fit(train_X,train_y)

# 查看使用AdaBoost算法后模型的MSE 和EVS
predict_test_y=ada_regressor.predict(test_X)

import sklearn.metrics as metrics
print(‘AdaBoost决策树回归模型的评测结果----->>>‘)
print(‘均方误差MSE:{}‘.format(
    round(metrics.mean_squared_error(predict_test_y,test_y),2)))
print(‘解释方差分:{}‘.format(
    round(metrics.explained_variance_score(predict_test_y,test_y),2)))

-------------------------------------输---------出--------------------------------

AdaBoost决策树回归模型的评测结果----->>>

均方误差MSE:7.87

解释方差分:0.9

--------------------------------------------完-------------------------------------

########################小**********结###############################

1,两种优化方法:第一种通过优化max_depth可以发现,在depth=7时得到的MSE最小,且解释方差分最大,故而认定max_depth=7.

2,第二种通过AdaBoost增强算法来优化模型,得到的MSE(7.87)比depth优化最好的MSE(11.73)要小很多,且解释方差分也有了较大提高,说明优化效果比较好。

3,AdaBoost(Adaptive boosting)算法是一种自适应的利用其他系统来增强模型准确性的算法,将不同版本的算法结果进行组合,用加权汇总的方式获得最终结果。AdaBoost算法在每个阶段获取的信息都会反馈到模型中,这样学习器就可以在后一阶段重点训练难以分类的样本。

4,当然,对于本模型,还可以继续优化,比如优化决策树的结构,优化决策树的其他参数等。

#################################################################

4. 特征的相对重要性

本项目共有13个特征,但这13个特征对于房价的影响肯定是不同的,比如从直观上来看,学区房对房价影响肯定比较大,所以可以计算出各种不同特征对模型的影响,进而在特征比较复杂的情况下,可以忽略掉影响比较小的特征。

如下两部分代码可以将各种特征的相对重要性绘制到图中。

# 计算不同特征的相对重要性
def plot_importances(feature_importances, title, feature_names):
    ‘‘‘将feature_importance绘制到图表中,便于观察,
    并把重要性大于5的特征打印出来‘‘‘
    # 将重要性都归一化为0-100之内
    feature_importances=100.0*(feature_importances/max(feature_importances))

    # 将得分从高到低排序
    index_sorted=np.flipud(np.argsort(feature_importances))
    # 让X坐标轴上的标签居中显示
    pos=np.arange(index_sorted.shape[0])+0.5

    # 画条形图
    plt.figure()
    plt.bar(pos,feature_importances[index_sorted],align=‘center‘)
    plt.xticks(pos,feature_names[index_sorted])
    plt.ylabel(‘Relative Importance‘)
    plt.title(title)

    # 把重要性结果打印出来
    print(‘{} importance list------>>>>>‘.format(title))
    for importance,name in zip(feature_importances[index_sorted],
                               feature_names[index_sorted]):
        if importance>5:
            print(‘feature:{}, importance: {:.2f}‘.format(name,importance))
decision_regressor7=DecisionTreeRegressor(max_depth=7) # 最大深度确定为7
decision_regressor7.fit(train_X,train_y) # 对决策树回归模型进行训练
plot_importances(decision_regressor7.feature_importances_,
                 ‘DT regressor‘,housing_data.feature_names)
plot_importances(ada_regressor.feature_importances_,
                 ‘AdaBoost Optimized DT regressor‘,housing_data.feature_names)

-------------------------------------输---------出--------------------------------

DT regressor importance list------>>>>>

feature:LSTAT, importance: 100.00

feature:RM, importance: 52.24

feature:DIS, importance: 15.97

feature:PTRATIO, importance: 5.00

AdaBoost Optimized DT regressor importance list------>>>>>

feature:LSTAT, importance: 100.00

feature:RM, importance: 46.72

feature:DIS, importance: 21.80

feature:TAX, importance: 7.34

feature:AGE, importance: 7.29

feature:CRIM, importance: 6.51

feature:NOX, importance: 5.32

feature:PTRATIO, importance: 5.29

--------------------------------------------完-------------------------------------

########################小**********结###############################

1,通过上面两幅图的比较,可以看出,各种特征对模型的相对重要性变化很大,两种模型都发现最重要的特征是LSTAT(这和书本《Python机器学习经典实例》中不一样。

2,但AdaBoost增强算法貌似能够提升其他小特征的相对重要性,而且两种模型中特征重要性排序也不一样。

#################################################################

注:本部分代码已经全部上传到(我的github)上,欢迎下载。

参考资料:

1, Python机器学习经典实例,Prateek Joshi著,陶俊杰,陈小莉译

原文地址:https://www.cnblogs.com/RayDean/p/9764639.html

时间: 2024-10-07 06:33:39

【火炉炼AI】机器学习006-用决策树回归器构建房价评估模型的相关文章

【火炉炼AI】机器学习007-用随机森林构建共享单车需求预测模型

[火炉炼AI]机器学习007-用随机森林构建共享单车需求预测模型 (本文所使用的Python库和版本号: Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 ) 共享单车是最近几年才发展起来的一种便民交通工具,基本上是我等屌丝上班,下班,相亲,泡妞必备神器.本项目拟使用随机森林回归器构建共享单车需求预测模型,从而查看各种不同的条件下,共享单车的需求量. 1. 准备数据集 本次使用的数据集来源于加利福尼亚大学欧文分校(UCI)大学的公

【火炉炼AI】机器学习019-项目案例:使用SVM回归器估算交通流量

[火炉炼AI]机器学习019-项目案例:使用SVM回归器估算交通流量 (本文所使用的Python库和版本号: Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 ) 我们都知道,SVM是一个很好地分类器,不仅适用于线性分类模型,而且还适用于非线性模型,但是,在另一方面,SVM不仅可以用于解决分类问题,还可以用于解决回归问题. 本项目打算使用SVM回归器来估算交通流量,所使用的方法和过程与我的上一篇文章[火炉炼AI]机器学习018-项

【火炉炼AI】机器学习017-使用GridSearch搜索最佳参数组合

[火炉炼AI]机器学习017-使用GridSearch搜索最佳参数组合 (本文所使用的Python库和版本号: Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 ) 在前面的文章([火炉炼AI]机器学习012-用随机森林构建汽车评估模型及模型的优化提升方法),我们使用了验证曲线来优化模型的超参数,但是使用验证曲线难以同时优化多个参数的取值,只能一个参数一个参数的优化,从而获取每个参数的最优值,但是有时候,一个非常优秀的模型,可能A

【火炉炼AI】机器学习018-项目案例:根据大楼进出人数预测是否举办活动

[火炉炼AI]机器学习018-项目案例:根据大楼进出人数预测是否举办活动 (本文所使用的Python库和版本号: Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 ) 我们经常看到办公大楼中人来人往,进进出出,在平时没有什么活动的时候,进出大楼的人数会非常少,而一旦举办有大型商业活动,则人山人海,熙熙攘攘,所以很明显,大楼进出的人数和大楼是否举办活动有很明显的关联,那么,是否可以构建一个模型,通过大楼进出人数来预测该大楼是否在举办

【火炉炼AI】机器学习042-NLP文本的主题建模

[火炉炼AI]机器学习042-NLP文本的主题建模 (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2, NLTK 3.3) 文本的主题建模时用NLP来识别文本文档中隐藏的某种模式的过程,可以发现该文档的隐藏主题,以便对文档进行分析.主题建模的实现过程是,识别出某文本文档中最有意义,最能表征主题的词来实现主题分类,即寻找文本文档中的关键词,通过关键词就可以识别出某文档的隐藏主题. 1. 准备数

【火炉炼AI】机器学习046-图像边缘的检测方法

[火炉炼AI]机器学习046-图像边缘的检测方法 (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 ) 图像中各种形状的检测时计算机视觉领域中非常常见的技术之一,特别是图像中直线的检测,圆的检测,图像边缘的检测等,下面我们来研究一下如何快速检测图像边缘. 边缘是不同区域的分界线,是周围(局部)像素有显著变化的像素的集合,有幅值与方向两个属性.这个不是绝对的定义,主要记住边缘是局部特征以及周围

【火炉炼AI】机器学习048-Harris检测图像角点

[火炉炼AI]机器学习048-Harris检测图像角点 (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 ) 角点检测算法大致有三类:基于灰度图像的角点检测,基于二值图像的角点检测,基于轮廓曲线的角点检测.基于灰度图像的角点检测又可分为基于梯度.基于模板和基于模板梯度组合3类方法,其中基于模板的方法主要考虑像素领域点的灰度变化,即图像亮度的变化,将与邻点亮度对比足够大的点定义为角点.常见的基

【火炉炼AI】机器学习050-提取图像的Star特征

[火炉炼AI]机器学习050-提取图像的Star特征 (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 ) 对于图像的特征点,前面我们讨论过边缘检测方法,Harris角点检测算法等,这些检测算法检测的都是图像的轮廓边缘,而不是内部细节,如果要进一步提取图像内部细节方面的特征,需要用到SIFT特征提取器和Star特征提取器.上一篇我们讲解了SIFT特征提取器,下面我们来介绍Star特征提取器.

【火炉炼AI】深度学习005-简单几行Keras代码解决二分类问题

[火炉炼AI]深度学习005-简单几行Keras代码解决二分类问题 (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2, Keras 2.1.6, Tensorflow 1.9.0) 很多文章和教材都是用MNIST数据集作为深度学习届的"Hello World"程序,但是这个数据集有一个很大的特点:它是一个典型的多分类问题(一共有10个分类),在我们刚刚开始接触深度学习时,我倒是觉得