【机器学习】决策树原理、调参、可视化 + 银行信用卡欺诈检测案例(含数据集)

目录

决策分类树

2.1 ID3算法(信息增益)

2.2 C4.5 算法(信息增益率)

2.3 CART算法(Gini系数)

 CART构造决策树实例

决策树的剪枝

sklearn实现决策树

决策树的调参 

银行借贷欺诈检测案例

 训练模型

 调优及可视化

决策分类树

2.1 ID3算法(信息增益)

ID3是决策树学习算法中最具有影响和最为典型的算法,它的基本思想是,利用信息熵的原理,选择信息增益最大的属性作为分类属性。

ID3算法在分类时选择信息熵下降最快的类别作为分类依据

 entropy(P_{i}) =- \sum_{i = 1}^{n}P_{i}log_{2}P_{i}

 

2.2 C4.5 算法(信息增益率)

C4.5算法是ID3算法的拓展,它继承了ID3算法的优点并对ID3算法进行了改进和补充。

C4.5算法采用信息增益率作为选择分支属性的标准,克服了ID3算法中信息增益选择属性时偏向选择取值多的属性的不足

  • 能够处理连续型的属性,将连续性属性离散化,将连续性属性的值分为不同区间,依据是比较各个分裂点Gian值的大小
  • 简单的忽略缺失数据,即在计算增益时,仅考虑具有属性值的记录

 

2.3 CART算法(Gini系数)

基尼指数代表了模型的不纯度,基尼系数越小,不纯度越低,特征越好。这和信息增益(率)正好相反。

基尼指数反映了从数据集中随机抽取两个样本,其类别标记不一致的概率。因此基尼指数越小,则数据集纯度越高。基尼指数偏向于特征值较多的特征,类似信息增益。基尼指数可以用来度量任何不均匀分布,是介于 0~1 之间的数,0 是完全相等,1 是完全不相等。


Gini = 1-\sum_{i = 1}^{n}[P_{(i)}]^{2} = \sum_{i = 1}^{n}P_{i}(1-P_{i})

 CART算法处理分类问题时,以叶子节点上样本投票预测类别,处理回归问题时,以叶子节点的样本均值作为预测值

 CART构造决策树实例

  •  二元属性:有房(是/否)
  • 多元属性:婚姻(单身/已婚/离异)
  • 序数属性:年收入
ID有房者婚姻年收入拖欠贷款者
1单身125k
2已婚100k
3单身70k
4已婚120k
5离异95k
6已婚60k
7离异220k
8单身85k
9已婚75k
10单身90k

构造一颗决策树:

首先选择一个根节点 (Gini) 

 同理:婚姻Gini加权 = 3/10,年收入Gini加权= 5/14

 婚姻Gini加权最小,所以选择婚姻作为根节点

决策树的剪枝

剪枝参数(提高决策树的泛化性)
决策树不加限制,会生长到衡量不纯度的指标最优,或者没有更多特征可用,这样的决策树会过拟合。当决策树对训练数据有过于优秀的解释性,它必然包含了训练样本中的噪声,并且对未知数据的拟合程度不足

  • 限制树的最大深度max_depth
  • 限制一个节点在分枝后的每个子节点都必须包含至少min_sample_leaf个训练样本,否则不分支
  • 限定一个节点必须要包含至少min_samples_split个训练样本,否则分枝就不会发生。
  • 限制分枝时考虑的特征个数max_features,超过限制个数的特征都会被舍弃。用来限制高维度数据的过拟合的剪枝参数

  • 限制信息增益的大小min_impurity_decrease,信息增益小于设定数值的分枝不会发生。

  1. 预剪枝 在构建决策树的过程中,提前停止
  2. 后剪枝 决策树构建好后开始裁剪

C_{a} = C(T)+\alpha \left | T_{leaf} \right |   叶子结点越多,损失越大

sklearn实现决策树

import pandas as pd
import graphviz
from sklearn import tree
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
wine = load_wine()


pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target)],axis = 1)
X_train,X_test,y_train,y_test = train_test_split(wine.data,wine.target,test_size = 0.3)
clf = DecisionTreeClassifier(criterion = 'entropy',random_state = 30,splitter = 'random')
clf.fit(X_train,y_train)
score = clf.score(X_test,y_test)
score

#决策树可视化
feature_name = ['酒精','苹果酸','灰','灰的碱性','镁','总酚','类黄酮','非黄烷类酚类','花青素','颜色强度','色调','od280/od315稀释葡萄酒','脯氨酸']
dot_data = tree.export_graphviz(clf,out_file = None,feature_names= feature_name,
                                class_names=["琴酒","雪莉","贝尔摩德"],
                                filled=True,
                                rounded = True)

graph = graphviz.Source(dot_data)
graph

#查看特征重要性
#  zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
[*zip(feature_name,clf.feature_importances_)]


'''[('酒精', 0.31494660642254896),
 ('苹果酸', 0.0),
 ('灰', 0.05724939731598719),
 ('灰的碱性', 0.06405387911775662),
 ('镁', 0.0),
 ('总酚', 0.010518365863640303),
 ('类黄酮', 0.4249255550082155),
 ('非黄烷类酚类', 0.01898375957316527),
 ('花青素', 0.0),
 ('颜色强度', 0.0),
 ('色调', 0.0),
 ('od280/od315稀释葡萄酒', 0.10932243669868624),
 ('脯氨酸', 0.0)]'''

决策树的调参 

score_train = clf.score(X_train,y_train)
score_train
#剪枝参数(提高决策树的泛化)
# 决策树不加限制,会生长到衡量不纯度的指标最优,或者没有更多特征可用,这样的决策树会过拟合
# 当决策树对训练数据有过于优秀的解释性,它必然包含了训练样本中的噪声,并且对未知数据的拟合程度不足


clf = DecisionTreeClassifier(criterion = 'entropy',random_state = 20,splitter = 'random',
                            max_depth = 4,
                             min_samples_split  =9,
#                            min_samples_leaf = 10
                            )
clf = clf.fit(X_train,y_train)
clf.score(X_test,y_test)
#0.8333333333333334

#确认最优的剪枝参数,限制树的深度max_depth
import matplotlib.pyplot as plt
test = []
for i in range(10):#0~9
    clf = DecisionTreeClassifier(criterion = 'entropy',
                                 random_state = 20,
                                 splitter = 'random',
                                 max_depth = i+1)
    clf = clf.fit(X_train,y_train)
    score = clf.score(X_test,y_test)
    test.append(score)
plt.plot(range(1,11),test,color = 'red',label = 'max_depth')
plt.xlabel('max_depth')
plt.ylabel('score')
plt.legend()
plt.show()
#根据图像可知最佳max_depth = 4

clf.predict(X_test)#返回每个测试样本的分类/回归结果

clf.apply(X_test)#返回每个测试样本所在的叶子结点的索引

银行借贷欺诈检测案例

数据集:

链接:https://pan.baidu.com/s/14Bfo1sKhoGoXAAz8fGWzNQ?pwd=lq03 
提取码:lq03

 训练模型

# 导入库
import pandas as pd
import numpy as np
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn import metrics
from IPython.display import Image
import pydotplus
from sklearn import tree
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import GridSearchCV
import warnings
warnings.filterwarnings("ignore")

# sep=‘\s+‘ 这是正则表达式,通过一定规则的表达式来匹配字符串用的
# \s 表示空白字符,包括但不限于空格、回车(\r)、换行(\n)、tab或者叫水平制表符(\t)等,这个根据编码格式不同代表的含义也不一样,感兴趣可以搜索看一下
# + 是重复修饰符,表示它前面与它紧邻的表达式格式相匹配的字符串至少出现一个,上不封顶
# \s+ 意思就是至少有一个空白符存在

data = pd.read_csv('loan_data 银行借贷决策树.txt',sep='\s+',encoding='utf-8',index_col='nameid')
data.head()

data.columns

x = data.drop(['approve'],axis = 1).values
y =  data['approve'].values
print(x.shape,y.shape)


x1 = x[:900]
y1 = y[:900]
x2 = x[900:]
y2 = y[900:]

x_train,x_test,y_train,y_test = train_test_split(x1,y1,test_size = 0.2)


clf = DecisionTreeClassifier()
clf.fit(x_train,y_train)
y_pred = clf.predict(x_test)
print('训练集评分:', clf.score(x_train,y_train))
print('验证集评分:', clf.score(x_test,y_test))
print('测试集评分', clf.score(x2,y2))
print("查准率:", metrics.precision_score(y_test,y_pred))
print('召回率:',metrics.recall_score(y_test,y_pred))
print('f1分数:', metrics.f1_score(y_test,y_pred))

'''训练集评分: 1.0
验证集评分: 0.7277777777777777
测试集评分 0.82
查准率: 0.8173913043478261
召回率: 0.7704918032786885
f1分数: 0.7932489451476794'''

 调优及可视化

#网格搜索最优参数
param = {'max_depth':[3,5,8],'min_samples_leaf':np.arange(3,10,1),'min_impurity_split':np.linspace(0.1,0.6,10),}
clf = GridSearchCV(DecisionTreeClassifier(),param_grid = param,cv = 8)
clf.fit(x_train,y_train)
print(clf.best_params_,clf.best_score_)

print(confusion_matrix(y_true  = y_test,y_pred = y_pred,labels = list(set(y))))#list(set())对原列表去重并按从小到大排序
print(metrics.classification_report(y_test,y_pred ,labels = list(set(y))))

#将网格搜索出来的最优参数代入模型重新训练
clf = DecisionTreeClassifier(max_depth = 5,min_samples_leaf = 4,min_impurity_split = 0.322)
clf.fit(x_train,y_train)
y_pred = clf.predict(x_test)
print('训练集评分:', clf.score(x_train,y_train))
print('验证集评分:', clf.score(x_test,y_test))
print('测试集评分', clf.score(x2,y2))
print("查准率:", metrics.precision_score(y_test,y_pred))
print('召回率:',metrics.recall_score(y_test,y_pred))
print('f1分数:', metrics.f1_score(y_test,y_pred))

'''训练集评分: 0.8347222222222223
验证集评分: 0.8555555555555555
测试集评分 0.99
查准率: 0.8287671232876712
召回率: 0.9918032786885246
f1分数: 0.9029850746268656'''

print(confusion_matrix(y_true  = y_test,y_pred = y_pred,labels = list(set(y))))#list(set())对原列表去重并按从小到大排序
print(metrics.classification_report(y_test,y_pred ,labels = list(set(y))))


import graphviz
dot_data = tree.export_graphviz(clf,out_file = None,
                                feature_names = data.columns[:-1],
                                class_names  = data.columns[-1],
                                filled = True,
                                rounded = True,
                                special_characters = True)
graph = graphviz.Source(dot_data)
graph


from sklearn.datasets import load_iris
from sklearn import tree
import graphviz
from sklearn.tree import DecisionTreeClassifier
iris = load_iris()
clf = DecisionTreeClassifier()
clf = clf.fit(iris.data,iris.target)
dot_data = tree.export_graphviz(clf ,out_file = None)
graph = graphviz.Source(dot_data)
graph .render('iris')

  • 3
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值