日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

决策树原理详解及python代码实现

發(fā)布時(shí)間:2024/1/23 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 决策树原理详解及python代码实现 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

決策樹(shù)算法(信貸中常用來(lái)尋找規(guī)則)

  • 1、算法原理
    • 1.1 ID3(多叉樹(shù)分類(lèi))
    • 1.2 C4.5(多叉樹(shù)分類(lèi))
    • 1.3 Cart(二叉樹(shù)分類(lèi)+回歸)
  • 2、ID3、C4.5與Cart比較
  • 3、算法優(yōu)缺點(diǎn)
  • 4、算法需要注意的點(diǎn)
  • 5、python代碼實(shí)現(xiàn)
    • 5.1導(dǎo)入相關(guān)包
    • 5.2 讀取數(shù)據(jù)并數(shù)據(jù)處理
    • 5.3 模型訓(xùn)練
    • 5.4 評(píng)估指標(biāo)
    • 5.4 決策樹(shù)以圖的形式輸出

1、算法原理

1.1 ID3(多叉樹(shù)分類(lèi))

信息熵:Ent(D)=?∑i=1npilogpiEnt(D)=-\sum_{i=1}^np_ilogp_iEnt(D)=?i=1n?pi?logpi?其中n為類(lèi)別,pip_ipi?為每個(gè)類(lèi)別的概率,DDD為某個(gè)特征,越小越確定

信息增益:Gain(D,a)=Ent(D)=?∑v=1v∣Dv∣∣D∣Ent(Dv)Gain(D,a)=Ent(D)=-\sum_{v=1}^v\frac{|D^v|}{|D|}Ent(D^v)Gain(D,a)=Ent(D)=?v=1v?DDv?Ent(Dv)越大純度提升越大,所以分裂argmaxGain(D,a)argmaxGain(D,a)argmaxGain(D,a)

eg.15個(gè)樣本,9個(gè)1和6個(gè)0;有個(gè)特征A(取值A1A_1A1?A2A_2A2?A3A_3A3?,其中A1A_1A1?(3個(gè)1,2個(gè)0),其中A2A_2A2?(2個(gè)1,3個(gè)0)其中A3A_3A3?(4個(gè)1,1個(gè)0))

Ent(A)=?(915?log2915+615?log2615)=0.971Ent(A)=-(\frac{9}{15}*log_2\frac{9}{15}+\frac{6}{15}*log_2\frac{6}{15})=0.971Ent(A)=?(159??log2?159?+156??log2?156?)=0.971

Gain(A,a)=0.971?(515Ent(A1)+515Ent(A2)+515Ent(A3))=0.083Gain(A,a)=0.971-(\frac{5}{15}Ent(A1)+\frac{5}{15}Ent(A2)+\frac{5}{15}Ent(A3))=0.083Gain(A,a)=0.971?(155?Ent(A1)+155?Ent(A2)+155?Ent(A3))=0.083

  • ID3在相同條件下取值較多的比較少的信息增益要大(2個(gè)值為12\frac{1}{2}21?,3個(gè)值為13\frac{1}{3}31?,但是3個(gè)信息增益會(huì)更大)
  • ID3沒(méi)有考慮連續(xù)特征
  • ID3對(duì)缺失值未考慮

需要懲罰取值較多的信息增益,引出了信息增益率,即C4.5的算法

1.2 C4.5(多叉樹(shù)分類(lèi))

IV(a)=?∑v=1v∣Dv∣∣D∣log2∣Dv∣∣D∣IV(a)=-\sum_{v=1}^v\frac{|D^v|}{|D|}log_2\frac{|D^v|}{|D|}IV(a)=?v=1v?DDv?log2?DDv? 特征取值越多,IV(a)IV(a)IV(a)越大

信息增益率:Gain_ratio(D,a)=Gain(D,a)IV(a)Gain\_ratio(D,a)=\frac{Gain(D,a)}{IV(a)}Gain_ratio(D,a)=IV(a)Gain(D,a)? argmaxGain_ratio(D,a)Gain\_ratio(D,a)Gain_ratio(D,a)

  • 如果為連續(xù)型變量,先從大到小排序,分別取2個(gè)中值(均值)作為劃分點(diǎn)計(jì)算

引出了分類(lèi)+回歸的決策樹(shù)

1.3 Cart(二叉樹(shù)分類(lèi)+回歸)

Gini(D)=1?∑i=1npi2Gini(D)=1-\sum_{i=1}^np_i^2Gini(D)=1?i=1n?pi2? 反映隨機(jī)抽2個(gè)樣本,不一致的概率,越小越好(越純)

Ginisplit(D)=1?∑v=1v∣Dv∣∣D∣Gini(Dv)Gini_{split}(D)=1-\sum_{v=1}^v\frac{|D^v|}{|D|}Gini(D^v)Ginisplit?(D)=1?v=1v?DDv?Gini(Dv)

eg.Age(youth(5)、middle(5)、senior(4)),以youth(5)和middle+senior(9)分割為例:

Ginisplit(Age)=514[1?[(35)2+(25)2]]+914[1?[(29)2+(79)2]]=0.39Gini_{split}(Age)=\frac{5}{14}[1-[(\frac{3}{5})^2+(\frac{2}{5})^2]]+\frac{9}{14}[1-[(\frac{2}{9})^2+(\frac{7}{9})^2]]=0.39Ginisplit?(Age)=145?[1?[(53?)2+(52?)2]]+149?[1?[(92?)2+(97?)2]]=0.39
如果為連續(xù)性變量處理方式與C4.5相同

回歸mse:

  • 根據(jù)每一個(gè)連續(xù)值作為劃分點(diǎn)(或用分類(lèi)的方式取均值作為劃分點(diǎn)),將其劃分S1S_1S1?S2S_2S2?
  • 計(jì)算每個(gè)分支(S1S_1S1?S2S_2S2?)的均值。 mean=sum(s1或s2里真實(shí)值)該集合樣本總數(shù)mean=\frac{sum(s_1或s_2里真實(shí)值)}{該集合樣本總數(shù)}mean=數(shù)sum(s1?s2?實(shí))?即為該分支的預(yù)測(cè)值
  • 計(jì)算S1S_1S1?S2S_2S2?的mse的和。 mse=(該集合每一個(gè)樣本真實(shí)值?mean)2mse=(該集合每一個(gè)樣本真實(shí)值-mean)^2mse=(個(gè)實(shí)?mean)2

注:實(shí)踐證明GiniGiniGiniGainGainGain效果差不多

2、ID3、C4.5與Cart比較

處理方式信息增益(ID3)信息增益率(C4.5)Gini(Cart)
連續(xù)值處理×\times×√\surd√\surd
缺失值處理×\times×√\surd√\surd
剪枝×\times×√\surd√\surd
  • ID3、C4.5與Cart特征選擇只選一個(gè)特征。但大多數(shù)由一組特征決定。這樣得到的決策樹(shù)更準(zhǔn)確(oc1)
  • 樣本發(fā)生一點(diǎn)改變,樹(shù)的結(jié)構(gòu)可能會(huì)發(fā)生劇烈的變化

3、算法優(yōu)缺點(diǎn)

一、優(yōu)點(diǎn):

  • 簡(jiǎn)單直觀,生成的決策樹(shù)可解釋性強(qiáng)
  • 不需要數(shù)據(jù)預(yù)處理(例如歸一化處理,但封裝的scikit-learn需要處理缺失值與字符型變量)
  • 可以處理多維度多分類(lèi)問(wèn)題

一、缺點(diǎn):

  • 容易過(guò)擬合
  • 樣本發(fā)生改變可能導(dǎo)致完全不同的樹(shù)
  • 樣本不平衡時(shí),樹(shù)會(huì)偏向于類(lèi)別較多的一類(lèi)

4、算法需要注意的點(diǎn)

決策樹(shù)的構(gòu)建過(guò)程中出現(xiàn)過(guò)擬合的原因及解決方法
原因:

  • 在構(gòu)建過(guò)程中沒(méi)有進(jìn)行合理的限制(如樹(shù)的深度等)
  • 樣本中有噪聲數(shù)據(jù),沒(méi)有進(jìn)行有效的剔除
  • 變量較多也容易產(chǎn)生過(guò)擬合

解決方法: 剪枝、限制深度、RF、正則化等

決策樹(shù)如何處理缺失值
1、使用權(quán)重方法重構(gòu)。(可認(rèn)為以前1?Gain*Gain?Gain,現(xiàn)在無(wú)缺失比率?Gain*Gain?Gain)訓(xùn)練時(shí)特征出現(xiàn)缺失怎么處理(劃分)即不考慮缺失,然后重賦權(quán)重
2、將缺失(劃分變量)的樣本中分別放到不同分支再進(jìn)行分支。缺失變量樣本的歸屬分支問(wèn)題
3、同時(shí)探查所有分支,然后算每個(gè)類(lèi)別的概率,取概率最大的類(lèi)別賦值該樣本。測(cè)試集中缺失處理

決策樹(shù)遞歸終止的條件
1、所有子集被正確分類(lèi);2、沒(méi)有合適的特征選擇或信息增益(信息增益率/Gini)很小

決策樹(shù)的變量重要性
如樣本分裂占比?*?Gini/信息增益比

5、python代碼實(shí)現(xiàn)

5.1導(dǎo)入相關(guān)包

import numpy as np import pandas as pd from sklearn.preprocessing import LabelEncoder #分類(lèi)變量編碼包 from sklearn.model_selection import train_test_split from sklearn.tree import DecisionTreeClassifier import variable_iv as vi import Logistic_model as lmimport os os.chdir('E:/wyz/Desktop/cart/') os.environ["PATH"] += os.pathsep + 'D:/Program Files (x86)/Graphviz2.38/bin/'#決策樹(shù)可視化的包

5.2 讀取數(shù)據(jù)并數(shù)據(jù)處理

data = pd.read_excel('ceshi.xlsx',sheet_name = 'Sheet2') #分類(lèi)變量編碼 from sklearn.preprocessing import LabelEncoder le = LabelEncoder() str_variable = list(data.dtypes[data.dtypes.values == object].index) for col in str_variable: data[col] = le.fit_transform(data[col].astype(str)) #在單變量分析的基礎(chǔ)上填充缺失值(看哪一組的1的比率最接近于缺失值的那一組) data['var1'] = data['var1'].fillna(0.42089) data['var2'] = data['var2'].fillna(125.854) #劃分?jǐn)?shù)據(jù)集 y = data_model['target'] x = data_model.drop('target', axis=1) x_train, x_test, y_train, y_test = train_test_split(x, y,random_state=0,train_size=0.7)

5.3 模型訓(xùn)練

#建立模型(min_samples_leaf和min_samples_split需要慎重選擇)(和傳統(tǒng)決策樹(shù)有很大區(qū)別) model_tree = DecisionTreeClassifier(criterion='gini',#劃分標(biāo)準(zhǔn)splitter='best',#特征劃分標(biāo)準(zhǔn)max_depth=3,#樹(shù)的最大深度min_samples_split=20,#劃分所需要的最小樣本數(shù)min_samples_leaf=10,#分到每個(gè)葉子最小樣本數(shù)max_features=None,#用于參與劃分的變量個(gè)數(shù) max_leaf_nodes=None,#最大葉子節(jié)點(diǎn)數(shù) min_impurity_decrease=0.0,#節(jié)點(diǎn)劃分最小不純度 min_weight_fraction_leaf=0.0,#葉子節(jié)點(diǎn)最小的樣本權(quán)重和presort=False,#進(jìn)行擬合前是否預(yù)分?jǐn)?shù)據(jù)來(lái)加快樹(shù)的構(gòu)建random_state=None, )#建模要class_weight='balanced' model_tree.fit(x_train, y_train)

5.4 評(píng)估指標(biāo)

test_proba = pd.DataFrame(model_tree.predict_proba(x_test))[1].values#預(yù)測(cè)為0的概率 print('測(cè)試集AUC: %.4f'%roc_auc_score(y_test,test_proba))#AUC,預(yù)測(cè)為概率#變量重要性(是由該節(jié)點(diǎn)樣本占總體樣本*gini的減少量) importances = list(model_tree.feature_importances_) print(importances)#輸出變量重要的前幾個(gè)變量(求最大的三個(gè)索引nsmallest與nlargest相反求最小) import heapq imp_index = list(map(importances.index, heapq.nlargest(3,importances))) var_imp = [] for i in imp_index:var_imp.append(list1[i]) print(var_imp)

5.4 決策樹(shù)以圖的形式輸出

#解決中文亂碼問(wèn)題(含中文的輸出方式) from sklearn.externals.six import StringIO import pydotplus from IPython.display import Image dot_data = StringIO() #決策樹(shù)圖 list1 = ['var1','var2','var3','var4','var5','var6'] tree.export_graphviz(model_tree, out_file=dot_data, feature_names=list1,filled=True, rounded=True, special_characters=True) graph = pydotplus.graph_from_dot_data(dot_data.getvalue().replace( 'helvetica' ,' "Microsoft YaHei" ')) graph.write_png("result1.png")#將圖畫(huà)出來(lái) #https://blog.csdn.net/qq_39386012/article/details/83857609#commentBox Image(graph.create_png())#在jupter中可視化出來(lái)from sklearn import tree import pydotplus #決策樹(shù)圖(不含含中文的輸出方式) list1 = ['var1','var2','var3','var4','var5','var6'] dot_data = tree.export_graphviz(model_tree, out_file=None, feature_names=list1,filled=True, rounded=True, special_characters=True) graph = pydotplus.graph_from_dot_data(dot_data) graph.write_png("result2.png")#將圖畫(huà)出來(lái)

決策樹(shù)參數(shù)詳解

參數(shù)默認(rèn)值及輸入類(lèi)型介紹
criterion 默認(rèn)值:gini,即CART算法
輸入:entropy, gini
特征選擇標(biāo)準(zhǔn)
splitter 默認(rèn)值:best
輸入:best, random
best在特征的所有劃分點(diǎn)中找出最優(yōu)的劃分點(diǎn),random隨機(jī)的在部分劃分點(diǎn)中找 局部最優(yōu)的劃分點(diǎn)。默認(rèn)的‘best’適合樣本量不大的時(shí)候,而如果樣本數(shù)據(jù)量非常大,此時(shí)決策樹(shù)構(gòu)建推薦‘random’
max_depth 默認(rèn)值:None
輸入:int, None
決策樹(shù)最大深度。一般數(shù)據(jù)比較少或者特征少的時(shí)候可以不用管這個(gè)值,如果模型樣本數(shù)量多,特征也多時(shí),推薦限制這個(gè)最大深度,具體取值取決于數(shù)據(jù)的分布。常用的可以取值10-100之間,常用來(lái)解決過(guò)擬合
min_samples_split 默認(rèn)值:2
輸入:int, float
內(nèi)部節(jié)點(diǎn)(即判斷條件)再劃分所需最小樣本數(shù)。如果是int,則取傳入值本身作為最小樣本數(shù);如果是float,則取ceil(min_samples_split*樣本數(shù)量)作為最小樣本數(shù)。(向上取整)
min_samples_leaf 輸入:int, float葉子節(jié)點(diǎn)(即分類(lèi))最少樣本數(shù)。如果是int,則取傳入值本身作為最小樣本數(shù);如果是float,則取ceil(min_samples_leaf*樣本數(shù)量)的值作為最小樣本數(shù)。這個(gè)值限制了葉子節(jié)點(diǎn)最少的樣本數(shù),如果某葉子節(jié)點(diǎn)數(shù)目小于樣本數(shù),則會(huì)和兄弟節(jié)點(diǎn)一起被剪枝
min_weight_fraction_leaf 默認(rèn)值:0
輸入:float
葉子節(jié)點(diǎn)(即分類(lèi))最小的樣本權(quán)重和,【float】。這個(gè)值限制了葉子節(jié)點(diǎn)所有樣本權(quán)重和的最小值,如果小于這個(gè)值,則會(huì)和兄弟節(jié)點(diǎn)一起被剪枝。默認(rèn)是0,就是不考慮權(quán)重問(wèn)題,所有樣本的權(quán)重相同。
注:一般來(lái)說(shuō)如果我們有較多樣本有缺失值或者分類(lèi)樹(shù)樣本的分布類(lèi)別偏差很大,就會(huì)引入樣本權(quán)重,這時(shí)就要注意此值
max_features 輸入:int,float在劃分?jǐn)?shù)據(jù)集時(shí)考慮的最多的特征值數(shù)量,【int值】。在每次split時(shí)最大特征數(shù);【float值】表示百分?jǐn)?shù),即(max_features*n_features)
random_state 默認(rèn)值:None
輸入:int, randomSate instance, None
max_leaf_nodes 默認(rèn)值:None
輸入:int, None
最大葉子節(jié)點(diǎn)數(shù)。通過(guò)設(shè)置最大葉子節(jié)點(diǎn)數(shù),可以防止過(guò)擬合。默認(rèn)值None,默認(rèn)情況下不設(shè)置最大葉子節(jié)點(diǎn)數(shù)。如果加了限制,算法會(huì)建立在最大葉子節(jié)點(diǎn)數(shù)內(nèi)最優(yōu)的決策樹(shù)。如果特征不多,可以不考慮這個(gè)值,但是如果特征多,可以加限制,具體的值可以通過(guò)交叉驗(yàn)證得到
min_impurity_decrease 默認(rèn)值:0
輸入:float
節(jié)點(diǎn)劃分最小不純度,默認(rèn)值為‘0’。限制決策樹(shù)的增長(zhǎng),節(jié)點(diǎn)的不純度(基尼系數(shù),信息增益,均方差,絕對(duì)差)必須大于這個(gè)閾值,否則該節(jié)點(diǎn)不再生成子節(jié)點(diǎn)
class_weight 默認(rèn)值:None
輸入:dict, list of dicts, balanced
類(lèi)別權(quán)重(不適用于回歸樹(shù),sklearn.tree.DecisionTreeRegressor) 指定樣本各類(lèi)別的權(quán)重,主要是為了防止訓(xùn)練集某些類(lèi)別的樣本過(guò)多,導(dǎo)致訓(xùn)練的決策樹(shù)過(guò)于偏向這些類(lèi)別。balanced,算法自己計(jì)算權(quán)重,樣本量少的類(lèi)別所對(duì)應(yīng)的樣本權(quán)重會(huì)更高。如果樣本類(lèi)別分布沒(méi)有明顯的偏倚,則可以不管這個(gè)參數(shù)
presort 默認(rèn)值:False
輸入:bool
表示在進(jìn)行擬合之前,是否預(yù)分?jǐn)?shù)據(jù)來(lái)加快樹(shù)的構(gòu)建
注:對(duì)于數(shù)據(jù)集非常龐大的分類(lèi),presort=true將導(dǎo)致整個(gè)分類(lèi)變得緩慢;當(dāng)數(shù)據(jù)集較小,且樹(shù)的深度有限制,presort=true才會(huì)加速分類(lèi)

決策樹(shù)調(diào)參注意事項(xiàng)

  • 當(dāng)樣本少數(shù)量但是樣本特征非常多的時(shí)候,決策樹(shù)很容易過(guò)擬合,一般來(lái)說(shuō),樣本數(shù)比特征數(shù)多一些會(huì)比較容易建立健壯的模型
  • 如果樣本數(shù)量少但是樣本特征非常多,在擬合決策樹(shù)模型前,推薦先做維度規(guī)約,比如主成分分析(PCA),特征選擇(Losso)或者獨(dú)立成分分析(ICA)。這樣特征的維度會(huì)大大減小。再來(lái)擬合決策樹(shù)模型效果會(huì)好。
  • 推薦多用決策樹(shù)的可視化,同時(shí)先限制決策樹(shù)的深度(比如最多3層),這樣可以先觀察下生成的決策樹(shù)里數(shù)據(jù)的初步擬合情況,然后再?zèng)Q定是否要增加深度。
  • 在訓(xùn)練模型先,注意觀察樣本的類(lèi)別情況(主要指分類(lèi)樹(shù)),如果類(lèi)別分布非常不均勻,就要考慮用class_weight來(lái)限制模型過(guò)于偏向樣本多的類(lèi)別。
  • 決策樹(shù)的數(shù)組使用的是numpy的float32類(lèi)型,如果訓(xùn)練數(shù)據(jù)不是這樣的格式,算法會(huì)先做copy再運(yùn)行。
  • 如果輸入的樣本矩陣是稀疏的,推薦在擬合前調(diào)用csc_matrix稀疏化,在預(yù)測(cè)前調(diào)用csr_matrix稀疏化。

總結(jié)

以上是生活随笔為你收集整理的决策树原理详解及python代码实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。