決策樹(Decision Tree,又稱為判定樹)算法是機(jī)器學(xué)習(xí)中常見的一類算法,是一種以樹結(jié)構(gòu)(包括二叉樹和多叉樹)形式表達(dá)的預(yù)測(cè)分析模型。每個(gè)決策點(diǎn)實(shí)現(xiàn)一個(gè)具有離散輸出的測(cè)試函數(shù),記為分支沼沈。決策樹由結(jié)點(diǎn)和有向邊組成吠勘。結(jié)點(diǎn)有兩種類型: 內(nèi)部結(jié)點(diǎn)和葉節(jié)點(diǎn)若治。內(nèi)部節(jié)點(diǎn)表示一個(gè)特征或?qū)傩跃诱祝~節(jié)點(diǎn)表示一個(gè)類覆山。
一、決策樹的結(jié)構(gòu)
決策樹通常有三個(gè)步驟:特征選擇泥栖、決策樹生成簇宽、決策樹的修建。
特征選擇是建立決策樹之前十分重要的一步吧享。如果是隨機(jī)地選擇特征魏割,那么所建立決策樹的學(xué)習(xí)效率將會(huì)大打折扣。通常我們?cè)谶x擇特征時(shí)钢颂,會(huì)考慮到兩種不同的指標(biāo)钞它,分別為:信息增益和信息增益比。要想弄清楚這兩個(gè)概念殊鞭,我們就不得不提到信息論中的另一個(gè)十分常見的名詞 —— 熵遭垛。熵(Entropy)是表示隨機(jī)變量不確定性的度量。簡(jiǎn)單來講操灿,熵越大锯仪,隨機(jī)變量的不確定性就越大。而特征 A 對(duì)于某一訓(xùn)練集 D 的信息增益 g(D, A) 定義為集合 D 的熵 H(D) 與特征 A 在給定條件下 D 的熵 H(D/A) 之差趾盐。
二庶喜、決策樹分兩個(gè)階段
1、訓(xùn)練階段
從給定的訓(xùn)練數(shù)據(jù)集DB救鲤,構(gòu)造出一顆決策樹
class=DecisionTree(DB)
2久窟、分類階段
從根開始,按照決策樹的分類屬性逐層往下劃分蜒简,直到葉節(jié)點(diǎn)瘸羡,獲得概念(決策、分類)結(jié)果搓茬。
y=DecisionTree(x)
三犹赖、決策樹熵原理
熵:代表的是一個(gè)混亂程度
假設(shè)X和Y兩個(gè)事件相互獨(dú)立队他,則P(X,Y)=P(X)*P(Y),Log(XY)=Log(X)+Log(Y)
H(X),H(Y):事件發(fā)生的不確定性
P(幾率越大)->H(X)值越小->熵值越小
四张肾、構(gòu)造決策樹根節(jié)點(diǎn)
決策樹的基本思想是隨著樹深度的增加芭析,節(jié)點(diǎn)的熵迅速地降低。熵降低的速度越快越好吞瞪,這樣我們構(gòu)造的決策樹是一顆高度最矮的決策樹(分支過多容易出現(xiàn)過擬合的現(xiàn)象)馁启,我們舉一個(gè)實(shí)例來看一下:
接下來我們分別求出四個(gè)特征條件下的信息熵:
以outlook為例:
當(dāng)outlook=sunny時(shí)霉颠,2/5的概率打球,3/5的概率不打球荆虱,entropy=0.971
當(dāng)outlook=overcast時(shí)蒿偎,entropy=0
當(dāng)outlook=rainy時(shí),entropy=0.971
而根據(jù)歷史統(tǒng)計(jì)數(shù)據(jù)怀读,outlook取值為sunny酥郭、overcast、rainy的概率分別是5/14愿吹、4/14不从、5/14,所以當(dāng)已知變量outlook的值時(shí)犁跪,信息熵為:
5/14 x 0.971 + 4/14 x 0 + 5/14 x 0.971 = 0.693
這樣的話系統(tǒng)熵就從0.940下降到了0.693椿息,信息增益gain(outlook)為0.940-0.693=0.247
同樣可以計(jì)算出gain(temperture)=0.029,gain(humidity)=0.152坷衍,gain(windy)=0.048寝优。gain(outlook)最大(即outlook在第一步使系統(tǒng)的信息熵下降的最快),所以決策樹的根節(jié)點(diǎn)就去outlook枫耳。其余子節(jié)點(diǎn)的求法和根節(jié)點(diǎn)類似乏矾,所以決策樹算法是一個(gè)遞歸算法。
我們使用代碼實(shí)現(xiàn)一下:
from math import log
def createDataSet():
#outlook:sunny:1,overcast:2,rainy:3
#temperature:hot:1,mild:2,cool:3
#humidity:high:1,normal:2
#windy:false:1,true:2
#play:no,yes
dataSet=[
[1,1,1,1,'no'],
[1,1,1,2,'no'],
[2,1,1,1,'yes'],
[3,2,1,1,'yes'],
[3,3,2,1,'yes'],
[3,3,2,2,'no'],
[2,3,2,2,'yes'],
[1,2,1,1,'no'],
[1,3,2,1,'yes'],
[3,2,2,1,'yes'],
[1,2,2,2,'yes'],
[2,2,1,2,'yes'],
[2,1,2,1,'yes'],
[3,2,1,2,'no']
]
labels=['outlook','temperature','humidity','windy','play']
return dataSet,labels
def calcShannonEnt(dataSet):
#返回?cái)?shù)據(jù)集行數(shù)
numEntries=len(dataSet)
#保存每個(gè)標(biāo)簽(label)出現(xiàn)次數(shù)的字典
labelCounts={}
#對(duì)每組特征向量進(jìn)行統(tǒng)計(jì)
for featVec in dataSet:
currentLabel=featVec[-1]#提取標(biāo)簽信息
if currentLabel not in labelCounts.keys():#如果標(biāo)簽沒有放入統(tǒng)計(jì)次數(shù)
labelCounts[currentLabel]=0
labelCounts[currentLabel]+=1#label計(jì)數(shù)
shannonEnt=0.0
#計(jì)算經(jīng)驗(yàn)熵
for key in labelCounts:
prob=float(labelCounts[key])/numEntries #選擇該標(biāo)簽的概率
shannonEnt-=prob*log(prob,2) #利用公式計(jì)算
return shannonEnt
def chooseBestFeatureToSplit(dataSet):
#特征數(shù)量
numFeatures = len(dataSet[0]) - 1
#計(jì)數(shù)數(shù)據(jù)集的香農(nóng)熵
baseEntropy = calcShannonEnt(dataSet)
#信息增益
bestInfoGain = 0.0
#最優(yōu)特征的索引值
bestFeature = -1
#遍歷所有特征
for i in range(numFeatures):
# 獲取dataSet的第i個(gè)所有特征
featList = [example[i] for example in dataSet]
#創(chuàng)建set集合{},元素不可重復(fù)
uniqueVals = set(featList)
#經(jīng)驗(yàn)條件熵
newEntropy = 0.0
#計(jì)算信息增益
for value in uniqueVals:
#subDataSet劃分后的子集
subDataSet = splitDataSet(dataSet, i, value)
#計(jì)算子集的概率
prob = len(subDataSet) / float(len(dataSet))
#根據(jù)公式計(jì)算經(jīng)驗(yàn)條件熵
newEntropy += prob * calcShannonEnt((subDataSet))
#信息增益
infoGain = baseEntropy - newEntropy
#打印每個(gè)特征的信息增益
print("第%d個(gè)特征的增益為%.3f" % (i, infoGain))
#計(jì)算信息增益
if (infoGain > bestInfoGain):
#更新信息增益钻心,找到最大的信息增益
bestInfoGain = infoGain
#記錄信息增益最大的特征的索引值
bestFeature = i
#返回信息增益最大特征的索引值
return bestFeature
def splitDataSet(dataSet,axis,value):
retDataSet=[]
for featVec in dataSet:
if featVec[axis]==value:
reducedFeatVec=featVec[:axis]
reducedFeatVec.extend(featVec[axis+1:])
retDataSet.append(reducedFeatVec)
return retDataSet
if __name__=='__main__':
dataSet,features=createDataSet()
print(dataSet)
print(calcShannonEnt(dataSet))
print("最優(yōu)索引值:"+str(chooseBestFeatureToSplit(dataSet)))
五凄硼、決策樹算法
ID3:信息增益
C4.5:信息增益率
CART:Gini系數(shù)
ID3 算法通過遞歸的方式建立決策樹。建立時(shí)捷沸,從根節(jié)點(diǎn)開始摊沉,對(duì)節(jié)點(diǎn)計(jì)算每個(gè)獨(dú)立特征的信息增益,選擇信息增益最大的特征作為節(jié)點(diǎn)特征痒给。接下來说墨,對(duì)該特征施加判斷條件,建立子節(jié)點(diǎn)苍柏。然后針對(duì)子節(jié)點(diǎn)再此使用信息增益進(jìn)行判斷尼斧,直到所有特征的信息增益很小或者沒有特征時(shí)結(jié)束,這樣就逐步建立一顆完整的決策樹试吁。除了從信息增益演化而來的 ID3 算法突颊,還有一種常見的算法叫 C4.5。C4.5 算法同樣由 John Ross Quinlan 發(fā)明潘悼,但它使用了信息增益比來選擇特征,這被看成是 ID3 算法的一種改進(jìn)爬橡。C4.5算法能夠處理連續(xù)型的屬性治唤。首先將連續(xù)型屬性離散化,把連續(xù)型屬性的值分成不同的區(qū)間糙申,依據(jù)是比較各個(gè)分裂點(diǎn)Gian值得大小宾添,關(guān)于缺失數(shù)據(jù)在構(gòu)建決策樹時(shí),可以簡(jiǎn)單地忽略缺失數(shù)據(jù)柜裸,即在計(jì)算增益時(shí)缕陕,僅考慮具有屬性值的記錄。
ID3 和 C4.5 算法簡(jiǎn)單高效疙挺,但是他倆均存在一個(gè)缺點(diǎn)扛邑,那就是用“完美去造就了另一個(gè)不完美”。這兩個(gè)算法從信息增益和信息增益比開始铐然,對(duì)整個(gè)訓(xùn)練集進(jìn)行的分類蔬崩,擬合出來的模型針對(duì)該訓(xùn)練集的確是非常完美的。但是搀暑,這種完美就使得整體模型的復(fù)雜度較高沥阳,而對(duì)其他數(shù)據(jù)集的預(yù)測(cè)能力就降低了,也就是我們常說的過擬合而使得模型的泛化能力變?nèi)酢?br>
CART 算法本身就包含了決策樹的生成和修剪自点,并且可以同時(shí)被運(yùn)用到分類樹和回歸樹桐罕。這就是和 ID3 及 C4.5 之間的最大區(qū)別。
當(dāng)然,過擬合的問題也是可以解決的功炮,那就是對(duì)決策樹進(jìn)行修剪溅潜。
六、決策樹的剪枝策略
決策樹的修剪死宣,其實(shí)就是通過優(yōu)化損失函數(shù)來去掉不必要的一些分類特征伟恶,降低模型的整體復(fù)雜度。修剪的方式毅该,就是從樹的葉節(jié)點(diǎn)出發(fā)博秫,向上回縮,逐步判斷眶掌。如果去掉某一特征后挡育,整棵決策樹所對(duì)應(yīng)的損失函數(shù)更小,那就將該特征及帶有的分支剪掉朴爬。
剪枝策略分為兩種:
預(yù)剪枝:在構(gòu)建決策樹的過程時(shí)即寒,提前停止
后剪枝:決策樹構(gòu)建好后,然后才開始裁剪
七召噩、鳶尾花分類實(shí)驗(yàn)
數(shù)據(jù)集的介紹
鳶尾花數(shù)據(jù)集是機(jī)器學(xué)習(xí)領(lǐng)域一個(gè)非常經(jīng)典的分類數(shù)據(jù)集母赵。數(shù)據(jù)集名稱的準(zhǔn)確名稱為 Iris DataSet,總共包含 150 行數(shù)據(jù)。每一行數(shù)據(jù)由 4 個(gè)特征值及一個(gè)目標(biāo)值組成具滴。其中 4 個(gè)特征值分別為:萼片長(zhǎng)度凹嘲、萼片寬度、花瓣長(zhǎng)度构韵、花瓣寬度周蹭。該數(shù)據(jù)集可以直接從網(wǎng)上下載,網(wǎng)上有很多關(guān)于該數(shù)據(jù)集的介紹疲恢,如果找不到可以在下方留言或者私信我凶朗。
#導(dǎo)入數(shù)據(jù)集
import pandas as pd
iris_data = pd.read_csv('F:\\BaiduNetdiskDownload\\決策樹\\決策樹鳶尾花\\iris.data')
#指定列名
iris_data.columns = ['sepal_length_cm', 'sepal_width_cm', 'petal_length_cm', 'petal_width_cm', 'class']
iris_data.head()
#查看一下數(shù)據(jù)集的信息
iris_data.describe()#特征之間數(shù)據(jù)的分布
這里我們使用seaborn來進(jìn)行繪圖操作,它比matplotlib更方便直觀一點(diǎn):
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sb
sb.pairplot(iris_data.dropna(), hue='class')#不能有缺失值
plt.figure(figsize=(10, 10))
for column_index, column in enumerate(iris_data.columns):
if column == 'class':
continue
plt.subplot(2, 2, column_index + 1)
sb.violinplot(x='class', y=column, data=iris_data)#小提琴圖
接下來我們進(jìn)行數(shù)據(jù)集的劃分:
from sklearn.cross_validation import train_test_split
all_inputs = iris_data[['sepal_length_cm', 'sepal_width_cm',
'petal_length_cm', 'petal_width_cm']].values
all_classes = iris_data['class'].values
(training_inputs,
testing_inputs,
training_classes,
testing_classes) = train_test_split(all_inputs, all_classes, train_size=0.75, random_state=1)
然后我們使用Scikit-learn包引入決策樹算法显拳,Scikit-learn(sklearn)是機(jī)器學(xué)習(xí)中常用的第三方模塊棚愤,對(duì)常用的機(jī)器學(xué)習(xí)方法進(jìn)行了封裝。但是DecisionTreeClassifier() 模型方法中也包含非常多的參數(shù)值杂数,這里列舉一下:
#使用決策樹算法進(jìn)行分析
from sklearn.tree import DecisionTreeClassifier
# 1.criterion gini or entropy 基尼系數(shù)和熵值的選擇
# 2.splitter best or random 前者是在所有特征中找最好的切分點(diǎn) 后者是在部分特征中(數(shù)據(jù)量大的時(shí)候)
# 3.max_features None(所有)遇八,log2,sqrt耍休,N 特征小于50的時(shí)候一般使用所有的
#剪枝操作
# 4.max_depth 數(shù)據(jù)少或者特征少的時(shí)候可以不管這個(gè)值刃永,如果模型樣本量多,特征也多的情況下羊精,可以嘗試限制下
#要不要停止操作
# 5.min_samples_split 如果某節(jié)點(diǎn)的樣本數(shù)少于min_samples_split斯够,則不會(huì)繼續(xù)再嘗試選擇最優(yōu)特征來進(jìn)行劃分
# 如果樣本量不大囚玫,不需要管這個(gè)值。如果樣本量數(shù)量級(jí)非常大读规,則推薦增大這個(gè)值抓督。
# 6.min_samples_leaf 這個(gè)值限制了葉子節(jié)點(diǎn)最少的樣本數(shù),如果某葉子節(jié)點(diǎn)數(shù)目小于樣本數(shù)束亏,則會(huì)和兄弟節(jié)點(diǎn)一起被
# 剪枝铃在,如果樣本量不大,不需要管這個(gè)值碍遍,大些如10W可是嘗試下5
# 7.min_weight_fraction_leaf 這個(gè)值限制了葉子節(jié)點(diǎn)所有樣本權(quán)重和的最小值定铜,如果小于這個(gè)值,則會(huì)和兄弟節(jié)點(diǎn)一起
# 被剪枝默認(rèn)是0怕敬,就是不考慮權(quán)重問題揣炕。一般來說,如果我們有較多樣本有缺失值东跪,
# 或者分類樹樣本的分布類別偏差很大畸陡,就會(huì)引入樣本權(quán)重,這時(shí)我們就要注意這個(gè)值了虽填。
# 8.max_leaf_nodes 通過限制最大葉子節(jié)點(diǎn)數(shù)丁恭,可以防止過擬合,默認(rèn)是"None”斋日,即不限制最大的葉子節(jié)點(diǎn)數(shù)牲览。
# 如果加了限制,算法會(huì)建立在最大葉子節(jié)點(diǎn)數(shù)內(nèi)最優(yōu)的決策樹桑驱。
# 如果特征不多,可以不考慮這個(gè)值跛蛋,但是如果特征分成多的話熬的,可以加以限制
# 具體的值可以通過交叉驗(yàn)證得到。
# 9.class_weight 指定樣本各類別的的權(quán)重赊级,主要是為了防止訓(xùn)練集某些類別的樣本過多
# 導(dǎo)致訓(xùn)練的決策樹過于偏向這些類別押框。這里可以自己指定各個(gè)樣本的權(quán)重
# 如果使用“balanced”,則算法會(huì)自己計(jì)算權(quán)重理逊,樣本量少的類別所對(duì)應(yīng)的樣本權(quán)重會(huì)高橡伞。
# 10.min_impurity_split 這個(gè)值限制了決策樹的增長(zhǎng),如果某節(jié)點(diǎn)的不純度
# (基尼系數(shù)晋被,信息增益兑徘,均方差,絕對(duì)差)小于這個(gè)閾值
# 則該節(jié)點(diǎn)不再生成子節(jié)點(diǎn)羡洛。即為葉子節(jié)點(diǎn) 挂脑。
#定義一個(gè)決策樹的對(duì)象
decision_tree_classifier = DecisionTreeClassifier()
#訓(xùn)練模型
# Train the classifier on the training set
decision_tree_classifier.fit(training_inputs, training_classes)
#所得模型的準(zhǔn)確性
# Validate the classifier on the testing set using classification accuracy
decision_tree_classifier.score(testing_inputs, testing_classes)
from sklearn.cross_validation import cross_val_score#交叉驗(yàn)證交叉驗(yàn)證用于評(píng)估模型的預(yù)測(cè)性能,尤其是訓(xùn)練好的模型在新數(shù)據(jù)上的表現(xiàn),可以在一定程度上減小過擬合崭闲。還可以從有限的數(shù)據(jù)中獲取盡可能多的有效信息肋联。
import numpy as np
decision_tree_classifier = DecisionTreeClassifier()
# cross_val_score returns a list of the scores, which we can visualize
# to get a reasonable estimate of our classifier's performance
cv_scores = cross_val_score(decision_tree_classifier, all_inputs, all_classes, cv=10)#cv:選擇每次測(cè)試折數(shù)
print (cv_scores)
#kde=False
sb.distplot(cv_scores)
plt.title('Average score: {}'.format(np.mean(cv_scores)))
我們?cè)O(shè)置一下參數(shù),查看運(yùn)行結(jié)果:
decision_tree_classifier = DecisionTreeClassifier(max_depth=1)
cv_scores = cross_val_score(decision_tree_classifier, all_inputs, all_classes, cv=10)
print (cv_scores)
sb.distplot(cv_scores, kde=False)
plt.title('Average score: {}'.format(np.mean(cv_scores)))
我們使用GridSearchCV網(wǎng)格搜索進(jìn)行自動(dòng)調(diào)參刁俭,把參數(shù)輸進(jìn)去橄仍,能給出最優(yōu)化的結(jié)果和參數(shù):
from sklearn.grid_search import GridSearchCV
from sklearn.cross_validation import StratifiedKFold
decision_tree_classifier = DecisionTreeClassifier()
parameter_grid = {'max_depth': [1, 2, 3, 4, 5],
'max_features': [1, 2, 3, 4]}
cross_validation = StratifiedKFold(all_classes, n_folds=10)
grid_search = GridSearchCV(decision_tree_classifier,
param_grid=parameter_grid,
cv=cross_validation)
grid_search.fit(all_inputs, all_classes)
print('Best score: {}'.format(grid_search.best_score_))
print('Best parameters: {}'.format(grid_search.best_params_))
八、決策樹的優(yōu)缺點(diǎn)以及改進(jìn)
- 優(yōu)點(diǎn):
1牍戚、簡(jiǎn)單易理解和解釋侮繁,樹木可視化
2、需要很少的數(shù)據(jù)準(zhǔn)備翘魄,其他技術(shù)通常需要數(shù)據(jù)歸一化 - 缺點(diǎn):
決策樹學(xué)習(xí)者可以創(chuàng)建不能很好的推廣數(shù)據(jù)的過于復(fù)雜的樹鼎天,這被稱為過擬合 - 改進(jìn):
1、剪枝cart算法(決策樹API當(dāng)中已經(jīng)實(shí)現(xiàn)暑竟,隨機(jī)森林參數(shù)調(diào)優(yōu)有相關(guān)介紹)
2斋射、隨機(jī)森林
九、集成學(xué)習(xí)方法——隨機(jī)森林
1但荤、集成學(xué)習(xí)
集成學(xué)習(xí)童工建立幾個(gè)模型組合來解決單一預(yù)測(cè)問題罗岖。它的工作原理是生成多個(gè)分類器/模型,各自獨(dú)立的學(xué)習(xí)和做出預(yù)測(cè)腹躁,這些預(yù)測(cè)最后結(jié)合成單預(yù)測(cè)桑包,因此優(yōu)于任何一個(gè)單分類做出來的預(yù)測(cè)。
2纺非、隨機(jī)森林
在機(jī)器學(xué)習(xí)中哑了,隨機(jī)森林是一個(gè)包含多個(gè)決策樹的分類器,并且其輸出的類別是由個(gè)別樹輸出的類別的眾數(shù)而定烧颖。
- 隨機(jī)森林建立多個(gè)決策樹的過程(N個(gè)樣本弱左,M個(gè)特征)
1、隨機(jī)在N個(gè)樣本當(dāng)中選擇一個(gè)樣本炕淮,重復(fù)N次拆火,樣本有可能重復(fù)
2、隨機(jī)在M個(gè)特征當(dāng)中選出m個(gè)特征(m<<M)建立決策樹
3涂圆、采用bootstrap抽樣(隨機(jī)有放回的抽樣)
為什么要隨機(jī)抽樣訓(xùn)練集:
如果不隨機(jī)抽樣们镜,每棵樹的訓(xùn)練集都一樣,那么最終訓(xùn)練出的樹分類結(jié)果也是完全一樣的
為什么要有放回的抽樣:
如果不是有放回的抽樣润歉,那么每棵樹的訓(xùn)練樣本都是不同的模狭,都是沒有交集的,這樣每棵樹都是"有偏的"踩衩,都是絕對(duì)"片面的"(當(dāng)然這樣說可能不對(duì))胞皱,也就是說每棵樹訓(xùn)練出來都是有很大差異的邪意,而隨機(jī)森林最后分類取決于多棵樹(弱分類器)的投票表決。
3反砌、隨機(jī)森林分類器的API
由于隨機(jī)森林API的參數(shù)眾多雾鬼,這里我們就選擇部分常用的進(jìn)行介紹:
sklearn.ensemble.RandomForestClassifier(n_estimators=10,criterion='gini',max_depth=None,bootstrap=True,random_state=None)
參數(shù) | 說明 |
---|---|
n_estimators | integer,optional(default=10)森林里的樹木數(shù)量120,200宴树,300策菜,500,800酒贬,1200 |
criteria | string,可選(default="gini")分割特征的測(cè)量方法 |
max_depth | integer或None,可選(默認(rèn)=無)樹的最大深度5又憨,8,15锭吨,25蠢莺,30 |
max_features | 每個(gè)決策樹的最大特征數(shù)量,若max_features="auto"或者"sqrt",則'max_features=sqrt(n_features),若max_features="log2"則'max_features=log2(n_features)'零如,若max_features="None"則'max_features=n_features' |
bootstrap | boolean,optional(default = True)是否在構(gòu)建樹時(shí)使用放回抽樣 |
4躏将、案例分析
這里補(bǔ)充一點(diǎn),決策樹可視化問題考蕾,通過sklearn.tree.export_graphviz()
可以將樹導(dǎo)出成DOT格式祸憋,然后使用graphviz
工具可以將dot格式轉(zhuǎn)換成png或者jpg格式進(jìn)行查看dot -Tpng tree.dot -o tree.png
import pandas as pd
from sklearn.feature_extraction import DictVectorizer
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.tree import DecisionTreeClassifier,export_graphviz
def Decision():
"""
決策樹預(yù)測(cè)泰坦尼克生死
:return:
"""
#讀取數(shù)據(jù)
data = pd.read_csv('../../數(shù)據(jù)集/機(jī)器學(xué)習(xí)/分類算法/Titanic/titanic.csv')
# print(data.columns.values)
#處理數(shù)據(jù),找出特征值和目標(biāo)值
x = data.loc[:,['sex','age','pclass']]
y = data.loc[:,['survived']]
#有缺失值肖卧,處理缺失值蚯窥,平均值填充
x['age'].fillna(x['age'].mean(),inplace = True)
#劃分訓(xùn)練集和測(cè)試集
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.25)
#進(jìn)行字典特征的抽取,特征->類別->one_hot編碼(特征里面是類別,值的類型都不同塞帐,要進(jìn)行one_hot編碼)
dict = DictVectorizer(sparse=False)
x_train = dict.fit_transform(x_train.to_dict(orient="records"))
x_test = dict.transform(x_test.to_dict(orient="records"))
# 利用決策樹進(jìn)行分類
dec = DecisionTreeClassifier(max_depth=5)
dec.fit(x_train,y_train)
#預(yù)測(cè)準(zhǔn)確率
print("準(zhǔn)確率為:",dec.score(x_test,y_test))
print(dict.get_feature_names())
#導(dǎo)出樹的結(jié)構(gòu)
export_graphviz(dec,out_file='../../數(shù)據(jù)集/機(jī)器學(xué)習(xí)/分類算法/Titanic/tree.dot',feature_names=['年齡','pclass','女性','男性'])
return None
if __name__ == "__main__":
Decision()
我們運(yùn)行一下之后拦赠,會(huì)在對(duì)應(yīng)的目錄下生成tree.dot
graphviz
https://graphviz.gitlab.io/_pages/Download/Download_windows.html這種格式都可以,安裝完后添加到系統(tǒng)變量牌里,windows添加系統(tǒng)變臉我就不說了颊咬,直接把目錄加載到bin目錄下务甥,能看到dot.exe那個(gè)文件路徑牡辽。添加到系統(tǒng)變量中后,打開dos命令行敞临,輸入
最后我們進(jìn)入tree.dot的文件中,打開dos命令行輸入挺尿,
這時(shí)文件下就會(huì)多出一個(gè)tree.png的圖片奏黑,我們打開就可以看到了炊邦。
接下來我們進(jìn)行決策樹的演練熟史,
import pandas as pd
from sklearn.feature_extraction import DictVectorizer
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.tree import DecisionTreeClassifier,export_graphviz
from sklearn.ensemble import RandomForestClassifier
def Decision():
"""
決策樹預(yù)測(cè)泰坦尼克生死
:return:
"""
#讀取數(shù)據(jù)
data = pd.read_csv('../../數(shù)據(jù)集/機(jī)器學(xué)習(xí)/分類算法/Titanic/titanic.csv')
# print(data.columns.values)
#處理數(shù)據(jù)馁害,找出特征值和目標(biāo)值
x = data.loc[:,['sex','age','pclass']]
y = data.loc[:,['survived']]
#有缺失值,處理缺失值蹂匹,平均值填充
x['age'].fillna(x['age'].mean(),inplace = True)
#劃分訓(xùn)練集和測(cè)試集
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.25)
#進(jìn)行字典特征的抽取,特征->類別->one_hot編碼(特征里面是類別碘菜,值的類型都不同,要進(jìn)行one_hot編碼)
dict = DictVectorizer(sparse=False)
x_train = dict.fit_transform(x_train.to_dict(orient="records"))
x_test = dict.transform(x_test.to_dict(orient="records"))
# 利用決策樹進(jìn)行分類
# dec = DecisionTreeClassifier(max_depth=5)
#
# dec.fit(x_train,y_train)
#
# #預(yù)測(cè)準(zhǔn)確率
# print("準(zhǔn)確率為:",dec.score(x_test,y_test))
# print(dict.get_feature_names())
#
# #導(dǎo)出樹的結(jié)構(gòu)
# export_graphviz(dec,out_file='../../數(shù)據(jù)集/機(jī)器學(xué)習(xí)/分類算法/Titanic/tree.dot',feature_names=['年齡','pclass','女性','男性'])
#隨機(jī)森林預(yù)測(cè)分類(超參數(shù)調(diào)優(yōu))
rf = RandomForestClassifier()
param = {"n_estimators":[120,200,300,500,800],"max_depth":[5,8,15,25,30]}
#網(wǎng)格搜索與交叉驗(yàn)證
gc = GridSearchCV(rf,param_grid=param,cv=5)
gc.fit(x_train,y_train)
#輸出準(zhǔn)確率
print("準(zhǔn)確率為:",gc.score(x_test,y_test))
print("選擇最好的模型是:",gc.best_estimator_)
print("每次交叉驗(yàn)證的結(jié)果",gc.cv_results_)
return None
if __name__ == "__main__":
Decision()
最后得出當(dāng) n_estimators=500,max_depth=25模型最好限寞。
十忍啸、隨機(jī)森林算法的優(yōu)點(diǎn)
這里提一下,隨機(jī)森林算法幾乎沒有缺點(diǎn)履植,唯一的缺點(diǎn)是參數(shù)的選取
- 在當(dāng)前所有算法中计雌,具有極好的準(zhǔn)確率
- 能夠有效地運(yùn)行在大數(shù)據(jù)集上
- 能夠處理具有高維特征的輸入樣本,而且不需要降維
- 能夠評(píng)估各個(gè)特征在分類問題上的重要性
隨機(jī)森林的用法到這里就結(jié)束玫霎,有不明白的地方可以私信我凿滤。歡迎一起學(xué)習(xí),一起進(jìn)步鼠渺。
參考鏈接
1.《統(tǒng)計(jì)學(xué)習(xí)方法》鸭巴,李航,清華大學(xué)出版社
2.https://blog.csdn.net/oxuzhenyi/article/details/76427704
3.http://www.reibang.com/p/52b86c774b0b
4.https://blog.csdn.net/qq_36523839/article/details/80707678
5.b站視頻講解(up主:藍(lán)亞之舟)