机器学习-基于决策树的分类与预测

一、原理

1.决策树(decision tree):本质上是一种通过一系列规则对数据进行分类的分类模型,采用树行(如二叉树…)结构,使用层层推理(基于if-then-else的监督学习算法)来来实现最终的分类。其基本结构由以下元素构成:
机器学习-基于决策树的分类与预测_第1张图片

2.优缺点
主要优点:具有很好的解释性,模型可以生成可以理解的规则。可以发现特征的重要程度。模型的计算复杂度较低。
主要缺点:模型容易过拟合,需要采用减枝技术处理。不能很好利用连续型特征。预测能力有限,无法达到其他强监督模型效果。方差较高,数据分布的轻微改变很容易造成树结构完全不同。

3.决策树学习的步骤:特征选择➡决策树生成➡决策剪枝
特征选择:特征选择决定了使用哪些特征来做判断。在训练数据集中,每个样本的属性可能有很多个,不同属性的作用有大有小。因而特征选择的作用就是筛选出跟分类结果相关性较高的特征,也就是分类能力较强的特征。

决策树生成:选择好特征后,就从根节点触发,对节点计算所有特征的信息增益,选择信息增益最大的特征作为节点特征,根据该特征的不同取值建立子节点;对每个子节点使用相同的方式生成新的子节点,直到信息增益很小或者没有特征可以选择为止。

决策树剪枝:剪枝的主要目的是对抗过拟合,通过主动去掉部分分支来降低过拟合的风险。

4.决策树构建的伪代码
机器学习-基于决策树的分类与预测_第2张图片

决策树的构建过程是一个递归过程。函数存在三种返回状态:(1)当前节点包含的样本全部属于同一类别,无需继续划分;(2)当前属性集为空或者所有样本在某个属性上的取值相同,无法继续划分;(3)当前节点包含的样本集合为空,无法划分。
其中,划分选择sklearn提供了两种:信息增益和基尼(gini)指数。
信息熵(entropy)是一种衡量数据混乱程度的指标,信息熵越小,则数据的“纯度”越高。一般信息增益越大,则意味着使用某一个特征来进行划分的效果越好。信息熵相比基尼系数,对不纯度更加敏感,对不纯度的惩罚更强,但信息熵对于高维数据或者噪音很多的数据容易过拟合
信息增益=父节点的信息熵-子节点的信息熵
基尼指数∈(0,1),反映了从数据集D中随机抽取两个的类别标记不一致的概率。基尼指数的计算不涉及对数,因此比信息熵的计算相对快一些。
在实际应用中,信息熵和基尼系数的效果基本相同。

二、实战

2.1 demo实践

2.1.1源码

##  基础函数库
import numpy as np

## 导入画图库
import matplotlib.pyplot as plt
import seaborn as sns

## 导入决策树模型函数
from sklearn.tree import DecisionTreeClassifier
from sklearn import tree

##Demo演示LogisticRegression分类

## 构造数据集
x_fearures = np.array([[-1, -2], [-2, -1], [-3, -2], [1, 3], [2, 1], [3, 2]])
y_label = np.array([0, 1, 0, 1, 0, 1])

## 调用决策树模型
tree_clf = DecisionTreeClassifier()

## 用决策树模型拟合构造的数据集
tree_clf = tree_clf.fit(x_fearures, y_label)

## 可视化构造的数据样本点
plt.figure()
plt.scatter(x_fearures[:,0],x_fearures[:,1], c=y_label, s=50, cmap='viridis')
plt.title('Dataset')
plt.show()

## 本段代码实际效果为本地生成PDF可视化文档,在体验过程中可以不运行,可能无法正常展示结果;
## 代码生成的可视化结果会截图展示实际效果
#!pip install graphviz
import graphviz
feature_name =['特征1','特征2']
dot_data = tree.export_graphviz(tree_clf
                                # , feature_names=feature_name
                                ,out_file=None)#将生成的决策树导出为dot格式,画图专用
graph = graphviz.Source(dot_data)
# graph.render("pengunis")
# 'pengunis.pdf'

## 创建新样本
x_fearures_new1 = np.array([[0, -1]])
x_fearures_new2 = np.array([[2, 1]])
## 在训练集和测试集上分布利用训练好的模型进行预测
y_label_new1_predict = tree_clf.predict(x_fearures_new1)
y_label_new2_predict = tree_clf.predict(x_fearures_new2)
print('The New point 1 predict class:\n',y_label_new1_predict)
print('The New point 2 predict class:\n',y_label_new2_predict)
# The New point 1 predict class:
 # [1]
# The New point 2 predict class:
 # [0]

2.1.2 运行结果
图1
机器学习-基于决策树的分类与预测_第3张图片

图2

(图中X[i]代表特征样本里索引号为i的特征)

2.2 数据分析

2.2.1 描述
本次选择企鹅数据(palmerpenguins)进行方法的尝试训练,该数据集一共包含8个变量,其中7个特征变量,1个目标分类变量。共有150个样本,目标变量为 企鹅的类别 其都属于企鹅类的三个亚属,分别是(Adélie, Chinstrap and Gentoo)。包含的三种种企鹅的七个特征,分别是所在岛屿,嘴巴长度,嘴巴深度,脚蹼长度,身体体积,性别以及年龄。
机器学习-基于决策树的分类与预测_第4张图片

2.2.2 源码

##  基础函数库
import numpy as np
import pandas as pd

## 绘图函数库
import matplotlib.pyplot as plt
import seaborn as sns

## 我们利用Pandas自带的read_csv函数读取并转化为DataFrame格式

data = pd.read_csv('D:\Python\workplace\ML\DecisionTree\penguins_raw.csv')
## 为了方便我们仅选取四个简单的特征,有兴趣的同学可以研究下其他特征的含义以及使用方法
data = data[['Species','Culmen Length (mm)','Culmen Depth (mm)',
            'Flipper Length (mm)','Body Mass (g)']]

## 利用.info()查看数据的整体信息
data.info()
## 
## RangeIndex: 344 entries, 0 to 343
## Data columns (total 5 columns):
## Species                344 non-null object
## Culmen Length (mm)     342 non-null float64
## Culmen Depth (mm)      342 non-null float64
## Flipper Length (mm)    342 non-null float64
## Body Mass (g)          342 non-null float64
## dtypes: float64(4), object(1)
## memory usage: 13.6+ KB

## 进行简单的数据查看,我们可以利用 .head() 头部.tail()尾部
data.head()
data = data.fillna(-1)#填补缺失值
data.tail()

## 其对应的类别标签为'Adelie Penguin', 'Gentoo penguin', 'Chinstrap penguin'三种不同企鹅的类别。
data['Species'].unique()
## array(['Adelie Penguin (Pygoscelis adeliae)',
##       'Gentoo penguin (Pygoscelis papua)',
##       'Chinstrap penguin (Pygoscelis antarctica)'], dtype=object)

## 利用value_counts函数查看每个类别数量
pd.Series(data['Species']).value_counts()
## Adelie Penguin (Pygoscelis adeliae)          152
## Gentoo penguin (Pygoscelis papua)            124
## Chinstrap penguin (Pygoscelis antarctica)     68
## Name: Species, dtype: int64

## 对于特征进行一些统计描述
data.describe()

## 特征与标签组合的散点可视化
sns.pairplot(data=data, diag_kind='hist', hue= 'Species')
plt.show()
#见图1

'''为了方便我们将标签转化为数字
       'Adelie Penguin (Pygoscelis adeliae)'        ------0
       'Gentoo penguin (Pygoscelis papua)'          ------1
       'Chinstrap penguin (Pygoscelis antarctica)   ------2 '''

def trans(x):
    if x == data['Species'].unique()[0]:
        return 0
    if x == data['Species'].unique()[1]:
        return 1
    if x == data['Species'].unique()[2]:
        return 2

data['Species'] = data['Species'].apply(trans)
for col in data.columns:
    if col != 'Species':
        sns.boxplot(x='Species', y=col, saturation=0.5, palette='pastel', data=data)
        plt.title(col)
        plt.show()
#见图2

# 选取其前三个特征绘制三维散点图
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111, projection='3d')

data_class0 = data[data['Species']==0].values
data_class1 = data[data['Species']==1].values
data_class2 = data[data['Species']==2].values
# 'setosa'(0), 'versicolor'(1), 'virginica'(2)
ax.scatter(data_class0[:,0], data_class0[:,1], data_class0[:,2],label=data['Species'].unique()[0])
ax.scatter(data_class1[:,0], data_class1[:,1], data_class1[:,2],label=data['Species'].unique()[1])
ax.scatter(data_class2[:,0], data_class2[:,1], data_class2[:,2],label=data['Species'].unique()[2])
plt.legend()

plt.show()
#见图3

2.2.3 结果
图1
机器学习-基于决策树的分类与预测_第5张图片
图2(其他三个特征绘制图形类似图2)
机器学习-基于决策树的分类与预测_第6张图片

图3
机器学习-基于决策树的分类与预测_第7张图片

2.3 建模预测

2.3.1描述
利用决策树模型在二分类和三分类(多分类)上进行训练和预测。
2.3.2源码

## 为了正确评估模型性能,将数据划分为训练集和测试集,并在训练集上训练模型,在测试集上验证模型性能。
from sklearn.model_selection import train_test_split

## 选择其类别为0和1的样本 (不包括类别为2的样本)
data_target_part = data[data['Species'].isin([0,1])][['Species']]
data_features_part = data[data['Species'].isin([0,1])][['Culmen Length (mm)','Culmen Depth (mm)',
            'Flipper Length (mm)','Body Mass (g)']]

## 测试集大小为20%, 80%/20%分
x_train, x_test, y_train, y_test = train_test_split(data_features_part, data_target_part, test_size = 0.2, random_state = 2020)

## 从sklearn中导入决策树模型
from sklearn.tree import DecisionTreeClassifier
from sklearn import tree
## 定义 决策树模型
clf = DecisionTreeClassifier(criterion='entropy')
## 在训练集上训练决策树模型
clf.fit(x_train, y_train)
## DecisionTreeClassifier(class_weight=None, criterion='entropy', max_depth=None,
##            max_features=None, max_leaf_nodes=None,
##            min_impurity_decrease=0.0, min_impurity_split=None,
##            min_samples_leaf=1, min_samples_split=2,
##            min_weight_fraction_leaf=0.0, presort=False, random_state=None,
##            splitter='best')

## 可视化
## 本段代码实际效果为本地生成PDF可视化文档,在体验过程中可以不运行,可能无法正常展示结果;
## 代码生成的可视化结果会截图展示实际效果
import graphviz
dot_data = tree.export_graphviz(clf, out_file=None)
graph = graphviz.Source(dot_data)
graph.render("penguins")
## 'penguins.pdf'
#见图1

## 在训练集和测试集上分布利用训练好的模型进行预测
train_predict = clf.predict(x_train)
test_predict = clf.predict(x_test)
from sklearn import metrics
## 利用accuracy(准确度)【预测正确的样本数目占总预测样本数目的比例】评估模型效果
print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_train,train_predict))
print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_test,test_predict))
## 查看混淆矩阵 (预测值和真实值的各类情况统计矩阵)
confusion_matrix_result = metrics.confusion_matrix(test_predict,y_test)
print('The confusion matrix result:\n',confusion_matrix_result)
# 利用热力图对于结果进行可视化
plt.figure(figsize=(8, 6))
sns.heatmap(confusion_matrix_result, annot=True, cmap='Blues')
plt.xlabel('Predicted labels')
plt.ylabel('True labels')
plt.show()
#见图2
## The accuracy of the Logistic Regression is: 0.9954545454545455
## The accuracy of the Logistic Regression is: 1.0
## The confusion matrix result:
## [[31  0]
## [ 0 25]]

## 测试集大小为20%, 80%/20%分
x_train, x_test, y_train, y_test = train_test_split(data[['Culmen Length (mm)','Culmen Depth (mm)',
            'Flipper Length (mm)','Body Mass (g)']], data[['Species']], test_size = 0.2, random_state = 2020)
## 定义 决策树模型
clf = DecisionTreeClassifier()
# 在训练集上训练决策树模型
clf.fit(x_train, y_train)
## DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
##            max_features=None, max_leaf_nodes=None,
##            min_impurity_decrease=0.0, min_impurity_split=None,
##            min_samples_leaf=1, min_samples_split=2,
##            min_weight_fraction_leaf=0.0, presort=False, random_state=None,
##            splitter='best')

## 在训练集和测试集上分布利用训练好的模型进行预测
train_predict = clf.predict(x_train)
test_predict = clf.predict(x_test)
## 由于逻辑回归模型是概率预测模型(前文介绍的 p = p(y=1|x,\theta)),所有我们可以利用 predict_proba 函数预测其概率
train_predict_proba = clf.predict_proba(x_train)
test_predict_proba = clf.predict_proba(x_test)
print('The test predict Probability of each class:\n',test_predict_proba)
## 其中第一列代表预测为0类的概率,第二列代表预测为1类的概率,第三列代表预测为2类的概率。
## 利用accuracy(准确度)【预测正确的样本数目占总预测样本数目的比例】评估模型效果
print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_train,train_predict))
print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_test,test_predict))
#  The test predict Probability of each class:
#    [[0. 0. 1.]
#    [0. 1. 0.]
#    [0. 1. 0.]
#    [1. 0. 0.]
#    …………
#    [0. 1. 0.]
#    [0. 0. 1.]
#    [1. 0. 0.]
#    [1. 0. 0.]]
#  The accuracy of the Logistic Regression is: 0.996363636364

#  The accuracy of the Logistic Regression is: 0.971014492754

## 查看混淆矩阵
confusion_matrix_result = metrics.confusion_matrix(test_predict,y_test)
print('The confusion matrix result:\n',confusion_matrix_result)

# 利用热力图对于结果进行可视化
plt.figure(figsize=(8, 6))
sns.heatmap(confusion_matrix_result, annot=True, cmap='Blues')
plt.xlabel('Predicted labels')
plt.ylabel('True labels')
plt.show()
#见图3


#    The confusion matrix result:
#    [[30  1  0]
#    [ 0 23  0]
#    [ 2  0 13]]


2.3.3结果
图1(penguins.pdf)
机器学习-基于决策树的分类与预测_第8张图片

图2(二分类)
机器学习-基于决策树的分类与预测_第9张图片

图3(三分类)
机器学习-基于决策树的分类与预测_第10张图片

学习链接:天池机器学习算法:决策树

你可能感兴趣的:(MachineLearning,决策树,可视化,数据挖掘,python,机器学习)