隨機森林是一種元估計量,它適合數據集各個子樣本上的許多決策樹分類器,並使用平均數來提高預測准確性和控制過度擬合。子樣本大小由max_samples參數bootstrap=True (default)控制,否則整個數據集用於構建每棵樹
隨機森林優勢
- 隨機森林算法幾乎不需要輸入的准備。它們不需要測算就能夠處理二分特征、分類特征、數值特征的數據。隨機森林算法能完成隱含特征的選擇,並且提供一個很好的特征重要度的選擇指標。
- 隨機森林算法訓練速度快。性能優化過程剛好又提高了模型的准確性,這種精彩表現並不常有,反之亦然。這種旨在多樣化子樹的子設定隨機特征,同時也是一種突出的性能優化!調低給定任意節點的特征划分,能讓你簡單的處理帶有上千屬性的數據集。(如果數據集有很多行的話,這種方法同樣的也可以適用於行采樣)
- 隨機森林算法很難被打敗。針對任何給定的數據集,盡管你常能找到一個優於它的模型(比較典型的是神經網絡或者一些增益算法 boosting algorithm),但這類算法肯定不多,而且通常建這樣的模型並調試好要比隨機森林算法模型要耗時的更多。這也是為何隨機森林算法作為基准模型表現出色的原因。
- 建立一個差勁的隨機森林模型真的很難!因為隨機森林算法對指定使用的超參數(hyper-parameters )並不十分敏感。為了要得到一個合適的模型,它們不需要做很多調整。只需使用大量的樹,模型就不會產生很多偏差。大多數的隨機森林算法的實現方法的參數設置初始值也都是合理的。
- 通用性。隨機森林算法可以應用於很多類別的模型任務。它們可以很好的處理回歸問題,也能對分類問題應付自如(甚至可以產生合適的標准概率值)。雖然我從沒親自嘗試,但它們還可以用於聚類 分析問題。
Extra trees,Extremely Randomized Trees,指極度隨機樹,和隨機森林區別是:
1、隨機森林應用的是Bagging模型,而ET是使用所有的訓練樣本得到每棵決策樹,也就是每棵決策樹應用的是相同的全部訓練樣本;
2、隨機森林是在一個隨機子集內得到最佳分叉屬性,而ET是完全隨機的得到分叉值,從而實現對決策樹進行分叉的。
訓練隨機森林時,建議使用cross_validated(交叉驗證),把數據n等份,每次取其中一份當驗證集,其余數據訓練隨機森林,並用於預測測試集。最終得到n個結果,並平均得到最終結果
class sklearn.ensemble.RandomForestClassifier(n_estimators=100, *, criterion='gini', max_depth=None, min_samples_split=2,
min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0,
min_impurity_split=None, bootstrap=True, oob_score=False, n_jobs=None, random_state=None, verbose=0,
warm_start=False, class_weight=None, ccp_alpha=0.0, max_samples=None)
參數詳解:
- n_estimators:森林中決策樹的數量。默認100
- criterion:分裂節點所用的標准,可選“gini”, “entropy”,默認“gini”。
- max_depth:樹的最大深度。如果為None,則將節點展開,直到所有葉子都是純凈的(只有一個類),或者直到所有葉子都包含少於min_samples_split個樣本。默認是None。
- min_samples_split:拆分內部節點所需的最少樣本數:如果為int,則將min_samples_split視為最小值。如果為float,則min_samples_split是一個分數,而ceil(min_samples_split * n_samples)是每個拆分的最小樣本數。默認是2。
- min_samples_leaf:在葉節點處需要的最小樣本數。僅在任何深度的分割點在左分支和右分支中的每個分支上至少留下min_samples_leaf個訓練樣本時,才考慮。這可能具有平滑模型的效果,尤其是在回歸中。如果為int,則將min_samples_leaf視為最小值。如果為float,則min_samples_leaf是分數,而ceil(min_samples_leaf * n_samples)是每個節點的最小樣本數。默認是1。
- min_weight_fraction_leaf:在所有葉節點處(所有輸入樣本)的權重總和中的最小加權分數。如果未提供sample_weight,則樣本的權重相等。
- max_features:尋找最佳分割時要考慮的特征數量:如果為int,則在每個拆分中考慮max_features個特征。如果為float,則max_features是一個分數,並在每次拆分時考慮int(max_features * n_features)個特征。如果為“auto”,則max_features = sqrt(n_features)。如果為“ sqrt”,則max_features = sqrt(n_features)。如果為“ log2”,則max_features = log2(n_features)。如果為None,則max_features = n_features。注意:在找到至少一個有效的節點樣本分區之前,分割的搜索不會停止,即使它需要有效檢查多個max_features功能也是如此。
- max_leaf_nodes:最大葉子節點數,整數,默認為None
- min_impurity_decrease:如果分裂指標的減少量大於該值,則進行分裂。
- min_impurity_split:決策樹生長的最小純凈度。默認是0。自版本0.19起不推薦使用:不推薦使用min_impurity_split,而建議使用0.19中的min_impurity_decrease。min_impurity_split的默認值在0.23中已從1e-7更改為0,並將在0.25中刪除。
- bootstrap:是否進行bootstrap操作,bool。默認True。如果bootstrap==True,將每次有放回地隨機選取樣本,只有在extra-trees中,bootstrap=False
- oob_score:是否使用袋外樣本來估計泛化精度。默認False。
- n_jobs:並行計算數。默認是None。
- random_state:控制bootstrap的隨機性以及選擇樣本的隨機性。
- verbose:在擬合和預測時控制詳細程度。默認是0。
- warm_start:不常用
- class_weight:每個類的權重,可以用字典的形式傳入{class_label: weight}。如果選擇了“balanced”,則輸入的權重為n_samples / (n_classes * np.bincount(y))。
- ccp_alpha:將選擇成本復雜度最大且小於ccp_alpha的子樹。默認情況下,不執行修剪。
- max_samples:如果bootstrap為True,則從X抽取以訓練每個基本分類器的樣本數。如果為None(默認),則抽取X.shape [0]樣本。如果為int,則抽取max_samples樣本。如果為float,則抽取max_samples * X.shape [0]個樣本。因此,max_samples應該在(0,1)中。是0.22版中的新功能。
最主要的兩個參數是n_estimators和max_features,n_estimators理論上是越大越好,但是計算時間也相應增長。所以,並不是取得越大就會越好,預測效果最好的將會出現在合理的樹個數;max_features每個決策樹在隨機選擇的這max_features特征里找到某個“最佳”特征,使得模型在該特征的某個值上分裂之后得到的收益最大化。max_features越少,方差就會減少,但同時偏差就會增加。如果是回歸問題,則max_features=n_features,如果是分類問題,則max_features=sqrt(n_features),其中,n_features 是輸入特征數
屬性:
base_estimator_:使用的基本分類器
estimators_:子分類器的集合。
classes_:類標簽(單輸出問題)或類標簽數組的列表(多輸出問題)。
n_classes_:類數(用於單輸出問題),或包含每個輸出的類數的列表(用於多輸出問題)。
n_features_:執行擬合(fit)時的特征數量。
n_outputs_:執行擬合 (fit) 時的輸出數量。
oob_score_:使用袋外估計獲得的訓練數據集的分數。僅當oob_score為True時,此屬性才存在。
oob_decision_function_:使用訓練集上的實際估計值計算的決策函數。如果n_estimators小,則有可能在引導過程中從未遺漏任何數據點。在這種情況下,oob_decision_function_可能包含NaN。僅當oob_score為True時,此屬性才存在。
方法:
apply(X)將森林中的樹木應用於X,返回葉子索引。
decision_path(X)返回林中的決策路徑。
fit(X,y [,sample_weight])根據訓練集(X,y)建立一個森林樹木。
get_params([深])獲取此估計量的參數。
predict(X)預測X的類。
predict_log_proba(X)預測X的類對數概率。
predict_proba(X)預測X的類概率。
score(X,y [,sample_weight])返回給定測試數據和標簽上的平均准確度。
set_params(**參數)設置此估算器的參數。
fit(x,y)時,x需要是數組或者是系數矩陣,也可以是df 形式
例子:
使用的是泰坦尼克號存活的數據,使用單個決策樹和隨機深林比較效果
import pandas as pd import seaborn as sns #展示一下兩種路徑的寫法 titanic= pd.read_csv("D:\\Users\\Downloads\\《泰坦尼克號數據分析項目數據》\\train.csv", index_col=0) #刪除無關列 titanic.drop(['Ticket','Cabin','Name'],axis=1,inplace=True) #補全年齡缺失值 fillna_titanic=[] for i in titanic.Sex.unique(): update=titanic.loc[titanic.Sex==i].fillna(value={'Age':titanic.Age[titanic.Sex==i].mean()}) fillna_titanic.append(update) titanic=pd.concat(fillna_titanic) #補全登船信息 titanic.fillna(value={'Embarked':titanic.Embarked.mode()[0]},inplace=True) #數值pclass轉化成類型 titanic.Pclass=titanic.Pclass.astype('category') #啞變量處理 dummy=pd.get_dummies(titanic[['Sex','Embarked','Pclass']]) #水平合並titanic和啞變量數據集 titanic=pd.concat([titanic,dummy],axis=1) titanic.drop(['Sex','Embarked','Pclass'],axis=1,inplace=True) #訓練集和測試集的搭建 from sklearn import model_selection #取出所有自變量名稱 predictors=titanic.columns[1:] #將數據拆分為訓練集和測試集,測試集的比例為25% X_train,X_test,y_train,y_test=model_selection.train_test_split(titanic[predictors],titanic.Survived, test_size=0.25,random_state=1234) #使用網格法找出最優越模型參數 from sklearn.model_selection import GridSearchCV from sklearn import tree #預設各參數的不同選項值 max_depth=[2,3,4,5,6] min_samples_split=[2,4,6,8] min_samples_leaf=[2,4,8,10,12] #將各參數的值以字典的形式組織起來 parameters={'max_depth':max_depth,'min_samples_split':min_samples_split,'min_samples_leaf':min_samples_leaf} #網格搜索法,測試不同的參數值,網格搜索用於找到比較適當的參數 grid_dtcateg=GridSearchCV(estimator=tree.DecisionTreeClassifier(),param_grid=parameters,cv=10) #模型擬合 grid_dtcateg.fit(X_train,y_train) #返回最佳組合的參數值 print(grid_dtcateg.best_params_) #單棵決策樹建模 from sklearn import metrics #構建分類決策樹(上面已經找到了最適當的參數,將這參數填寫進去即可) CART_Class=tree.DecisionTreeClassifier(max_depth=3,min_samples_leaf=4,min_samples_split=2) #模型擬合 decision_tree=CART_Class.fit(X_train,y_train) #模型在測試集上的預測 pred=CART_Class.predict(X_test) #模型的准確率 print('模型在測試集的預測准確率為:',metrics.accuracy_score(y_test,pred)) import matplotlib.pyplot as plt y_score=CART_Class.predict_proba(X_test)[:,1] fpr,tpr,threshold=metrics.roc_curve(y_test,y_score) #計算AUC的值 roc_auc=metrics.auc(fpr,tpr) #繪制面積圖 plt.stackplot(fpr,tpr,color='steelblue',alpha=0.5,edgecolor='black') #添加邊際線 plt.plot(fpr,tpr,color='black',lw=1) #添加對角線 plt.plot([0,1],[0,1],color='red',linestyle='-') #添加文本信息 plt.text(0.5,0.3,'ROC curve(area=%0.2f)'%roc_auc) #添加x軸與y軸標簽 plt.xlabel('1-Specificity') plt.ylabel('Sensitivity') #顯示圖形 plt.show() #構建隨機森林,隨機森林可以提高單棵決策樹的預測准確度 from sklearn import ensemble RF_class=ensemble.RandomForestClassifier(n_estimators=200,random_state=1234) #隨機森林的擬合 RF_class.fit(X_train,y_train) #模型在測試集上的預測 RFclass_pred=RF_class.predict(X_test) #模型的准確率 print('模型在測試集的預測准確率為:',metrics.accuracy_score(y_test,RFclass_pred)) #計算繪圖數據 y_score=RF_class.predict_proba(X_test)[:,1] fpr,tpr,threshold=metrics.roc_curve(y_test,y_score) #計算AUC的值 roc_auc=metrics.auc(fpr,tpr) #繪制面積圖 plt.stackplot(fpr,tpr,color='steelblue',alpha=0.5,edgecolor='black') #添加邊際線 plt.plot(fpr,tpr,color='black',lw=1) #添加對角線 plt.plot([0,1],[0,1],color='red',linestyle='-') #添加文本信息 plt.text(0.5,0.3,'ROC curve(area=%0.2f)'%roc_auc) #添加x軸與y軸標簽 plt.xlabel('1-Specificity') plt.ylabel('Sensitivity') #顯示圖形 plt.show()
{'max_depth': 3, 'min_samples_leaf': 4, 'min_samples_split': 2} 模型在測試集的預測准確率為: 0.8295964125560538
模型在測試集的預測准確率為: 0.852017937219731
哪些因素決定着泰坦尼克號上的獲救率呢:
#自變量的重要性程度 importance=RF_class.feature_importances_ #構建序列用於繪圖 Impt_Series=pd.Series(importance,index=X_train.columns) #對序列排序繪圖 Impt_Series.sort_values(ascending=True).plot(kind='barh') plt.show()