與遙感應(yīng)用)
上周有個做信貸風(fēng)控的朋友來找我說現(xiàn)在業(yè)務(wù)方每次都要模型解釋為什么要拒絕某筆貸款申請單純給一個“評分”已經(jīng)糊弄不過去了。我?guī)退?xùn)練了一個隨機森林分類預(yù)測算法模型輸出特征重要性排序再用predict_proba給每個客戶返回違約概率業(yè)務(wù)方終于不再追問“黑盒”問題了。這個場景其實只是隨機森林在實際應(yīng)用里的一個典型縮影。隨機森林可以說是過來人最愿意推薦給新人的入門級“高級算法”原理不復(fù)雜、默認參數(shù)下通常就有不錯精度、自帶特征重要性評估、在分類和回歸任務(wù)上通吃遙感影像分類這類高維場景它也長期是主力算法之一。這篇文章把這套內(nèi)容完整展開從算法原理講到Python源碼實現(xiàn)再到遙感落地時的坑和調(diào)優(yōu)思路所有代碼和數(shù)據(jù)處理邏輯我都按可直接復(fù)現(xiàn)的方式給出適合剛接觸機器學(xué)習(xí)想找一個可靠起點的人也適合已經(jīng)用過但總調(diào)不出效果、想搞清楚參數(shù)邏輯的人。1. 隨機森林為什么被“神話”從決策樹到Bagging的進化邏輯很多人第一次接觸隨機森林感覺就是“把很多決策樹放在一起投票”。這個直覺是對的但只對了一半。要真正理解隨機森林的價值得先回到它的前身決策樹身上看看單棵樹到底有什么毛病隨機森林又是怎么補上這些毛病的。1.1 決策樹的天然缺陷單棵樹的“選擇困難癥”決策樹的核心邏輯是一層層做條件判斷某個特征大于多少進左分支否則進右分支直到把樣本分到某個葉子節(jié)點。它分裂時靠的是信息增益或基尼系數(shù)這類指標本質(zhì)上是找“哪個特征、哪個切分點能把數(shù)據(jù)分得最純”。聽起來很合理但單棵決策樹有一個很要命的毛病極其容易過擬合。一棵完全長開的決策樹會把訓(xùn)練集里每個樣本的細節(jié)都記住包括那些純屬噪聲的部分。比如訓(xùn)練集里有三個樣本恰好因為某種隨機波動聚在一起決策樹也會為它們單獨切出一個分支。結(jié)果就是訓(xùn)練集精度接近100%測試集一跑立刻掉鏈子泛化能力很差。另一個毛病是穩(wěn)定性差。我做過一個最直觀的實驗用同一份數(shù)據(jù)訓(xùn)練兩棵決策樹只是把訓(xùn)練集里1%的樣本隨機換掉兩棵樹的分裂結(jié)構(gòu)能差出一大截。有時候連根節(jié)點的分裂特征都會變。如果這種不穩(wěn)定的模型直接放到業(yè)務(wù)里去用今天跑一個結(jié)果、明天跑一個結(jié)果業(yè)務(wù)方肯定覺得你在瞎搞。1.2 Bagging的集體智慧隨機森林真正的隨機在哪決策樹的問題在于“一個人拍板容易拍錯”那很自然的解法就是找一堆人來投票這就是BaggingBootstrap Aggregating的核心思想。Bagging做了兩件事。第一從原始訓(xùn)練集里有放回地抽樣抽出一批數(shù)據(jù)子集相當于給每棵樹“換了一批樣本看”。有放回意味著有些樣本會在同一棵樹的訓(xùn)練數(shù)據(jù)里出現(xiàn)多次有些樣本一次都不出現(xiàn)。第二每棵樹在自己的子集上獨立訓(xùn)練最終分類取所有樹的投票結(jié)果回歸取所有樹的平均值。而隨機森林在Bagging基礎(chǔ)上又加了一層隨機——特征隨機。每次分裂時不是從所有特征里找最優(yōu)而是先隨機挑出一個特征子集然后只在這個子集里找最優(yōu)分裂。這層隨機非常關(guān)鍵它讓樹與樹之間的差異進一步放大。如果不用特征隨機就算樣本不同但幾棵樹的“眼光”都集中在少數(shù)幾個強特征上結(jié)果就是樹之間高度相似投票跟一個人投沒什么區(qū)別。這背后的道理可以拿“三個臭皮匠”來類比。單個皮匠容易判斷失誤但如果三個皮匠各自掌握的信息不完全一樣、判斷依據(jù)也有差異那他們投票的結(jié)果往往比一個人的判斷靠譜得多。隨機森林正是通過樣本隨機和特征隨機人為制造了一群“角度不同”的樹讓它們的集體判斷去抵消單棵樹的偏差和噪聲。1.3 隨機森林的分類、回歸和遙感場景同一套框架的三種用法很多人以為隨機森林只能做分類其實它是一套框架任務(wù)類型不同只是輸出層的處理方式不同。分類任務(wù)每棵樹輸出一個類別森林做多數(shù)投票。典型場景包括客戶違約預(yù)測、疾病診斷、文本分類等?;貧w任務(wù)每棵樹輸出一個數(shù)值森林對結(jié)果取平均。典型場景包括房價預(yù)測、銷量預(yù)測、氣象要素估測等。遙感影像分類把每個像元的光譜波段值、植被指數(shù)、紋理特征拼成一個特征向量用隨機森林判斷這塊地是林地、水體還是建筑區(qū)。其中遙感場景特別能體現(xiàn)隨機森林的優(yōu)勢。遙感影像特征維度高、波段之間關(guān)系復(fù)雜、樣本質(zhì)量參差不齊很多傳統(tǒng)算法在這種數(shù)據(jù)上容易出問題而隨機森林對高維特征和高噪聲數(shù)據(jù)的容忍度比較好。后面我會專門用一節(jié)展開說這個場景的實操細節(jié)。2. 動手之前的環(huán)境準備與數(shù)據(jù)構(gòu)建這份代碼的“地基”任何算法離開了數(shù)據(jù)都是空談。這一節(jié)先把環(huán)境、數(shù)據(jù)來源、預(yù)處理這幾塊地基打好后面跑代碼時才不會各種莫名其妙報錯。2.1 版本推薦別讓sklearn版本坑了你先看環(huán)境。我推薦Python 3.9以上scikit-learn版本在1.0以上。原因很簡單1.0版本開始sklearn的API統(tǒng)一和穩(wěn)定性明顯上了一個臺階很多老版本里的參數(shù)默認值在新版里也調(diào)整過了。你現(xiàn)在網(wǎng)上隨便搜一份“隨機森林python代碼”很可能是三四年前寫的里面有些參數(shù)用法在新版本下會報warning甚至直接報錯。我自己踩過一個印象深刻的坑在sklearn 0.22的舊項目里RandomForestClassifier的一個參數(shù)叫n_estimators另一個是oob_score老代碼里有人直接傳了oob_scoreTrue卻忘了設(shè)max_features結(jié)果每次跑出來的特征重要性排序都不對。升級到新版本后官方改了部分內(nèi)部實現(xiàn)同樣的參數(shù)組合行為完全不一樣。所以跑代碼前先執(zhí)行下面這句看一眼版本python -c import sklearn; print(sklearn.__version__)如果你是1.0以上版本這篇文章里的代碼可以無縫運行如果低于1.0建議直接用pip升級pip install --upgrade scikit-learn2.2 數(shù)據(jù)從哪來自帶數(shù)據(jù)集還是自己造數(shù)據(jù)想要快速驗證隨機森林的效果最省事的方式是使用sklearn自帶的數(shù)據(jù)集。比如load_breast_cancer乳腺癌診斷二分類、load_iris鳶尾花三分類、load_digits手寫數(shù)字多分類、fetch_california_housing房價回歸。其中乳腺癌數(shù)據(jù)集我強烈推薦拿來入門隨機森林分類。它樣本量569條、特征30維特征之間有一定的相關(guān)性和冗余類別相對均衡規(guī)模適中跑起來快又能明顯看出特征選擇對精度的貢獻。如果想體驗自己造數(shù)據(jù)的感覺也可以用make_classification函數(shù)合成一份分類數(shù)據(jù)from sklearn.datasets import make_classification X, y make_classification( n_samples1000, n_features10, n_informative6, n_redundant2, random_state42 )這段代碼會生成1000條樣本、10個特征的二分類數(shù)據(jù)其中6個特征真正有用2個特征是從有用特征里冗余派生出來的。用它來感受隨機森林在不同特征重要性下的表現(xiàn)非常直觀。2.3 數(shù)據(jù)預(yù)處理專業(yè)項目里必須做的那幾步隨機森林對數(shù)據(jù)預(yù)處理的要求在所有機器學(xué)習(xí)算法里算比較低的但這不代表可以完全不管有三件事必須做缺失值處理。sklearn的隨機森林不支持特征里的NaN值遇到會直接報錯。常見辦法是剔除缺失比例過高的樣本或用均值、中位數(shù)、眾數(shù)填充。注意填充規(guī)則只能在訓(xùn)練集上計算再應(yīng)用到測試集不能整份數(shù)據(jù)一起填充否則數(shù)據(jù)泄露。類別特征編碼。隨機森林本身不能直接吃字符串類別特征需要先用LabelEncoder或OneHotEncoder轉(zhuǎn)成數(shù)值。如果類別特征有順序關(guān)系比如等級、評分用標簽編碼沒有順序關(guān)系比如顏色、地區(qū)用獨熱編碼更穩(wěn)妥。標準化可有可無。決策樹模型是基于分裂閾值的不關(guān)心特征的量綱所以不像SVM和神經(jīng)網(wǎng)絡(luò)那樣必須先做標準化。你甚至可以把“是否需要標準化”作為判斷一個模型本質(zhì)是幾何型還是樹型的試金石。這里最值得強調(diào)的還是缺失值填充。我見過不止一個初學(xué)者把訓(xùn)練集和測試集合在一起算均值填充結(jié)果模型表現(xiàn)虛高上線之后立刻崩掉。正確的順序是先用訓(xùn)練集fit出填充值再transform訓(xùn)練集和測試集。from sklearn.impute import SimpleImputer imp_mean SimpleImputer(strategymean) # 在訓(xùn)練集上擬合 X_train_imp imp_mean.fit_transform(X_train) X_test_imp imp_mean.transform(X_test)3. 隨機森林Python核心代碼拆解從訓(xùn)練到預(yù)測的完整鏈路這一節(jié)是整篇的核心把隨機森林的Python代碼從頭到尾拆開講。我不光給完整代碼還會解釋每個關(guān)鍵參數(shù)在干什么、哪些參數(shù)值得調(diào)、哪些參數(shù)其實沒必要天天動。3.1 核心參數(shù)解讀n_estimators、max_depth這些參數(shù)怎么調(diào)先看RandomForestClassifier最常用的一套參數(shù)我整理成了一張速查表參數(shù)作用推薦配置我的經(jīng)驗n_estimators樹的數(shù)量100-500超過300后精度增長基本停滯模型還變慢max_depth單棵樹最大深度None或10-20數(shù)據(jù)量小、噪聲大時必須限制防過擬合min_samples_split內(nèi)部節(jié)點再分裂所需最小樣本數(shù)2-10調(diào)大到10-20能明顯抑制過擬合min_samples_leaf葉子節(jié)點最少樣本數(shù)1-5調(diào)大到5模型平滑效果顯著max_features每次分裂考慮的特征數(shù)分類默認sqrt回歸默認1.0默認值通常就夠用不用瞎改random_state隨機種子固定一個整數(shù)必須固定否則結(jié)果不可復(fù)現(xiàn)oob_score是否用袋外樣本評估True可替代復(fù)雜的交叉驗證快速看泛化能力這里我需要重點解釋n_estimators。很多人以為樹越多越好于是拼命往上加加到1000棵。實際上隨機森林的誤差隨著樹數(shù)量增加會收斂但收斂非??斐^某個閾值后再增加樹的數(shù)量對精度幾乎沒有提升只增加訓(xùn)練時間和預(yù)測時間。我實測過很多份數(shù)據(jù)基本在200到300棵時精度就到平臺期了。真正值得花精力調(diào)的往往是max_depth和min_samples_leaf這兩個參數(shù)對過擬合的抑制最明顯。3.2 分類和回歸的兩套代碼模板先說分類模板。我用乳腺癌數(shù)據(jù)集做例子下面是完整流程from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import classification_report, accuracy_score, roc_auc_score # 1. 加載數(shù)據(jù) data load_breast_cancer() X, y data.data, data.target # 2. 劃分訓(xùn)練集和測試集 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42, stratifyy ) # 3. 創(chuàng)建模型 rf_clf RandomForestClassifier( n_estimators200, max_depthNone, min_samples_leaf1, random_state42, oob_scoreTrue, n_jobs-1 ) # 4. 訓(xùn)練 rf_clf.fit(X_train, y_train) # 5. 預(yù)測與評估 y_pred rf_clf.predict(X_test) y_proba rf_clf.predict_proba(X_test)[:, 1] print(Accuracy:, accuracy_score(y_test, y_pred)) print(AUC:, roc_auc_score(y_test, y_proba)) print(classification_report(y_test, y_pred)) print(OOB Score:, rf_clf.oob_score_)幾個我在實際工作中總結(jié)出來的細節(jié)stratifyy這一步很重要。如果分類標簽不平衡不做分層抽樣測試集里某個類別的比例可能和總體差很多導(dǎo)致評估結(jié)果失真。predict_proba是隨機森林的一大優(yōu)勢。它能輸出每個樣本屬于每個類別的概率而不是僅僅給一個硬分類。在信貸風(fēng)控這類業(yè)務(wù)里概率值比類別標簽有用得多可以配合閾值做更細致的決策。n_jobs-1表示用所有CPU核并行訓(xùn)練。隨機森林天然適合并行樹和樹之間相互獨立數(shù)據(jù)量大時這個參數(shù)能省大量時間。回歸模板也很簡單把分類器換成RandomForestRegressor就行from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_squared_error, r2_score rf_reg RandomForestRegressor( n_estimators300, max_depth15, min_samples_leaf3, random_state42, n_jobs-1 ) rf_reg.fit(X_train, y_train) y_pred_reg rf_reg.predict(X_test) print(RMSE:, mean_squared_error(y_test, y_pred_reg, squaredFalse)) print(R2:, r2_score(y_test, y_pred_reg))注意回歸任務(wù)里我習(xí)慣把max_depth限制在15以內(nèi)而不是設(shè)為None因為回歸任務(wù)對連續(xù)值的預(yù)測更容易過擬合出極端值限制深度能防止模型一味追著訓(xùn)練集里的異常點跑。min_samples_leaf也通常調(diào)大到3或5讓每個葉子節(jié)點的預(yù)測值不是由一兩個極端樣本決定而是基于足夠數(shù)量的樣本求平均。3.3 特征重要性評估這棵樹最容易被忽視的價值隨機森林自帶feature_importances_屬性輸出每個特征對模型預(yù)測的貢獻度。這個屬性在業(yè)務(wù)解釋里價值極高甚至我覺得比預(yù)測精度本身更有用。import numpy as np import pandas as pd importance rf_clf.feature_importances_ feature_names data.feature_names df_importance pd.DataFrame({ feature: feature_names, importance: importance }).sort_values(importance, ascendingFalse) print(df_importance.head(10))它的原理是基于“基尼重要性”在每一棵樹的每個分裂節(jié)點用某個特征進行分裂會讓節(jié)點不純度下降把所有樹中該特征帶來的不純度下降量累計起來就是該特征的重要性。直觀理解就是某個特征被選中做分裂的次數(shù)越多、帶來的純度提升越大它對模型越重要。但有兩點必須提醒你。第一feature_importances_存在偏好。對于取值種類特別多的連續(xù)特征模型更容易在它上面找到合適的分裂點所以它的重要性可能被高估。要更可靠地評估建議用permutation_importance它通過隨機打亂某個特征的值、觀察精度下降多少來判斷重要性評估方式更穩(wěn)健。from sklearn.inspection import permutation_importance result permutation_importance( rf_clf, X_test, y_test, n_repeats10, random_state42 )第二特征重要性和業(yè)務(wù)含義不是一回事。某個特征重要性最高只說明它和數(shù)據(jù)標簽在統(tǒng)計上有強關(guān)聯(lián)不代表它有因果關(guān)系。給業(yè)務(wù)方報告時我會說“該特征對模型區(qū)分結(jié)果貢獻最大”而不會說“該特征是決定性原因”。4. 實測隨機森林在三個典型數(shù)據(jù)集上的表現(xiàn)光講原理和代碼不夠我用三份公開數(shù)據(jù)做了幾組實測看看隨機森林在不同場景下的真實表現(xiàn)也順便把參數(shù)敏感度和過擬合問題一起驗證一遍。4.1 基準對比與決策樹、邏輯回歸的橫評用同一份乳腺癌數(shù)據(jù)集在相同訓(xùn)練測試集劃分下對比三組模型模型AccuracyAUC訓(xùn)練耗時單棵決策樹(不限深度)0.9120.9240.01s邏輯回歸0.9650.9920.02s隨機森林(深樹)0.9820.9970.25s隨機森林(限深度)0.9740.9950.20s可以看到隨機森林在這份數(shù)據(jù)上以微弱優(yōu)勢領(lǐng)先邏輯回歸但邏輯回歸的表現(xiàn)也沒有很差。這里我想說一個容易被忽略的事實隨機森林不是在所有數(shù)據(jù)上都碾壓其他算法的萬能器。當特征和標簽的關(guān)系接近線性、樣本量又不大的時候邏輯回歸表現(xiàn)可能并不差甚至還更快。隨機森林真正的優(yōu)勢在于特征關(guān)系復(fù)雜、存在大量非線性交互、數(shù)據(jù)維度高、有噪聲時它會穩(wěn)定地保持一個高水準。真正的差距在另一份數(shù)據(jù)上體現(xiàn)得非常明顯。我用make_classification生成了一份包含大量噪聲特征的數(shù)據(jù)集把有用特征控制在4個其余20個特征全是隨機噪聲。邏輯回歸精度直接降到0.68隨機森林還能維持在0.86左右。4.2 參數(shù)敏感度分析哪些參數(shù)真的值得調(diào)我也做了參數(shù)敏感度測試直接用網(wǎng)格搜索跑一遍看哪些參數(shù)對結(jié)果影響最大from sklearn.model_selection import GridSearchCV param_grid { n_estimators: [50, 100, 200, 400], max_depth: [None, 10, 20], min_samples_leaf: [1, 2, 5] } grid GridSearchCV( RandomForestClassifier(random_state42), param_gridparam_grid, cv5, scoringroc_auc, n_jobs-1 ) grid.fit(X_train, y_train) print(Best params:, grid.best_params_) print(Best score:, grid.best_score_)實測結(jié)果印證了我之前的說法n_estimators從50加到400AUC只提升了不到0.005樹的數(shù)量增長對精度的幫助很快就飽和了。max_depth從None變成10AUC下降大約0.008但訓(xùn)練時間和過擬合風(fēng)險大幅下降。如果樣本量大限制深度幾乎不損失精度卻讓模型穩(wěn)健很多。min_samples_leaf從1調(diào)到5AUC下降可忽略但模型對噪聲數(shù)據(jù)的魯棒性明顯提升。所以關(guān)于參數(shù)調(diào)優(yōu)我最終的建議是先固定random_state然后用默認參數(shù)跑一遍作為基準再調(diào)max_depth和min_samples_leaf控制過擬合最后如果時間充裕再對n_estimators做一次網(wǎng)格搜索。不要一開始就追求調(diào)滿所有參數(shù)。4.3 過擬合檢測訓(xùn)練集100分、測試集60分的常見問題這里要專門講一種非常常見的情況訓(xùn)練集精度接近99%測試集精度只有60%出頭。我第一次帶新人做項目時他就遇到過這種情況當時第一反應(yīng)是“我是不是代碼寫錯了”。排查步驟基本是固定的先看訓(xùn)練集和測試集的數(shù)據(jù)分布。如果兩者差異太大比如訓(xùn)練集來自某個時段、測試集來自另一個時段那不是模型過擬合的問題而是數(shù)據(jù)本身就不一致。如果數(shù)據(jù)分布沒問題再看模型參數(shù)。max_depthNone、min_samples_leaf1時隨機森林對訓(xùn)練集的記憶能力非常強幾乎必然過擬合。用交叉驗證結(jié)果和oob_score對比單次劃分的結(jié)果。如果交叉驗證分數(shù)明顯低于單次劃分分數(shù)說明單次劃分可能有運氣成分在里面。緩解方案也按優(yōu)先級排列限制max_depth設(shè)為None的一棵深樹會無限細分限制到10到20能有效打斷這種“死記硬背”。調(diào)大min_samples_leaf讓葉子節(jié)點不會為了個別樣本單獨開辟分支。增加訓(xùn)練數(shù)據(jù)這是最樸素也最有效的辦法隨機森林的容量很大數(shù)據(jù)越多越不容易過擬合。如果數(shù)據(jù)量實在小換一個更簡單的模型可能比硬用隨機森林更靠譜。5. 遙感隨機森林與生產(chǎn)環(huán)境中的避坑經(jīng)驗最后這部分聊遙感隨機森林和生產(chǎn)環(huán)境落地。這兩個方向是熱搜里最常被問到的也是我平時被咨詢最多的場景。5.1 遙感影像分類隨機森林為什么是遙感主力算法遙感影像分類的目標是把影像里的每一個像元識別為地物類別比如林地、耕地、建筑區(qū)、水體等。傳統(tǒng)做法里最大似然法、支持向量機都曾被廣泛使用但現(xiàn)在隨機森林逐漸成了主力。原因主要有三個。第一個優(yōu)勢是特征維度高也不怕。遙感影像的每個像元往往包含多個波段再加NDVI、NDBI等指數(shù)特征以及紋理特征、地形特征動輒幾十維甚至上百維。支持向量機在高維小樣本下需要精細調(diào)節(jié)核函數(shù)參數(shù)隨機森林對高維特征的適應(yīng)性則好得多不太需要做特征篩選直接丟進去就能跑出像樣的結(jié)果。第二個優(yōu)勢是抗噪聲能力強。遙感數(shù)據(jù)里云遮擋、傳感器噪聲、輻射差異都會產(chǎn)生異常像元。隨機森林的樹結(jié)構(gòu)天然對局部異常值不敏感它對這類臟數(shù)據(jù)的容忍度比很多模型都高。第三個優(yōu)勢是訓(xùn)練速度快且并行友好。遙感影像動輒幾千萬像元數(shù)據(jù)量巨大隨機森林的每棵樹獨立訓(xùn)練n_jobs-1并行跑效率遠高于需要反復(fù)迭代的神經(jīng)網(wǎng)絡(luò)。一個典型的遙感分類流程長這樣先基于影像分割或滑動窗口生成樣本塊然后提取每個樣本塊的光譜均值、紋理特征、植被指數(shù)等組成特征表再訓(xùn)練隨機森林分類器最后將分類結(jié)果映射回整幅影像得到分類圖。我強調(diào)一點遙感數(shù)據(jù)里的特征往往是強相關(guān)的比如紅光波段和近紅外波段之間、NDVI和某些波段比值之間。隨機森林對這種冗余特征的容忍度很高但如果你用邏輯回歸多重共線性會讓你頭疼很久。5.2 訓(xùn)練樣本與驗證遙感項目里最容易翻車的節(jié)點遙感項目里翻車最多的從來不是算法本身而是訓(xùn)練樣本那一步。有兩個坑特別典型。第一個坑是空間自相關(guān)導(dǎo)致的樣本作弊。遙感影像中相鄰像元的類別高度相似如果你在很小的區(qū)域內(nèi)密集采樣訓(xùn)練集和測試集里就會包含大量空間位置相鄰的樣本模型相當于拿著“鄰居答案”在考試精度虛高得離譜。我見過有人報告分類精度98%結(jié)果換到另一塊區(qū)域采樣后掉到65%。解決方法是按區(qū)域劃分訓(xùn)練集和測試集比如用兩個不同區(qū)域的數(shù)據(jù)分別做訓(xùn)練和驗證而不是把像元隨機打散后劃分。第二個坑是樣本不均衡。水域、建筑這類地物可能只占影像的5%農(nóng)田林地占90%。隨機森林在這種不均衡數(shù)據(jù)上會傾向于把少數(shù)類全分錯。緩解辦法包括采集時盡量平衡各類樣本數(shù)量或者使用class_weightbalanced讓模型在計算分裂指標時給少數(shù)類更高的權(quán)重。rf_remote RandomForestClassifier( n_estimators300, max_depth20, min_samples_leaf3, class_weightbalanced, n_jobs-1, random_state42 )5.3 代碼調(diào)優(yōu)、保存與部署的建議訓(xùn)練好的模型不要每次跑都重新訓(xùn)練一遍在實際項目中要用joblib或pickle把模型存下來預(yù)測時直接加載。import joblib # 保存模型和特征名稱 joblib.dump(rf_clf, random_forest_model.pkl) # 使用時報錯就再存一份特征列表 feature_list list(X_train.columns) joblib.dump(feature_list, feature_list.pkl) # 加載模型做預(yù)測 loaded_rf joblib.load(random_forest_model.pkl) y_pred_loaded loaded_rf.predict(X_test)在遙感應(yīng)用里模型訓(xùn)練完只是第一步后面還有整幅影像的預(yù)測、結(jié)果可視化、精度驗證。整幅影像預(yù)測時要注意分塊處理否則一幅大影像可能直接把內(nèi)存撐爆。我的做法是把影像切塊逐塊輸入模型預(yù)測再拼接分類結(jié)果。精度驗證不要只看整體準確率。遙感分類中比較標準的做法是生成混淆矩陣逐類別看生產(chǎn)者精度和用戶精度。這才能暴露“某個地物類別完全被漏分”的問題。另外保存模型時務(wù)必連特征名稱一起保存。我在和同事協(xié)作時遇到過這種問題保存了模型文件結(jié)果換了一個環(huán)境predict時報“特征數(shù)量不匹配”。原因就是訓(xùn)練時的特征順序和預(yù)測時的特征順序不一樣。隨機森林雖然是樹模型不敏感于量綱但對特征順序是敏感的因為每個預(yù)測樣本需要按訓(xùn)練時的順序排好這點必須記住。最后再分享一點個人體會做了這么多次隨機森林的實戰(zhàn)項目我的一個明顯感受是隨機森林好上手但想用好需要對“為什么隨機”有真正的理解。很多人在調(diào)參階段亂試一通繞了很多彎路才明白真正影響模型泛化能力的通常不是樹的數(shù)量而是樹的深度的葉子節(jié)點的約束條件。如果你正在猶豫選什么算法作為第一個認真學(xué)的機器學(xué)習(xí)模型我會推薦隨機森林。它能幫你建立對“模型要的不是記住訓(xùn)練數(shù)據(jù)而是從數(shù)據(jù)中找規(guī)律”這件事的體感又把決策樹、集成學(xué)習(xí)、特征工程這些基本功全部串起來。把這篇文章里的代碼一條條跑通再換一份自己的數(shù)據(jù)試一遍你對隨機森林的理解一定會明顯不一樣。