机器学习:决策树与随机森林

决策树引入

逻辑回归是一种线性有监督离散型分类模型

决策树是一种非线性有监督离散型分类模型

随机森林也是一种非线性有监督离散型分类模型

离散化

案例分析: 离散化

数据类型

  1. 离散的数据 需指明取值数量 2^M 种分割方式
    天气 : 晴天 雨天 多云
    学历: 高中 本科 研究生

  2. 连续的数据 需离散化, 需指明离散化后的数量
    车速:
    低速 (60)中速 (80 )高速
    M+1种分割方式

决策树是通过固定的条件来对类别进行判断:
在这里插入图片描述
在这里插入图片描述

决策树的生成:

数据在不断分裂的递归过程,每一次分裂,尽可能让类别一样的数据在树的一边,当树的叶子节点的数据都是一类的时候,则停止分裂(if lese语句)
在这里插入图片描述

计算纯度的方式

在这里插入图片描述
基尼系数,熵越大,方差越大,数据集越不一样,纯度越高

基尼系数

基尼系数是指国际上通用的、用以衡量一个国家或地区居民收入差距的常用指标

  • 若低于0.2表示指数等级极低;(高度平均)
  • 0.2-0.29表示指数等级低;(比较平均)
  • 0.3-0.39表示指数等级中;(相对合理)
  • 0.4-0.59表示指数等级高;(差距较大)
  • 0.6以上表示指数等级极高。(差距悬殊)

一般发达国家的基尼指数在0.24到0.36之间,美国偏高,为0.45。中国国家统计局公布基尼系数2012年为0.474,2013年为0.473,2014年为0.469,2015年为0.462,2016年为0.465

熵和方差我们前面讲过,这里不再赘述

决策树的分割方式:非线性

在这里插入图片描述

单颗决策树的缺陷

单颗决策树的缺点:

运算量大,需要一次加载所有数据进内存。并且找寻分割条件是一个极耗资源的工作

训练样本中出现异常数据时,将会对决策树产生很大影响。抗干扰能力差

解决方法:

减少决策树所需训练样本(减少列或者减少行)

随机采样,降低异常数据的影响

逻辑回归的优点:

和逻辑回归比,逻辑回归可以给告诉我们概率(或者设置阈值),二决策树只能0, 1

随机森林

森林:由树组成

随机:生成树的数据都是从数据集中随机选取的

当数据集很大的时候,我们随机选取数据集的一部分,生成一颗树,重复上述过程,我们可以生成一堆
形态各异的树,这些树放在一起就叫森林
在这里插入图片描述
在这里插入图片描述

随机森林VS逻辑回归

在这里插入图片描述

剪枝

预剪枝: 在这棵树还没开始分裂的时候,提前设定好一些条件,在达到这些条件以后就不长了

后剪枝:先长,长完了再去掉(比如合并叶子节点)

预剪枝的方式:

(1)控制分裂的层次
(2)控制叶子节点的样本数量

剪枝保证了模型的通用性

决策树做回归

在这里插入图片描述
通过求均值的方式来让分类结果可数

代码实现

决策树

# encoding:utf-8
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
# 决策数的分类器
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt

iris = load_iris()
data = pd.DataFrame(iris.data)
data.columns = iris.feature_names
data['Species'] = iris.target
# print(data)

# 花萼长度和宽度
x = data.iloc[:, :2]
y = data.iloc[:, -1]

# 对数据集进行切分
# 相同的随机种子产生的随机数是一样
# 不同的随机种子产生的随机数不一样
x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.75, random_state=42)

# 创建一个决策数的模型
tree_clf = DecisionTreeClassifier(max_depth=4, criterion='entropy')
tree_clf.fit(x_train, y_train)
y_test_hat = tree_clf.predict(x_test)
print("acc score:", accuracy_score(y_test, y_test_hat))

depth = np.arange(1, 15)
err_list = []

"""
splitter: 分裂的方式
             best   找最好的维度进行分裂
             random 随机找维度进行分裂
feature: splitter方法中,找best分割维度的时候,需要在多少个维度中找那个最好的 
            none 就是不限制找的数量
            int 就是找n个数进行考量
            float就是找0.5(50%)去试
            sqrt就是找所有特征数开根号个特征
max_depth: 树分裂的最大深度 none
min_sample_split:分裂前我需要保证这个叶子有几个样本 
                      int就是要保证叶子里的样本数大于n,
                      float 就是要保证叶子里的样本数大于某个百分比
min_sample_leaf: 分裂后需要保证每个分裂的叶子有几个样本
min_weight_fraction_leaf:每个叶子节点里的样本数,必须是所有样本的10%
max_leaf_nodes:最多的叶子数
min_impurity_split:每个叶子节点里的不纯度,这个参数是为了保证树不会过早的停止生长;达不到指标就会继续往下分裂 
"""

for d in depth:
    clf = DecisionTreeClassifier(criterion='entropy', max_depth=d)
    clf.fit(x_train, y_train)
    y_test_hat = clf.predict(x_test)
    result = (y_test_hat == y_test)
    err = 1 - np.mean(result)
    err_list.append(err)
    print(d, '错误率: %.2f%%' % (100 * err))

plt.figure(facecolor='w')
plt.plot(depth, err_list, 'ro-', lw=2)
plt.xlabel('Decision Tree Depth', fontsize=15)
plt.ylabel('Error Rate', fontsize=15)
plt.title('Decision Tree Depth & Over Fit', fontsize=18)
plt.grid(True)
plt.show()

在这里插入图片描述
在这里插入图片描述

随机森林

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from sklearn.datasets import load_iris

iris = load_iris()
X = iris.data[:, :2]  # 花萼的长度和宽度(因为选花瓣的长宽的话,分类效果太好了)
y = iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=43)

# n_estimators指的是用多少颗树, max_leaf_1des指树的复杂程度, n_jobs指用多少个线程
rnd_clf = RandomForestClassifier(n_estimators=30, max_leaf_nodes=16, n_jobs=1)
rnd_clf.fit(X_train, y_train)

# bagging:并行思想,bagging的决策树和随机森林其实是等价的
# max_samples 训练时用所有的样本  splitter=random 指的是虽然每课小树取使用所有样本,但是我只使用随机出来的一部分维度来训练每棵小树
bag_clf = BaggingClassifier(
    DecisionTreeClassifier(splitter="random", max_leaf_nodes=16),
    n_estimators=30, max_samples=1.0, bootstrap=True, n_jobs=1
)
bag_clf.fit(X_train, y_train)

y_pred_rf = rnd_clf.predict(X_test)
y_pred_bag = bag_clf.predict(X_test)
print(accuracy_score(y_test, y_pred_rf))
print(accuracy_score(y_test, y_pred_bag))

# Feature Importance 用随机森林选择出来重要的特征,也就是分裂效果好的特征,也就是和y相关性大的特征
# 一般来说,相关性越大的特征,应该出现在树的上层
iris = load_iris()
# -1 表示有多少线程用多少线程
rnd_clf = RandomForestClassifier(n_estimators=500, n_jobs=-1)
rnd_clf.fit(iris["data"], iris['target'])
for name, score in zip(iris['feature_names'], rnd_clf.feature_importances_):
    print(name, score)

'''
Xgbost: 并行
GDBT:串行
公司中,特征提取会用到树的算法

'''

在这里插入图片描述

总结

决策树和随机森林

1.决策树
(1)决策树是一个有监督的机器学习算法,做分类用的,而且是非线性的。
(2)决策树的建模过程,不是创造一个方程了,而是构建一棵树。这棵树不一定只是二叉树
(3)损失函数:

  1. 基尼系数
  2. 方差

这三种,都是值越大,纯度越高

纯度:当我们应用一个特征(比如说头发长度)对数据(男女)进行分类的时候,如果这个特征能把数据都分到一边去(全部男,或者全部女),我们就说这个特征可分类的纯度高

有很多参数都在围绕纯度进行调式:splitter (best, random)…

(4) 决策树的参数:都是为了构建一个优秀的决策树,提供的支持
max_leaf_node, max_depth…
(5)剪枝:就是决策数的正则化

为了减少过拟合的现象

预剪枝:在树没有生成前,通过对将要生成树的判断,来进行限制max_depth

后剪枝:在树生成之后,通过对某些叶子节点的删除,来进行限制max_leaf_perc

2.随机森林
随机森林,就是由很多决策树构成的
(1)并行思想:因为随机森林中的树都是相互独立的,所以这些树可以在不同的机器上,或者CPU,GPU上运行,这样能极大缩短建模的时间

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章