基于sklearn的决策树分类器理论基础代码实现

理论基础

决策树

决策树是一种树形结构的机器学习算法,所有的样本起始于根节点,每个具有子节点的父节点都有一个判断,根据判断结果将样本向子节点分流,测试样本从根节点开始向下流动,通过判断最终到达某个没有子节点的叶子节点,这个节点就是该样本所属的类别。 例如,判断一个动物是鸭子,狗还是兔子,可以具有以下的决策树:

  • 判断是否有四条腿
    • 没有,是鸭子
    • 有,判断眼睛颜色
      • 红色,是兔子
      • 非红色,是狗

决策树训练算法

训练决策树时,可以描述如下

  1. 从父节点找到最优划分属性
  2. 根据属性划分出子节点
  3. 若子节点为空/属性相同(无需划分)或样本相等(无法划分),返回,否则返回第一步继续递归划分

找到最优划分属性时,计算按每个属性划分的信息熵,取信息熵最大的属性为最优划分属性

代码实现

载入数据——泰坦尼克号数据导入

import pandas as pd
titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")
print(titan.head())
   row.names pclass  survived  \
0          1    1st         1   
1          2    1st         0   
2          3    1st         0   
3          4    1st         0   
4          5    1st         1   

                                              name      age     embarked  \
0                     Allen, Miss Elisabeth Walton  29.0000  Southampton   
1                      Allison, Miss Helen Loraine   2.0000  Southampton   
2              Allison, Mr Hudson Joshua Creighton  30.0000  Southampton   
3  Allison, Mrs Hudson J.C. (Bessie Waldo Daniels)  25.0000  Southampton   
4                    Allison, Master Hudson Trevor   0.9167  Southampton   

                         home.dest room      ticket   boat     sex  
0                     St Louis, MO  B-5  24160 L221      2  female  
1  Montreal, PQ / Chesterville, ON  C26         NaN    NaN  female  
2  Montreal, PQ / Chesterville, ON  C26         NaN  (135)    male  
3  Montreal, PQ / Chesterville, ON  C26         NaN    NaN  female  
4  Montreal, PQ / Chesterville, ON  C22         NaN     11    male  
print(titan.info())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1313 entries, 0 to 1312
Data columns (total 11 columns):
row.names    1313 non-null int64
pclass       1313 non-null object
survived     1313 non-null int64
name         1313 non-null object
age          633 non-null float64
embarked     821 non-null object
home.dest    754 non-null object
room         77 non-null object
ticket       69 non-null object
boat         347 non-null object
sex          1313 non-null object
dtypes: float64(1), int64(2), object(8)
memory usage: 112.9+ KB
None

数据预处理

选取特征

x = titan[["pclass","age","sex"]]
y = titan["survived"]
print(x.info())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1313 entries, 0 to 1312
Data columns (total 3 columns):
pclass    1313 non-null object
age       633 non-null float64
sex       1313 non-null object
dtypes: float64(1), object(2)
memory usage: 30.9+ KB
None

年龄补全——使用平均值

x['age'].fillna(x['age'].mean(),inplace=True)
print(x.info())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1313 entries, 0 to 1312
Data columns (total 3 columns):
pclass    1313 non-null object
age       1313 non-null float64
sex       1313 non-null object
dtypes: float64(1), object(2)
memory usage: 30.9+ KB
None


c:\users\qiank\appdata\local\programs\python\python35\lib\site-packages\pandas\core\generic.py:3660: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self._update_inplace(new_data)

数据分割

from sklearn.cross_validation import train_test_split
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.25,random_state=1)
print(x_train.shape)
print(x_test.shape)
(984, 3)
(329, 3)

特征转换

from sklearn.feature_extraction import DictVectorizer
vec = DictVectorizer(sparse=False)
x_train = vec.fit_transform(x_train.to_dict(orient='record'))
x_test = vec.transform(x_test.to_dict(orient='record'))
print(vec.feature_names_,"\n",x_train[:5])
['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', 'sex=female', 'sex=male'] 
 [[ 31.19418104   0.           0.           1.           0.           1.        ]
 [ 31.19418104   0.           0.           1.           0.           1.        ]
 [ 35.           0.           1.           0.           1.           0.        ]
 [ 31.           0.           1.           0.           0.           1.        ]
 [ 26.           0.           0.           1.           0.           1.        ]]

调用决策树分类器

from sklearn.tree import DecisionTreeClassifier
dtc = DecisionTreeClassifier()
dtc.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')

模型评估

自带评估

dtc.score(x_test,y_test)
0.81155015197568392

评估器

from sklearn.metrics import classification_report
y_pre = dtc.predict(x_test)
print(classification_report(y_pre,y_test,target_names=["died","survived"]))
             precision    recall  f1-score   support

       died       0.91      0.80      0.85       226
   survived       0.66      0.83      0.74       103

avg / total       0.83      0.81      0.82       329

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏云霄雨霁

加权有向图----无环情况下的最短路径算法

1890
来自专栏应兆康的专栏

Accuracy

$A_{cc}=\frac{1}{n}\sum{I(\hat{y}_i=y_i)}$

921
来自专栏林德熙的博客

C# 判断两条直线距离

d= \frac{ \left| C_1-C_2 \right|}{\sqrt{A^2+B^2}}

1292
来自专栏人工智能LeadAI

机器学习实战 | 第四章:模型验证和选择

模型选择和评估主要是在sklearn.model_selection这个模块里面.这里只会列出概述和常见函数的用法,更加详细的可以到sklearn.model_...

3825
来自专栏张俊红

Sklearn参数详解—SVM

2.6K4
来自专栏mathor

matlab—进阶绘图

这里我们要讲的是画一些与对数(log)有关的图像,这里的log,既可以是图像是log,又可以是坐标轴是log,我们接下来用一个例子来说明

1793
来自专栏锦小年的博客

复杂网络(2)--图论的基本理论-最小生成树问题

连通且不含圈的无向图称为树(tree)。树中度为1的节点称为树叶,度大于1的节点称为分支点。 若图G=(V,E)的生成子图是一棵树,则称该树为图G的生成树(...

3626
来自专栏尾尾部落

小白的机器学习实战——向量,矩阵和数组 小白的机器学习实战——向量,矩阵和数组

1494
来自专栏null的专栏

机器学习算法实现解析——libFM之libFM的训练过程概述

本节主要介绍的是libFM源码分析的第四部分——libFM的训练。 FM模型的训练是FM模型的核心的部分。 4.1、libFM中训练过程的实现 在FM模型的训练...

49511
来自专栏人工智能

人工智能AI(5):线性代数之矩阵、线性空间

在前面的篇幅中,我们简单的介绍过矩阵的定义,按照原计划本来,今天准备写特征分解以及奇异值分解,但是发现这其中涉及到比较多的矩阵相关的知识,所以在讨论这些问题之前...

2825

扫码关注云+社区

领取腾讯云代金券