您好,登錄后才能下訂單哦!
本文申明:此文為學(xué)習(xí)記錄過(guò)程,中間多處引用大師講義和內(nèi)容。
一、概念
決策樹(shù)(Decision Tree)是一種簡(jiǎn)單但是廣泛使用的分類器。通過(guò)訓(xùn)練數(shù)據(jù)構(gòu)建決策樹(shù),可以高效的對(duì)未知的數(shù)據(jù)進(jìn)行分類。決策數(shù)有兩大優(yōu)點(diǎn):1)決策樹(shù)模型可以讀性好,具有描述性,有助于人工分析;2)效率高,決策樹(shù)只需要一次構(gòu)建,反復(fù)使用,每一次預(yù)測(cè)的最大計(jì)算次數(shù)不超過(guò)決策樹(shù)的深度。
看了一遍概念后,我們先從一個(gè)簡(jiǎn)單的案例開(kāi)始,如下圖我們樣本:
對(duì)于上面的樣本數(shù)據(jù),根據(jù)不同特征值我們最后是選擇是否約會(huì),我們先自定義的一個(gè)決策樹(shù),決策樹(shù)如下圖所示:
對(duì)于上圖中的決策樹(shù),有個(gè)疑問(wèn),就是為什么第一個(gè)選擇是“長(zhǎng)相”這個(gè)特征,我選擇“收入”特征作為第一分類的標(biāo)準(zhǔn)可以嘛?下面我們就對(duì)構(gòu)建決策樹(shù)選擇特征的問(wèn)題進(jìn)行討論;在考慮之前我們要先了解一下相關(guān)的數(shù)學(xué)知識(shí):
信息熵:熵代表信息的不確定性,信息的不確定性越大,熵越大;比如“明天太陽(yáng)從東方升起”這一句話代表的信息我們可以認(rèn)為為0;因?yàn)樘?yáng)從東方升起是個(gè)特定的規(guī)律,我們可以把這個(gè)事件的信息熵約等于0;說(shuō)白了,信息熵和事件發(fā)生的概率成反比:數(shù)學(xué)上把信息熵定義如下:H(X)=H(P1,P2,…,Pn)=-∑P(xi)logP(xi)
互信息:指的是兩個(gè)隨機(jī)變量之間的關(guān)聯(lián)程度,即給定一個(gè)隨機(jī)變量后,另一個(gè)隨機(jī)變量不確定性的削弱程度,因而互信息取值最小為0,意味著給定一個(gè)隨機(jī)變量對(duì)確定一另一個(gè)隨機(jī)變量沒(méi)有關(guān)系,最大取值為隨機(jī)變量的熵,意味著給定一個(gè)隨機(jī)變量,能完全消除另一個(gè)隨機(jī)變量的不確定性
現(xiàn)在我們就把信息熵運(yùn)用到?jīng)Q策樹(shù)特征選擇上,對(duì)于選擇哪個(gè)特征我們按照這個(gè)規(guī)則進(jìn)行“哪個(gè)特征能使信息的確定性最大我們就選擇哪個(gè)特征”;比如上圖的案例中;
第一步:假設(shè)約會(huì)去或不去的的事件為Y,其信息熵為H(Y);
第二步:假設(shè)給定特征的條件下,其條件信息熵分別為H(Y|長(zhǎng)相),H(Y|收入),H(Y|身高)
第三步:分別計(jì)算信息增益(互信息):G(Y,長(zhǎng)相) = I(Y,長(zhǎng)相) = H(Y)-H(Y|長(zhǎng)相) 、G(Y,) = I(Y,長(zhǎng)相) = H(Y)-H(Y|長(zhǎng)相)等
第四部:選擇信息增益最大的特征作為分類特征;因?yàn)樵鲆嫘畔⒋蟮奶卣饕馕吨o定這個(gè)特征,能很大的消除去約會(huì)還是不約會(huì)的不確定性;
第五步:迭代選擇特征即可;
按以上就解決了決策樹(shù)的分類特征選擇問(wèn)題,上面的這種方法就是ID3方法,當(dāng)然還是別的方法如 C4.5;等;
二、決策樹(shù)的過(guò)擬合解決辦法
若決策樹(shù)的度過(guò)深的話會(huì)出現(xiàn)過(guò)擬合現(xiàn)象,對(duì)于決策樹(shù)的過(guò)擬合有二個(gè)方案:
1.剪枝-先剪枝和后剪紙(可以在構(gòu)建決策樹(shù)的時(shí)候通過(guò)指定深度,每個(gè)葉子的樣本數(shù)來(lái)達(dá)到剪枝的作用)
2.隨機(jī)森林 --構(gòu)建大量的決策樹(shù)組成森林來(lái)防止過(guò)擬合;雖然單個(gè)樹(shù)可能存在過(guò)擬合,但通過(guò)廣度的增加就會(huì)消除過(guò)擬合現(xiàn)象
三、隨機(jī)森林
隨機(jī)森林是一個(gè)最近比較火的算法,它有很多的優(yōu)點(diǎn):
隨機(jī)森林顧名思義,是用隨機(jī)的方式建立一個(gè)森林,森林里面有很多的決策樹(shù)組成,隨機(jī)森林的每一棵決策樹(shù)之間是沒(méi)有關(guān)聯(lián)的。在得到森林之后,當(dāng)有一個(gè)新的輸入樣本進(jìn)入的時(shí)候,就讓森林中的每一棵決策樹(shù)分別進(jìn)行一下判斷,看看這個(gè)樣本應(yīng)該屬于哪一類(對(duì)于分類算法),然后看看哪一類被選擇最多,就預(yù)測(cè)這個(gè)樣本為那一類。
上一段決策樹(shù)代碼:
# 花萼長(zhǎng)度、花萼寬度,花瓣長(zhǎng)度,花瓣寬度 iris_feature_E = 'sepal length', 'sepal width', 'petal length', 'petal width' iris_feature = u'花萼長(zhǎng)度', u'花萼寬度', u'花瓣長(zhǎng)度', u'花瓣寬度' iris_class = 'Iris-setosa', 'Iris-versicolor', 'Iris-virginica' if __name__ == "__main__": mpl.rcParams['font.sans-serif'] = [u'SimHei'] mpl.rcParams['axes.unicode_minus'] = False path = '..\\8.Regression\\iris.data' # 數(shù)據(jù)文件路徑 data = pd.read_csv(path, header=None) x = data[range(4)] y = pd.Categorical(data[4]).codes # 為了可視化,僅使用前兩列特征 x = x.iloc[:, :2] x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.7, random_state=1) print y_test.shape # 決策樹(shù)參數(shù)估計(jì) # min_samples_split = 10:如果該結(jié)點(diǎn)包含的樣本數(shù)目大于10,則(有可能)對(duì)其分支 # min_samples_leaf = 10:若將某結(jié)點(diǎn)分支后,得到的每個(gè)子結(jié)點(diǎn)樣本數(shù)目都大于10,則完成分支;否則,不進(jìn)行分支 model = DecisionTreeClassifier(criterion='entropy') model.fit(x_train, y_train) y_test_hat = model.predict(x_test) # 測(cè)試數(shù)據(jù) # 保存 # dot -Tpng my.dot -o my.png # 1、輸出 with open('iris.dot', 'w') as f: tree.export_graphviz(model, out_file=f) # 2、給定文件名 # tree.export_graphviz(model, out_file='iris1.dot') # 3、輸出為pdf格式 dot_data = tree.export_graphviz(model, out_file=None, feature_names=iris_feature_E, class_names=iris_class, filled=True, rounded=True, special_characters=True) graph = pydotplus.graph_from_dot_data(dot_data) graph.write_pdf('iris.pdf') f = open('iris.png', 'wb') f.write(graph.create_png()) f.close() # 畫(huà)圖 N, M = 50, 50 # 橫縱各采樣多少個(gè)值 x1_min, x2_min = x.min() x1_max, x2_max = x.max() t1 = np.linspace(x1_min, x1_max, N) t2 = np.linspace(x2_min, x2_max, M) x1, x2 = np.meshgrid(t1, t2) # 生成網(wǎng)格采樣點(diǎn) x_show = np.stack((x1.flat, x2.flat), axis=1) # 測(cè)試點(diǎn) print x_show.shape # # 無(wú)意義,只是為了湊另外兩個(gè)維度 # # 打開(kāi)該注釋前,確保注釋掉x = x[:, :2] # x3 = np.ones(x1.size) * np.average(x[:, 2]) # x4 = np.ones(x1.size) * np.average(x[:, 3]) # x_test = np.stack((x1.flat, x2.flat, x3, x4), axis=1) # 測(cè)試點(diǎn) cm_light = mpl.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF']) cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b']) y_show_hat = model.predict(x_show) # 預(yù)測(cè)值 print y_show_hat.shape print y_show_hat y_show_hat = y_show_hat.reshape(x1.shape) # 使之與輸入的形狀相同 print y_show_hat plt.figure(facecolor='w') plt.pcolormesh(x1, x2, y_show_hat, cmap=cm_light) # 預(yù)測(cè)值的顯示 plt.scatter(x_test[0], x_test[1], c=y_test.ravel(), edgecolors='k', s=150, zorder=10, cmap=cm_dark, marker='*') # 測(cè)試數(shù)據(jù) plt.scatter(x[0], x[1], c=y.ravel(), edgecolors='k', s=40, cmap=cm_dark) # 全部數(shù)據(jù) plt.xlabel(iris_feature[0], fontsize=15) plt.ylabel(iris_feature[1], fontsize=15) plt.xlim(x1_min, x1_max) plt.ylim(x2_min, x2_max) plt.grid(True) plt.title(u'鳶尾花數(shù)據(jù)的決策樹(shù)分類', fontsize=17) plt.show()
以上就是決策樹(shù)做分類,但決策樹(shù)也可以用來(lái)做回歸,不說(shuō)直接上代碼:
if __name__ == "__main__": N =100 x = np.random.rand(N) *6 -3 x.sort() y = np.sin(x) + np.random.randn(N) *0.05 x = x.reshape(-1,1) print x dt = DecisionTreeRegressor(criterion='mse',max_depth=9) dt.fit(x,y) x_test = np.linspace(-3,3,50).reshape(-1,1) y_hat = dt.predict(x_test) plt.plot(x,y,'r*',ms =5,label='Actual') plt.plot(x_test,y_hat,'g-',linewidth=2,label='predict') plt.legend(loc ='upper left') plt.grid() plt.show() #比較決策樹(shù)的深度影響 depth =[2,4,6,8,10] clr = 'rgbmy' dtr = DecisionTreeRegressor(criterion='mse') plt.plot(x,y,'ko',ms=6,label='Actual') x_test = np.linspace(-3,3,50).reshape(-1,1) for d,c in zip(depth,clr): dtr.set_params(max_depth=d) dtr.fit(x,y) y_hat = dtr.predict(x_test) plt.plot(x_test,y_hat,'-',color=c,linewidth =2,label='Depth=%d' % d) plt.legend(loc='upper left') plt.grid(b =True) plt.show()
不同深度對(duì)回歸的 影響如下圖:
下面上個(gè)隨機(jī)森林代碼
mpl.rcParams['font.sans-serif'] = [u'SimHei'] # 黑體 FangSong/KaiTi mpl.rcParams['axes.unicode_minus'] = False path = 'iris.data' # 數(shù)據(jù)文件路徑 data = pd.read_csv(path, header=None) x_prime = data[range(4)] y = pd.Categorical(data[4]).codes feature_pairs = [[0, 1]] plt.figure(figsize=(10,9),facecolor='#FFFFFF') for i,pair in enumerate(feature_pairs): x = x_prime[pair] clf = RandomForestClassifier(n_estimators=200,criterion='entropy',max_depth=3) clf.fit(x,y.ravel()) N, M =50,50 x1_min,x2_min = x.min() x1_max,x2_max = x.max() t1 = np.linspace(x1_min,x1_max, N) t2 = np.linspace(x2_min,x2_max, M) x1,x2 = np.meshgrid(t1,t2) x_test = np.stack((x1.flat,x2.flat),axis =1) y_hat = clf.predict(x) y = y.reshape(-1) c = np.count_nonzero(y_hat == y) print '特征:',iris_feature[pair[0]],'+',iris_feature[pair[1]] print '\t 預(yù)測(cè)正確數(shù)目:',c cm_light = mpl.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF']) cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b']) y_hat = clf.predict(x_test) y_hat = y_hat.reshape(x1.shape) plt.pcolormesh(x1,x2,y_hat,cmap =cm_light) plt.scatter(x[pair[0]],x[pair[1]],c=y,edgecolors='k',cmap=cm_dark) plt.xlabel(iris_feature[pair[0]],fontsize=12) plt.ylabel(iris_feature[pair[1]], fontsize=14) plt.xlim(x1_min, x1_max) plt.ylim(x2_min, x2_max) plt.grid() plt.tight_layout(2.5) plt.subplots_adjust(top=0.92) plt.suptitle(u'隨機(jī)森林對(duì)鳶尾花數(shù)據(jù)的兩特征組合的分類結(jié)果', fontsize=18) plt.show()
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。