机器学习03-(决策树:基本原理及集合算法、波士顿房屋价格数据分析与房价预测)

机器学习-03

  • 机器学习-03
      • 决策树
        • 基本算法原理
        • 集合算法
          • AdaBoost模型(正向激励)
      • 代码总结
        • 波士顿房屋价格数据分析与房价预测
        • 训练回归模型,预测房屋价格
        • 决策树回归
        • 正向激励

机器学习-03

决策树

基本算法原理

核心思想:相似的输入必会产生相似的输出。例如预测某人薪资:

年龄:1-青年,2-中年,3-老年
学历:1-本科,2-硕士,3-博士
经历:1-出道,2-一般,3-老手,4-骨灰
性别:1-男性,2-女性

年龄 学历 经历 性别 ==> 薪资
1 1 1 1 ==> 6000(低)
2 1 3 1 ==> 10000(中)
3 3 4 1 ==> 50000(高)
==>
1 3 2 2 ==> ?

为了提高搜索效率,使用树形数据结构处理样本数据:
年 龄 = 1 { 学 历 1 学 历 2 学 历 3 年 龄 = 2 { 学 历 1 学 历 2 学 历 3 年 龄 = 3 { 学 历 1 学 历 2 学 历 3 年龄=1\left\{ \begin{aligned} 学历1 \\ 学历2 \\ 学历3 \\ \end{aligned} \right. \quad\quad 年龄=2\left\{ \begin{aligned} 学历1 \\ 学历2 \\ 学历3 \\ \end{aligned} \right. \quad\quad 年龄=3\left\{ \begin{aligned} 学历1 \\ 学历2 \\ 学历3 \\ \end{aligned} \right. =1123=2123=3123
首先从训练样本矩阵中选择一个特征进行子表划分,使每个子表中该特征的值全部相同,然后再在每个子表中选择下一个特征按照同样的规则继续划分更小的子表,不断重复直到所有的特征全部使用完为止,此时便得到叶级子表,其中所有样本的特征值全部相同。对于待预测样本,根据其每一个特征的值,选择对应的子表,逐一匹配,直到找到与之完全匹配的叶级子表,用该子表中样本的输出,通过平均(回归)或者投票(分类)为待预测样本提供输出。

首先选择哪一个特征进行子表划分决定了决策树的性能。这么多特征,使用哪个特征先进行子表划分?

sklearn提供的决策树底层为cart树(Classification and Regression Tree),cart回归树在解决回归问题时的步骤如下:

  1. 原始数据集S,此时树的深度depth=0;
  2. 针对集合S,遍历每一个特征的每一个value,用该value将原数据集S分裂成2个集合:左集合left(<=value的样本)、右集合right(>value的样本),分别计算这2个集合的mse,找到使(left_mse+right_mse)最小的那个value,记录下此时的特征名称和value,这个就是最佳分割特征以及最佳分割值;
  3. 找到最佳分割特征以及最佳分割value之后,用该value将集合S分裂成2个集合,depth+=1;
  4. 针对集合left、right分别重复步骤2,3,直到达到终止条件。
终止条件有如下几种:
1、特征已经用完了:没有可供使用的特征再进行分裂了,则树停止分裂;
3、子节点中没有样本了:此时该结点已经没有样本可供划分,该结点停止分裂;
1、树达到了人为预先设定的最大深度:depth >= max_depth,树停止分裂。
2、节点的样本数量达到了人为设定的阈值:样本数量 < min_samples_split ,则树停止分裂;

决策树回归器模型相关API:

import sklearn.tree as st

# 创建决策树回归器模型  决策树的最大深度为4
model = st.DecisionTreeRegressor(max_depth=4)
# 训练模型  
# train_x: 二维数组样本数据
# train_y: 训练集中对应每行样本的结果
model.fit(train_x, train_y)
# 测试模型
pred_test_y = model.predict(test_x)

案例:预测波士顿地区房屋价格。

  1. 读取数据,打断原始数据集。 划分训练集和测试集。
import sklearn.datasets as sd
import sklearn.utils as su
# 加载波士顿地区房价数据集
boston = sd.load_boston()
print(boston.feature_names)
# |CRIM|ZN|INDUS|CHAS|NOX|RM|AGE|DIS|RAD|TAX|PTRATIO|B|LSTAT|
# 犯罪率|住宅用地比例|商业用地比例|是否靠河|空气质量|房间数|年限|距中心区距离|路网密度|房产税|师生比|黑人比例|低地位人口比例|
# 打乱原始数据集的输入和输出
x, y = su.shuffle(boston.data, boston.target, random_state=7)
# 划分训练集和测试集
train_size = int(len(x) * 0.8)
train_x, test_x, train_y, test_y = \
    x[:train_size], x[train_size:], \
    y[:train_size], y[train_size:]
  1. 创建决策树回归器模型,使用训练集训练模型。使用测试集测试模型。
import sklearn.tree as st
import sklearn.metrics as sm

# 创建决策树回归模型
model = st.DecisionTreeRegressor(max_depth=4)
# 训练模型
model.fit(train_x, train_y)
# 测试模型
pred_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pred_test_y))

集合算法

根据多个不同模型给出的预测结果,利用平均(回归)或者投票(分类)的方法,得出最终预测结果。

基于决策树的集合算法,就是按照某种规则,构建多棵彼此不同的决策树模型,分别给出针对未知样本的预测结果,最后通过平均或投票得到相对综合的结论。常用的集合模型包括Boosting类模型(AdaBoost、GBDT)与Bagging(自助聚合、随机森林)类模型。

AdaBoost模型(正向激励)

首先为样本矩阵中的样本随机分配初始权重,由此构建一棵带有权重的决策树,在由该决策树提供预测输出时,通过加权平均或者加权投票的方式产生预测值。将训练样本代入模型,预测其输出,对那些预测值与实际值不同的样本,提高其权重,由此形成第二棵决策树。重复以上过程,构建出不同权重的若干棵决策树。

正向激励相关API:

import sklearn.tree as st
import sklearn.ensemble as se
# model: 决策树模型(一颗)
model = st.DecisionTreeRegressor(max_depth=4)
# 自适应增强决策树回归模型	
# n_estimators:构建400棵不同权重的决策树,训练模型
model = se.AdaBoostRegressor(model, n_estimators=400, random_state=7)
# 训练模型
model.fit(train_x, train_y)
# 测试模型
pred_test_y = model.predict(test_x)

案例:基于正向激励训练预测波士顿地区房屋价格的模型。

# 创建基于决策树的正向激励回归器模型
model = se.AdaBoostRegressor(
	st.DecisionTreeRegressor(max_depth=4), n_estimators=400, random_state=7)
# 训练模型
model.fit(train_x, train_y)
# 测试模型
pred_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pred_test_y))

代码总结

波士顿房屋价格数据分析与房价预测

import numpy as np
import matplotlib.pyplot as plt
import sklearn.datasets as sd
import sklearn.utils as su
import pandas as pd
# 加载数据集
boston = sd.load_boston()
# print(boston.DESCR)
x, y, header = boston.data, boston.target, boston.feature_names
# 针对当前数据集,做简单的数据分析
data = pd.DataFrame(x, columns=header)
data['y'] = y
data.describe()
CRIM ZN INDUS CHAS NOX RM AGE DIS RAD TAX PTRATIO B LSTAT y
count 506.000000 506.000000 506.000000 506.000000 506.000000 506.000000 506.000000 506.000000 506.000000 506.000000 506.000000 506.000000 506.000000 506.000000
mean 3.593761 11.363636 11.136779 0.069170 0.554695 6.284634 68.574901 3.795043 9.549407 408.237154 18.455534 356.674032 12.653063 22.532806
std 8.596783 23.322453 6.860353 0.253994 0.115878 0.702617 28.148861 2.105710 8.707259 168.537116 2.164946 91.294864 7.141062 9.197104
min 0.006320 0.000000 0.460000 0.000000 0.385000 3.561000 2.900000 1.129600 1.000000 187.000000 12.600000 0.320000 1.730000 5.000000
25% 0.082045 0.000000 5.190000 0.000000 0.449000 5.885500 45.025000 2.100175 4.000000 279.000000 17.400000 375.377500 6.950000 17.025000
50% 0.256510 0.000000 9.690000 0.000000 0.538000 6.208500 77.500000 3.207450 5.000000 330.000000 19.050000 391.440000 11.360000 21.200000
75% 3.647423 12.500000 18.100000 0.000000 0.624000 6.623500 94.075000 5.188425 24.000000 666.000000 20.200000 396.225000 16.955000 25.000000
max 88.976200 100.000000 27.740000 1.000000 0.871000 8.780000 100.000000 12.126500 24.000000 711.000000 22.000000 396.900000 37.970000 50.000000
data.pivot_table(index='CHAS', values='y')
y
CHAS
0.0 22.093843
1.0 28.440000
data['DIS'].plot.box()

机器学习03-(决策树:基本原理及集合算法、波士顿房屋价格数据分析与房价预测)_第1张图片

# 判断每个字段与房价之间的关系
data.plot.scatter(x='RM', y='y')

机器学习03-(决策树:基本原理及集合算法、波士顿房屋价格数据分析与房价预测)_第2张图片

训练回归模型,预测房屋价格

  1. 整理数据集(输入集、输出集)
  2. 打乱数据集,拆分测试集、训练集。
  3. 选择模型,使用训练集训练模型,用测试集测试。
# 整理数据集(输入集、输出集)
x, y = data.iloc[:, :-1], data['y']
# 打乱数据集。  su:  sklearn.utils
# random_state:随机种子。 若两次随机操作使用的随机种子相同,则随机结果也相同。
x, y = su.shuffle(x, y, random_state=7)
# 拆分测试集、训练集。
train_size = int(len(x) * 0.9)
train_x, test_x, train_y, test_y = \
    x[:train_size], x[train_size:], y[:train_size], y[train_size:]
train_x.shape, test_x.shape, train_y.shape, test_y.shape
((455, 13), (51, 13), (455,), (51,))
# 选择模型,使用训练集训练模型,用测试集测试。
import sklearn.linear_model as lm
import sklearn.metrics as sm

model = lm.LinearRegression()
model.fit(train_x, train_y)  # 针对训练集数据进行训练
pred_test_y = model.predict(test_x)  # 针对测试集数据进行测试
print(sm.r2_score(test_y, pred_test_y))
print(sm.mean_absolute_error(test_y, pred_test_y))
0.8188356183218533
2.405641089772746
# 选择岭回归模型,使用训练集训练模型,用测试集测试。
model = lm.Ridge(0)
model.fit(train_x, train_y)  # 针对训练集数据进行训练
pred_test_y = model.predict(test_x)  # 针对测试集数据进行测试
print(sm.r2_score(test_y, pred_test_y))
print(sm.mean_absolute_error(test_y, pred_test_y))
0.8188356183218408
2.405641089772664
# 选择多项式回归模型,使用训练集训练模型,用测试集测试。
import sklearn.pipeline as pl
import sklearn.preprocessing as sp

model = pl.make_pipeline(sp.PolynomialFeatures(2), lm.Ridge(50))
model.fit(train_x, train_y)  # 针对训练集数据进行训练
pred_test_y = model.predict(test_x)  # 针对测试集数据进行测试
print(sm.r2_score(test_y, pred_test_y))
print(sm.mean_absolute_error(test_y, pred_test_y))
0.8935803967838563
2.0136422973642047

决策树回归

import sklearn.tree as st
# 决策树回归模型,使用训练集训练模型,用测试集测试。
model = st.DecisionTreeRegressor(max_depth=4)
model.fit(train_x, train_y)  # 针对训练集数据进行训练
pred_test_y = model.predict(test_x)  # 针对测试集数据进行测试
print(sm.r2_score(test_y, pred_test_y))
print(sm.mean_absolute_error(test_y, pred_test_y))
0.678829897847864
2.9230600667206295
import graphviz
dot_data = st.export_graphviz(model,out_file=None,feature_names= header)
graph = graphviz.Source(dot_data)
graph

机器学习03-(决策树:基本原理及集合算法、波士顿房屋价格数据分析与房价预测)_第3张图片

正向激励

import sklearn.ensemble as se

# AdaBoost回归模型,使用训练集训练模型,用测试集测试。
# 调整参数
params1 = [6, 7]
params2 = [50, 100, 150, 200]

for p1 in params1:
    for p2 in params2:
        model = st.DecisionTreeRegressor(max_depth=p1)
        model = se.AdaBoostRegressor(model, n_estimators=p2, random_state=7)
        model.fit(train_x, train_y)  # 针对训练集数据进行训练
        pred_test_y = model.predict(test_x)  # 针对测试集数据进行测试
        print('max_depth:', p1, '  n_estimators:', p2)
        print(sm.r2_score(test_y, pred_test_y))
        print(sm.mean_absolute_error(test_y, pred_test_y))
max_depth: 6   n_estimators: 50
0.8637049113548018
2.1825021616462665
max_depth: 6   n_estimators: 100
0.8814458900728809
2.060418077972981
max_depth: 6   n_estimators: 150
0.8786572551090628
2.067117240711519
max_depth: 6   n_estimators: 200
0.8793366363872159
2.048915502561963
max_depth: 7   n_estimators: 50
0.8621580468395789
2.0957038936825683
max_depth: 7   n_estimators: 100
0.8705920085320278
2.0740357212747056
max_depth: 7   n_estimators: 150
0.8710945918567736
2.049387496883028
max_depth: 7   n_estimators: 200
0.8677487622900691
2.0715533946795985

你可能感兴趣的:(机器学习)