机器学习之决策树

一、决策树的原理

《决策树》
     1、既可以用于回归,又可以用于分类;
     2、相似的输入都会有相似的输出;

           (决策树与随机森林)深入学习请移步:https://www.cnblogs.com/fionacai/p/5894142.html

   回归 -- 平均问题
   分类 -- 投票问题

《优化》:  (信息熵  -- 混乱度)
     1)结合业务优先选择有限的主要特征,划分子表,减低决策树的高度;
     2)根据香农定理计算根据每一个特征划分子表前后的信息熵差,选择熵减少量最大的特征,优先参与子表划分;
     3)集合算法:根据不同方法,【构建多个决策树】,利用它们的结果,按照取均(回归)或投票(分类)的方法,产生最终的预测结果。

《集合算法》
     A:自主聚合(按类别分组)
             采用有放回(机会均等)的抽样规则,从m个样本中随机抽取n个样本,构建一棵决策树,重复以上过程b次,得到b棵决策树。利用每棵决策树的预测结果,根据平均(回归)或者投票(分类)得到最终预测结果。
     B:随机森林(行和列都是随机的)(可以同时构建多个决策树)
              在自助聚合算法的基础上更进一步,对特征也应用自助聚合,即每次训练时,不是用所有的特征构建树结构,随机选择部分特征参与构建,以此避免特殊特征对预测结果的影响。
     C:正向激励(不同的权重值)(树的构建只能一棵一棵来,所以速度较慢)
            初始化时,针对m个样本分配初始权重,然后根据这个带有权重的模型预测训练样本,针对那些预测错误的样本提高其权重,再构建一棵决策树模型,重复以上过程,得到多个决策树;利用每棵决策树的预测结果,根据平均(回归)或者投票(分类)得到最终预测结果。

二、决策树的使用

sklearn.tree.DecisionTreeRegressor()  
--> 1、得到决策树回归器

sklearn.ensemble.AdaBoostRegressor(元回归器,
    n_estimators=评估器数, radom_state=随机种子源)  
--> 2、得到正向激励回归器

sklearn.ensemble.RandomForestRegressor(
    max_depth=最大树高, n_estimators=评估器数,
    min_samples_split=划分子表的最小样本数)  
--> 3、得到随机森林回归器

决策树模型.feature_importances_
--> 4、特征重要性
import numpy as np
import sklearn.datasets as sd
import sklearn.utils as su
import sklearn.tree as st
import sklearn.ensemble as se
import matplotlib.pyplot as mp

housing = sd.load_boston()
feature_names = housing.feature_names
x, y = su.shuffle(housing.data, housing.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
model = st.DecisionTreeRegressor(max_depth=4)
model.fit(train_x, train_y)
fi_dt = model.feature_importances_

# 模型2
model = se.AdaBoostRegressor(
    st.DecisionTreeRegressor(max_depth=4),
    n_estimators=400, random_state=7)
model.fit(train_x, train_y)
fi_ab = model.feature_importances_

# 绘图
# 1
mp.figure('Feature Importance', facecolor='lightgray')

mp.subplot(211)
mp.title('Decision Tree', fontsize=16)
mp.ylabel('Importance', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(axis='y', linestyle=":")
# 排序索引
sorted_indices = fi_dt.argsort()[::-1]  # 反向
pos = np.arange(sorted_indices.size)
mp.bar(pos, fi_dt[sorted_indices],
       facecolor='deepskyblue',
       edgecolor='steelblue')
mp.xticks(pos, feature_names[sorted_indices],
          rotation=30)  # 旋转角度
# 2
mp.subplot(212)
mp.title('AdaBoost Decision Tree', fontsize=16)
mp.xlabel('Feature', fontsize=12)
mp.ylabel('Importance', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(axis='y', linestyle=":")
sorted_indices = fi_ab.argsort()[::-1]  # 反向
pos = np.arange(sorted_indices.size)
mp.bar(pos, fi_ab[sorted_indices],
       facecolor='lightcoral',
       edgecolor='indianred')
mp.xticks(pos, feature_names[sorted_indices],
          rotation=30)  # 旋转角度

mp.tight_layout()
mp.show()
import sklearn.datasets as sd
import sklearn.utils as su
import sklearn.tree as st
import sklearn.ensemble as se
import sklearn.metrics as sm

housing = sd.load_boston()

x, y = su.shuffle(housing.data, housing.target,
                  random_state=7)     # 将数据重新排列,打乱,自由度为7

train_size = int(len(x) * 0.8)        # 取出样本数据的80%作为训练集
train_x, test_x, train_y, test_y = \
    x[:train_size], x[train_size:], \
    y[:train_size], y[train_size:]

# 模型1
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))  # 检验模型的精度

# 模型2
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))
for test, pred_test in zip(test_y, pred_test_y):
    print(test, '->', pred_test)
import csv
import numpy as np
import sklearn.utils as su
import sklearn.ensemble as se
import sklearn.metrics as sm
import matplotlib.pyplot as mp

# 数据集1
with open('../ML/data/bike_day.csv', 'r') as f:
    reader = csv.reader(f)   # 变为一个数据迭代器
    x, y = [], []
    for row in reader:
        x.append(row[2:13])   # 输入数据
        y.append(row[-1])     # 输出数据
fn_dy = np.array(x[0])   # 首行,标签数据
x = np.array(x[1:], dtype=float)  # 真正的输入数据
y = np.array(y[1:], dtype=float)  # 真正的输出数据
x, y = su.shuffle(x, y, random_state=7)  # 打乱数据
train_size = int(len(x) * 0.9)  # 取出输入数据的90%作为训练集数据
train_x, test_x, train_y, test_y = \
    x[:train_size], x[train_size:], \
    y[:train_size], y[train_size:]

# 创建随机森林模型
model = se.RandomForestRegressor(
    max_depth=10, n_estimators=1000,
    min_samples_split=2)
model.fit(train_x, train_y)  # 训练模型
fi_dy = model.feature_importances_
pred_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pred_test_y))
# ----------------------------------
# 数据集2
with open('../ML/data/bike_hour.csv', 'r') as f:
    reader = csv.reader(f)
    x, y = [], []
    for row in reader:
        x.append(row[2:13])
        y.append(row[-1])
fn_hr = np.array(x[0])
x = np.array(x[1:], dtype=float)
y = np.array(y[1:], dtype=float)
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:]
model = se.RandomForestRegressor(
    max_depth=10, n_estimators=1000,
    min_samples_split=2)
model.fit(train_x, train_y)
fi_hr = model.feature_importances_
pred_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pred_test_y))

# 绘图
# 1
mp.figure('Feature Importance', facecolor='lightgray')

mp.subplot(211)
mp.title('Bike Of Day', fontsize=16)
mp.ylabel('Importance', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(axis='y', linestyle=":")
# 排序索引
sorted_indices = fi_dy.argsort()[::-1]  # 反向
pos = np.arange(sorted_indices.size)
mp.bar(pos, fi_dy[sorted_indices],
       facecolor='deepskyblue',
       edgecolor='steelblue')
mp.xticks(pos, fn_dy[sorted_indices],
          rotation=30)  # 旋转角度
# 2
mp.subplot(212)
mp.title('AdaBoost Decision Tree', fontsize=16)
mp.xlabel('Feature', fontsize=12)
mp.ylabel('Importance', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(axis='y', linestyle=":")
sorted_indices = fi_hr.argsort()[::-1]  # 反向
pos = np.arange(sorted_indices.size)
mp.bar(pos, fi_hr[sorted_indices],
       facecolor='lightcoral',
       edgecolor='indianred')
mp.xticks(pos, fn_hr[sorted_indices],
          rotation=30)  # 旋转角度

mp.tight_layout()
mp.show()

 

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