隨機森林在大數(shù)據(jù)運用中非常的常見,它在預(yù)測和回歸上相比于SVM,多元線性回歸,邏輯回歸,多項式回歸這些,有著比較好的魯棒性。
隨機森林是一個用隨機方式建立的,包含多個決策樹的分類器。其輸出的類別是由各個樹輸出的類別的眾數(shù)而定。
優(yōu)點:
- 處理高緯度的數(shù)據(jù),并且不用做特征選擇,當然也可以使用隨機森林做特征篩選。
- 模型泛化能力強
- 對不平衡數(shù)據(jù)集來說,可以平衡誤差。
- 對缺失值,異常值不敏感。
缺點:
- 當數(shù)據(jù)噪聲比較大時,會產(chǎn)生過擬合現(xiàn)象。
- 對不同取值的屬性的數(shù)據(jù),取值劃分較多的屬性會對隨機森林產(chǎn)生更大的影響。
廢話不多說,直接上干貨
隨機森林的代碼的基本實現(xiàn)
分類模型
from sklearn.ensemble import RandomForestClassifier
#模型訓(xùn)練
forest = RandomForestClassifier()
forest.fit(x_train.values, y_train.values) #訓(xùn)練集和訓(xùn)練集標簽
#模型評估
score = forest.score(x_test, y_test)
print(score) #這里的score代表的acc,精確率
#模型預(yù)測
pre = forest.predict(x_test)
print(pre)
#模型預(yù)測--輸出概率值
pre_p = forest.predict_proba(x_test)
print(pre_p)
#計算模型運行的時間
import time
start = time.time()
end = time.time()
end-start
同時對于分類問題,我們常常需要用到的指標如混淆矩陣,準確率,精準率,召回率,F(xiàn)1指數(shù)等等。
下面為分類模型的評估指標計算方法
#分類模型的評估指標
from sklearn import metrics
import seaborn as sns
import matplotlib.pyplot as plt
class ClassEval():
def __init__(self, pre,y_test):
self.pre = pre
self.y_test = y_test
self.C2 = None
'''計算混淆矩陣'''
def confusion_matrix(self):
self.C2 = metrics.confusion_matrix(self.y_test,self.pre, labels=[0,1])
return self.C2
'''繪制混淆矩陣熱圖'''
def C2_heatmap(self):
self.confusion_matrix()
#繪圖
sns.set()
f, ax = plt.subplots(figsize=(8, 7))
TX = sns.heatmap(self.C2, annot=True, ax=ax, cmap="Spectral_r", fmt=".20g") # 熱力圖
#標題設(shè)置
ax.set_title("Confusion Matrix")
ax.set_xlabel("Predict")
ax.set_ylabel("Answer")
print("混淆矩陣")
'''計算準確率'''
def get_acc(self):
self.confusion_matrix()
print(type(self.C2))
#計算
acc = np.trace(self.C2)/self.C2.sum()
return acc
'''計算精準率'''
def get_precision(self):
self.confusion_matrix()
Precision = []
i = 0
for row in self.C2:
TP = row[i]
TP_FP = 0
for col in row:
TP_FP += col
Precision.append(TP/TP_FP)
i+=1
return Precision;
'''計算召回率'''
def get_Recall(self):
self.confusion_matrix()
Recall = []
i = 0
TP_FN = np.sum(self.C2, axis=0)
for row in self.C2:
TP = row[i]
Recall.append(TP/TP_FN[i])
i+=1
return Recall
'''計算F1指數(shù)'''
def get_F1(self):
self.confusion_matrix()
Precision = self.get_precision()
Recall = self.get_Recall()
F1 = []
for i in range(len(Precision)):
F1.append(2*Precision[i]*Recall[i] / (Precision[i] + Recall[i]))
return F1
'''計算kappa系數(shù)'''
def get_kappa(self):
self.confusion_matrix()
kappa = metrics.cohen_kappa_score(np.array(self.predict_label_list).astype(np.int16),np.array(self.answer_label_list).astype(np.int16))
return kappa
RF_data = ClassEval(pre, y_test.values)
# RF_data.C2_heatmap()
print("精確度",RF_data.get_acc())
print("精準率",RF_data.get_precision())
print("召回率",RF_data.get_Recall())
print("F1值",RF_data.get_F1())
回歸模型
from sklearn.ensemble import RandomForestRegressor
#訓(xùn)練模型
forest = RandomForestRegressor()
forest.fit(x_train.values, y_train.values) #訓(xùn)練集和訓(xùn)練集標簽
#模型評估
score = forest.score(x_test, y_test)
print(score) #這里的score代表的R2分數(shù)
#模型預(yù)測
pre = forest.predict(x_test)
print(pre)
#計算模型運行的時間
import time
start = time.time()
end = time.time()
end-start
回歸模型的評價指標結(jié)果如下
MSE:均方誤差,觀測值與真值偏差的平方和,反應(yīng)預(yù)測結(jié)果的精確度。
RMSE:MSE的算術(shù)平方根,用來衡量觀測值和真值之間的偏差。(開根號之后,誤差的結(jié)果就與真值在同一個級別)
MAE:平均絕對誤差,能更好地反映預(yù)測值誤差的實際情況
R2:介于0-1之間,越接近1,回歸擬合效果越好
MSE計算簡便,但MAE對異常點有更好的魯棒性。
MSE與MAE各自的優(yōu)缺點
-
MSE對誤差取了平方(令e=真實值-預(yù)測值),因此若e>1,則MSE會進一步增大誤差。如果數(shù)據(jù)中存在異常點,那么e值就會很大,而e則會遠大于|e|。因此,相對于使用MAE計算損失,使用MSE的模型會賦予異常點更大的權(quán)重。在第二個例子中,用RMSE計算損失的模型會以犧牲了其他樣本的誤差為代價,朝著減小異常點誤差的方向更新。然而這就會降低模型的整體性能。如果訓(xùn)練數(shù)據(jù)被異常點所污染,那么MAE損失就更好用(比如,在訓(xùn)練數(shù)據(jù)中存在大量錯誤的反例和正例標記,但是在測試集中沒有這個問題)。
-
直觀上可以這樣理解:如果我們最小化MSE來對所有的樣本點只給出一個預(yù)測值,那么這個值一定是所有目標值的平均值。但如果是最小化MAE,那么這個值,則會是所有樣本點目標值的中位數(shù)。眾所周知,對異常值而言,中位數(shù)比均值更加魯棒,因此MAE對于異常值也比MSE更穩(wěn)定。
-
MAE存在一個嚴重的問題(特別是對于神經(jīng)網(wǎng)絡(luò)):更新的梯度始終相同,也就是說,即使對于很小的損失值,梯度也很大。這樣不利于模型的學(xué)習(xí)。為了解決這個缺陷,我們可以使用變化的學(xué)習(xí)率,在損失接近最小值時降低學(xué)習(xí)率。而MSE在這種情況下的表現(xiàn)就很好,即便使用固定的學(xué)習(xí)率也可以有效收斂。MSE損失的梯度隨損失增大而增大,而損失趨于0時則會減小。這使得在訓(xùn)練結(jié)束時,使用MSE模型的結(jié)果會更精確。
MSE和MAE的選擇
如果異常點代表在商業(yè)中很重要的異常情況,并且需要被檢測出來,則應(yīng)選用MSE損失函數(shù)。相反,如果只把異常值當作受損數(shù)據(jù),則應(yīng)選用MAE損失函數(shù)??偟膩碚f,處理異常點時,MAE損失函數(shù)更穩(wěn)定,但它的導(dǎo)數(shù)不連續(xù),因此求解效率較低。MSE損失函數(shù)對異常點更敏感,但通過令其導(dǎo)數(shù)為0,可以得到更穩(wěn)定的封閉解。
from sklearn.metrics import mean_squared_error #MSE
from sklearn.metrics import mean_absolute_error #MAE
from sklearn.metrics import r2_score#R2
import numpy as np
R2 = r2_score(y_test,pre) #真實數(shù)據(jù)和預(yù)測數(shù)據(jù)
MSE = mean_squared_error(y_test,pre)
MAE = mean_absolute_error(y_test,pre)
RMSE = np.sqrt(MSE)
隨機森林的隨機搜索調(diào)優(yōu)
可以通過get_params()
函數(shù)來得到隨機森林的各項參數(shù)
- n_esimators:要使用的樹的數(shù)量
- max_feauters:每個節(jié)點拆分時要使用的特性數(shù)量
- max_depth:每棵樹上的葉子數(shù)量
- min_samples_split:分裂內(nèi)部節(jié)點所需的最小樣本數(shù)
- min_samples_leaf:每個葉子中的最小樣本數(shù)量
- bootstrap:取樣方法,是否替換。
Scikit-learn提供RandomizedSearchCV類實現(xiàn)隨機搜索。它需要兩個參數(shù)來建立:一個估計器和超參數(shù)的可能值集,稱為參數(shù)網(wǎng)格或空間。讓我們?yōu)槲覀兊碾S機森林模型定義這個參數(shù)網(wǎng)格:
from sklearn.model_selection import RandomizedSearchCV
#設(shè)置各類參數(shù)的范圍
n_estimators = np.arange(100, 2000, step=100) #從100,2000,步長為100
max_features = ["auto", "sqrt", "log2"] #max_features的幾種選擇
max_depth = list(np.arange(10, 100, step=10)) + [None] #深度計算
min_samples_split = np.arange(2, 10, step=2) #最小分割
min_samples_leaf = [1, 2, 4] #最小葉子
bootstrap = [True, False]
param_grid = {
"n_estimators": n_estimators,
"max_features": max_features,
"max_depth": max_depth,
"min_samples_split": min_samples_split,
"min_samples_leaf": min_samples_leaf,
"bootstrap": bootstrap,
}
#隨機參數(shù)調(diào)優(yōu)
forest = RandomForestRegressor()
'''
n_iter參數(shù),控制我們在搜索中允許的超參數(shù)組合的隨機選擇的迭代次數(shù)。
cv:同時也表示三折交叉驗證
scoring:評分標準
n_jobs=-1:表示使用機器上的所有內(nèi)核
'''
random_cv = RandomizedSearchCV(
forest, param_grid, n_iter=100, cv=3, scoring="r2", n_jobs=-1
)
random_cv.fit(X, y)
print("Best params:\n")
print(random_cv.best_params_)
雖然你用了各種調(diào)優(yōu)方法,但是你同樣也需要表達。你需要將你的調(diào)優(yōu)過程可視化
隨機森林的網(wǎng)格搜索調(diào)優(yōu)
相比于隨機搜索,網(wǎng)格搜索則類似與窮舉各種可能。
有13680個可能的超參數(shù)組合和3倍CV, GridSearchCV將必須適合隨機森林41040次。使用RandomizedGridSearchCV,我們得到了相當好的分數(shù),并且只需要100 * 3 = 300 次訓(xùn)練。
new_params = {
"n_estimators": [650, 700, 750, 800, 850, 900, 950, 1000],
"max_features": ['sqrt'],
"max_depth": [10, 15, 20, 25, 30],
"min_samples_split": [2, 4, 6],
"min_samples_leaf": [1, 2],
"bootstrap": [False],
}
from sklearn.model_selection import GridSearchCV
forest = RandomForestRegressor()
'''
這里我們不需要指定評分和CV,這里采用了默認設(shè)置
'''
grid_cv = GridSearchCV(forest, new_params, n_jobs=-1)
grid_cv.fit(X, y)
print('Best params:\n')
print(grid_cv.best_params_, '\n')
當您在實踐中使用需要大量計算的模型時,最好得到隨機搜索的結(jié)果,并在更小的范圍內(nèi)在網(wǎng)格搜索中驗證它們。
隨機森林的k折交叉驗證
把數(shù)據(jù)平均分成k等份,每次實驗?zāi)靡环葑鰷y試,其余用做訓(xùn)練。
因此你訓(xùn)練出來的模型也是k個,需要實驗k次求平均值。
from sklearn.model_selection import KFold
import pandas as pd
import numpy as np
#數(shù)據(jù)分割
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)
#轉(zhuǎn)成numpy格式
x_train = np.array(x_train)
y_train = np.array(y_train)
#這里的k表示進行幾折交叉驗證
k = 2
kfolder = KFold(n_splits=k, shuffle=True,random_state=0)
kfold = kfolder.split(x_train, y_train)
for train_index, val_index in kfold:
k_x_train = x_train[train_index] #訓(xùn)練集
k_y_train = y_train[train_index] #測試集標簽
k_x_vali = x_train[val_index] #驗證集
k_y_vali = y_train[val_index] #驗證集標簽
forest = RandomForestRegressor() #回歸采用平均值
#forest = RandomForestClassifier() #分類采用投票法
forest.fit(k_x_train, k_y_train) #訓(xùn)練集和訓(xùn)練集標簽
score = forest.score(x_test, y_test)
print(score) #這里的score代表的acc,精確率
這里只是一個簡單的實現(xiàn),最后預(yù)測的結(jié)果的融合,需要你們自己靈活組合,可以采用平均值,也可以采用堆疊法等
隨機森林特征篩選
主要就是可視化特征的重要程度,但是由于隨機森林對不同取值的屬性的數(shù)據(jù),取值劃分較多的屬性會對隨機森林產(chǎn)生更大的影響。
建議采用至少兩種機器學(xué)習(xí)方法進行特征篩選,在通過相關(guān)性熱圖,預(yù)測指標去判斷最后選擇那種模型作為特征篩選模型
# 將訓(xùn)練好的模型提取其特征的重要程度
import_level = model.feature_importances_ #這個方法可以調(diào)取關(guān)于特征重要程度
# 特征程度的顯示
x_columns = data.columns[1:]
index = np.argsort(import_level)[::-1]
for each in range(x.shape[1]):
print('The important level of '+ x_columns[each]+ ': '+ str(import_level[index[each]]))
如果特征較多,建議繪制折線圖,如果特征適量,那肯定是柱狀圖更加清晰文章來源:http://www.zghlxwxcb.cn/news/detail-782635.html
柱狀圖文章來源地址http://www.zghlxwxcb.cn/news/detail-782635.html
#柱狀圖可視化
plt.figure(figsize=(10,6))
plt.title('title',fontsize = 18)
plt.ylabel('import level',fontsize = 15,rotation = 90)
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
for i in range(x_columns.shape[0]):
plt.bar(i,import_level[index[i]],color = 'orange',align = 'center')
plt.xticks(np.arange(x_columns.shape[0]),x_columns,rotation = 90,fontsize = 15)
到了這里,關(guān)于python大數(shù)據(jù)之隨機森林(回歸與分類)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!