天天看點

機器學習之RandomForest(随機森林算法)

本文主要目的是通過一段及其簡單的小程式來快速學習python 中sklearn的RandomForest這一函數的基本操作和使用,注意不是用python純粹從頭到尾自己建構RandomForest,既然sklearn提供了現成的我們直接拿來用就可以了,當然其原理十分重要,下面最簡單介紹:

內建學習是将多個模型進行組合來解決單一的預測問題。它的原理是生成多個分類器模型,各自獨立地學習并作出預測。

這些預測最後結合起來得到預測結果,是以和單獨分類器的結果相比,結果一樣或更好。

bagging就是一種內建學習用來提高學習算法準确度的方法主要思想:

1.給定一個弱學習算法,和一個訓練集;

2.單個弱學習算法準确率不高;

3.将該學習算法使用多次,得出預測函數序列,進行投票;

4.最後結果準确率将得到提高.
           

随機森林是Bagging的一個拓展變體,是內建學習的一個分支,因為它依靠于決策樹的內建。

更詳細的介紹可以去官網檢視

随機森林有兩種算法(紅字就是主要差別)

RandomForest algorithm :

樣本提取時允許replacement(a bootstrap sample),在随機選取的部分(而不是全部的)features上進行劃分,與原論文的vote方法不同,scikit-learn通過平均每個分類器的預測機率(averaging their probabilistic prediction)來生成最終結果。

Extremely Randomized Trees :

有兩個class,分别處理分類和回歸,預設使用所有樣本,但劃分時features随機選取部分。

随機森林算法既可以應運到分類RandomForestClassifier(随機森林分類)、又可以用于回歸問題RandomForestRegressor(随機森林回歸),下面将分别給與代碼

RandomForestClassifier:

#RandomForestClassifier
import math
import matplotlib as mpl
import warnings
import numpy as np
from sklearn.model_selection import cross_val_score
from sklearn.datasets import make_blobs
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.tree import DecisionTreeClassifier
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
 
#忽略一些版本不相容等警告
warnings.filterwarnings("ignore")
 
#源資料産生具體看https://blog.csdn.net/ichuzhen/article/details/51768934
n_features=2  #每個樣本有幾個屬性或特征
x,y = make_blobs(n_samples=300, n_features=n_features, centers=6)
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=1, train_size=0.7)
 
#核心代碼
#傳統決策樹、随機森林算法、極端随機樹關于差別:https://blog.csdn.net/hanss2/article/details/53525503
#關于其中參數的說明請看http://www.jb51.net/article/131172.htm
clf1 = DecisionTreeClassifier(max_depth=None, min_samples_split=2,random_state=0)
clf2 = RandomForestClassifier(n_estimators=10,max_features=math.sqrt(n_features), max_depth=None,min_samples_split=2, bootstrap=True)
clf3 = ExtraTreesClassifier(n_estimators=10,max_features=math.sqrt(n_features), max_depth=None,min_samples_split=2, bootstrap=False)
 
 
 
'''
#交叉驗證
scores1 = cross_val_score(clf1, x_train, y_train)
scores2 = cross_val_score(clf2, x_train, y_train)
scores3 = cross_val_score(clf3, x_train, y_train)
print('DecisionTreeClassifier交叉驗證準确率為:'+str(scores1.mean()))    
print('RandomForestClassifier交叉驗證準确率為:'+str(scores2.mean()))    
print('ExtraTreesClassifier交叉驗證準确率為:'+str(scores3.mean()))
'''
 
 
 
 
 
clf1.fit(x_train, y_train)
clf2.fit(x_train, y_train)
clf3.fit(x_train, y_train)
 
#區域預測
x1_min, x1_max = x[:, 0].min(), x[:, 0].max()            # 第0列的範圍
x2_min, x2_max = x[:, 1].min(), x[:, 1].max()            # 第1列的範圍
x1, x2 = np.mgrid[x1_min:x1_max:200j, x2_min:x2_max:200j]# 生成網格采樣點行列均為200點
area_smaple_point = np.stack((x1.flat, x2.flat), axis=1) # 将區域劃分為一系列測試點去用學習的模型預測,進而根據預測結果畫區域
area1_predict = clf1.predict(area_smaple_point)          # 所有區域點進行預測
area1_predict = area1_predict.reshape(x1.shape)          # 轉化為和x1一樣的數組因為用plt.pcolormesh(x1, x2, area_flag, cmap=classifier_area_color) 
                                                         # 時x1和x2組成的是200*200矩陣,area_flag要與它對應
 
area2_predict = clf2.predict(area_smaple_point)          
area2_predict = area2_predict.reshape(x1.shape)
 
area3_predict = clf3.predict(area_smaple_point)          
area3_predict = area3_predict.reshape(x1.shape)
 
 
 
mpl.rcParams['font.sans-serif'] = [u'SimHei']            #用來正常顯示中文标簽    
mpl.rcParams['axes.unicode_minus'] = False               #用來正常顯示負号
 
classifier_area_color = mpl.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF'])  #區域顔色
cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b'])                                  #樣本所屬類别顔色
 
 
#繪圖
#第一個子圖
plt.subplot(2,2,1)
 
plt.pcolormesh(x1, x2, area1_predict, cmap=classifier_area_color)                        
plt.scatter(x_train[:,0], x_train[:,1], c=y_train,marker='o', s=50, cmap=cm_dark)    
plt.scatter(x_test[:,0],x_test[:,1], c=y_test,marker='x', s=50, cmap=cm_dark)
 
plt.xlabel('data_x', fontsize=8)  
plt.ylabel('data_y', fontsize=8)
plt.xlim(x1_min, x1_max)  
plt.ylim(x2_min, x2_max)
plt.title(u'DecisionTreeClassifier:傳統決策樹', fontsize=8)
plt.text(x1_max-9, x2_max-2, u'$o---train ; x---test$')
 
 
#第二個子圖
plt.subplot(2,2,2)
 
plt.pcolormesh(x1, x2, area2_predict, cmap=classifier_area_color)                        
plt.scatter(x_train[:,0], x_train[:,1], c=y_train,marker='o', s=50, cmap=cm_dark)    
plt.scatter(x_test[:,0],x_test[:,1], c=y_test,marker='x', s=50, cmap=cm_dark)
 
plt.xlabel('data_x', fontsize=8)  
plt.ylabel('data_y', fontsize=8)
plt.xlim(x1_min, x1_max)  
plt.ylim(x2_min, x2_max)
plt.title(u'RandomForestClassifier:随機森林算法', fontsize=8)
plt.text(x1_max-9,x2_max-2, u'$o---train ; x---test$')
 
 
#第三個子圖
plt.subplot(2,2,3)
 
plt.pcolormesh(x1, x2, area3_predict, cmap=classifier_area_color)                        
plt.scatter(x_train[:,0], x_train[:,1], c=y_train,marker='o', s=50, cmap=cm_dark)    
plt.scatter(x_test[:,0],x_test[:,1], c=y_test,marker='x', s=50, cmap=cm_dark)
 
plt.xlabel('data_x', fontsize=8)  
plt.ylabel('data_y', fontsize=8)
plt.xlim(x1_min, x1_max)  
plt.ylim(x2_min, x2_max)
plt.title(u'ExtraTreesClassifier:極端随機樹', fontsize=8)
plt.text(x1_max-9, x2_max-2, u'$o---train ; x---test$')
 
 
#第四個子圖
plt.subplot(2,2,4)
y=[]
scores1 = cross_val_score(clf1, x_train, y_train)
y.append(scores1.mean())
scores2 = cross_val_score(clf2, x_train, y_train)
y.append(scores2.mean())
scores3 = cross_val_score(clf3, x_train, y_train)
y.append(scores3.mean())
 
x=[0,1,2]
plt.bar(x,y,0.4,color="green")  
plt.xlabel("0--DecisionTreeClassifier;1--RandomForestClassifier;2--ExtraTreesClassifie", fontsize=8)  
plt.ylabel("平均準确率", fontsize=8)
plt.ylim(0.9, 0.99)
plt.title("交叉驗證",fontsize=8)
for a, b in zip(x, y):  
    plt.text(a, b, b, ha='center', va='bottom', fontsize=10)
 
plt.show()
           

運作結果分析:

機器學習之RandomForest(随機森林算法)

RandomForestRegressor:

#随機森林回歸
import matplotlib as mpl
import numpy as np
import warnings 
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import ExtraTreesRegressor
 
#忽略一些版本不相容等警告
warnings.filterwarnings("ignore")
 
#産生心狀坐标
t = np.arange(0,2*np.pi,0.1)
x = 16*np.sin(t)**3
x=x[:, np.newaxis]
y = 13*np.cos(t)-5*np.cos(2*t)-2*np.cos(3*t)-np.cos(4*t)
y[::7]+= 3* (1 - np.random.rand(9))                      #增加噪聲,在每數2個數的時候增加一點噪聲
 
#傳統決策樹線性回歸,随機森林回歸,極端森林回歸
rf1=DecisionTreeRegressor()
rf2=RandomForestRegressor(n_estimators=1000)           #一般來說n_estimators越大越好,運作結果呈現出的兩種結果該值分别是10和1000
rf3=ExtraTreesRegressor()
 
 
#三種算法的預測
y_rf1 =rf1.fit(x,y).predict(x)
y_rf2 =rf2.fit(x,y).predict(x)
y_rf3 =rf3.fit(x,y).predict(x)
 
#為了後面plt.text定位
x1_min, x1_max = x[:].min(), x[:].max()          
x2_min, x2_max = y[:].min(), y[:].max()
 
mpl.rcParams['font.sans-serif'] = [u'SimHei']            #用來正常顯示中文标簽    
mpl.rcParams['axes.unicode_minus'] = False
 
plt.scatter(x, y, color='darkorange', label='data')  
plt.hold('on')
 
plt.plot(x, y_rf1, color='b',  label='DecisionTreeRegressor')  
plt.plot(x, y_rf2, color='g',  label='RandomForestRegressor')  
plt.plot(x, y_rf3, color='r',  label='ExtraTreesRegressor')
 
plt.xlabel('data_x')  
plt.ylabel('data_y')  
plt.title('python_machine-learning_RandomForest(n_estimators=1000)-----心狀學習')  
plt.legend()
plt.text(x1_max-4, x2_max-1, u'$o---Sample-Point$')
plt.show()
           

運作結果分析:

機器學習之RandomForest(随機森林算法)

繼續閱讀