
簡介CARS競爭性自適應重加權算法可執(zhí)行代碼與文檔整合包面向化學計量學、光譜分析及機器學習研究者解決高維數據下PLS回歸的變量選擇與過擬合問題。rar壓縮包內共有37個文件以32個m格式MATLAB源程序為主另有2個mat實測數據集、1份PDF手冊、1個doc說明和1張示意圖整體大小1.27MB。已有11425人學習下載。資料內含PDF操作手冊、多種示例腳本與玉米光譜數據覆蓋CARS、SCARS、PLS、MCS等算法代碼含交叉驗證、預處理、可視化等模塊便于理解自適應重加權迭代流程與RMSECV評估機制可直接用于論文復現和實際光譜特征篩選。1. 變量篩選為何要競爭CARS算法切入光譜建模的獨特視角近紅外光譜數據動輒上千個波長點變量比樣本還要多按常理信息越豐富模型越準實測卻往往是變量越多預測誤差越大。因為波長點之間存在嚴重的共線性冗余信息和不相關噪聲會把偏最小二乘模型的回歸系數拉扯變形導致模型泛化能力急速下降。競爭性自適應重加權算法CARS要解決的正是這個矛盾它不追求一次性找出最優(yōu)變量組合而是通過模擬自然選擇的迭代過程讓變量在競爭中逐輪淘汰最終收斂到一個低維、低相關性的變量子集。理解CARS就理解了變量選擇里隨機但有方向這一類方法背后的設計動機與底層機制。2. CARS的骨架蒙特卡洛采樣與回歸系數權重的底層邏輯2.1 蒙特卡洛采樣為什么不看全量樣本CARS的第一步是抽樣。每一輪迭代算法會從校正集樣本里隨機抽取一定比例的樣本通常約80%基于這些樣本建立PLS模型。這里有個問題值得先想清楚為什么不直接用全部樣本建模我個人的理解是變量選擇的目標不只是找哪些變量有用還要找哪些變量總是有用——即魯棒性。如果用全量樣本只建一次模型某個變量的回歸系數可能是偶然大、也可能是偶然小而多次隨機抽樣相當于給每個變量提供了多次考試機會。一個真正重要的變量無論抽到哪一批樣本其回歸系數的絕對值都會穩(wěn)定地居于前列一個靠運氣突出重圍的變量則會在不同抽樣下權重忽高忽低。這種做法的本質是交叉驗證的思想下放到變量評估不用單獨留出驗證集而是通過反復重采樣觀察系數的穩(wěn)定性。每輪抽樣都得到一組回歸系數算法比較的是這些系數在不同抽樣下的相對大小而不是某一次的絕對數值。抽樣比例這個參數的敏感性也在這里體現比例太高每輪模型幾乎相同系數波動小等于白抽樣比例太低樣本子集不足以代表整體系數方差過大評估結果又不可靠。2.2 回歸系數絕對值最樸素的變量貢獻度量有了PLS模型每個變量都會得到一個回歸系數。系數的絕對值越大意味著該變量對預測結果的貢獻越強系數接近零的變量則基本可以被視為噪聲攜帶者。CARS把每個變量的回歸系數絕對值作為其權重并在這個權重的基礎上設計后續(xù)的隨機抽樣。這里要特別強調一個細節(jié)CARS用的不是VIP分數或相關系數而是PLS回歸系數。原因是回歸系數天然地考慮了變量之間的聯合作用——某個變量單獨來看與目標值毫無線性關系但在PLS的潛變量結構中它可能與其他變量協同發(fā)揮作用回歸系數能捕捉這種協同貢獻。VIP分數也能做到類似的事但VIP是基于協方差的投影度量而CARS選擇回歸系數的絕對值核心動機是可加性多個變量組合的貢獻大致可以按系數絕對值累加這為后面的按權重隨機抽樣提供了天然的數學基礎。在實際計算中權重計算非常廉價核心邏輯只有幾行import numpy as np from sklearn.cross_decomposition import PLSRegression def evaluate_variable_weight(X, y, sample_ratio0.8, n_components5): # 隨機抽取樣本子集完成蒙特卡洛采樣 n_samples X.shape[0] sampled_idx np.random.choice(n_samples, int(n_samples * sample_ratio), replaceFalse) # 用抽樣樣本建立 PLS 模型 pls PLSRegression(n_componentsn_components) pls.fit(X[sampled_idx], y[sampled_idx]) # 回歸系數的絕對值作為該輪變量權重 coefficients pls.coef_.ravel() weight np.abs(coefficients) # 按權重降序排序返回排序后的索引和權重 sorted_idx np.argsort(weight)[::-1] return sorted_idx, weight這段代碼把蒙特卡洛采樣 回歸系數評估兩個步驟壓縮在一個函數里。關鍵參數有三個sample_ratio控制抽樣比例過大則每輪模型幾乎相同失去多樣性過小則模型不穩(wěn)定系數估計方差太大一般取0.7到0.9之間。n_components是PLS潛變量數它決定模型對數據結構的擬合程度太小會欠擬合太大會把噪聲也擬合進去。返回值里的sorted_idx專門用于下一階段的變量淘汰。注意coef_的形狀PLSRegression的coef_在單因變量場景下是一個二維數組形狀為n_features行、1列所以需要ravel()展平成一維。很多初寫CARS實現的人會在這里取錯維度導致后續(xù)的索引對應不上原始變量這是一個非常隱蔽的坑。2.3 權重排序之后次輪變量子集如何產生每輪評估完權重后并不是簡單地砍掉后半截。CARS使用指數衰減函數確定本輪保留的變量比例然后用自適應重加權采樣按權重從保留變量里做放回式抽樣抽樣結果作為下一輪的變量子集。這里要區(qū)分兩個概念強制淘汰與隨機抽樣。強制淘汰是把當前輪次里確定不重要的變量直接刪掉這是硬性操作隨機抽樣則是在剩余變量里按權重概率性地選取權重大的變量有更高概率被選中但權重小的變量也保留了一絲被選中的機會。這個保留一絲機會的設計恰恰是CARS與貪心算法的分水嶺——貪心算法會無情地丟棄所有當前看起來不重要的變量而CARS允許眼下弱、但組合起來有用的變量有存活的機會。關于這個機制的數學細節(jié)是下一章要展開的重點。3. 指數衰減函數與自適應重加權采樣競爭淘汰的節(jié)奏控制3.1 EDF的數學形式為什么是冪函數衰減CARS每輪要保留多少比例的變量由指數衰減函數EDF決定。設初始變量總數為p當前第i輪從1開始計數總運行輪數為N則第i輪的變量保留率近似為r_i (p_min / p)^(i / N)p_min是計劃在最后一輪保留的最小變量數。這個形式變換一下就能看出指數衰減的本質等式兩邊取對數log(r_i) (i/N)·log(p_min/p)保留率的對數隨輪次線性下降也就是說保留率本身是幾何級數式的衰減。開頭幾輪淘汰速度快越到后面淘汰速度越慢。為什么不是線性衰減線性衰減意味著每輪淘汰固定比例這在變量數很多的光譜場景下會搶跑——前十幾輪把大量變量快速砍光后面想精細篩選時已經沒有候選變量了。而指數衰減前半段快速粗篩、后半段慢速細選正好匹配光譜變量成百上千個變量里真正關鍵的只有幾十個的分布特征。常見實現的EDF代碼如下def compute_retained_ratio(current_round, total_rounds, n_variables, min_variables): 計算第 current_round 輪需要保留的變量比例 current_round: 從 1 開始計數的當前輪次 total_rounds: 總輪次 N n_variables: 初始變量總數 min_variables: 計劃最終保留的最小變量數 # 指數衰減保留率按輪次比例指數下降 ratio (min_variables / n_variables) ** (current_round / total_rounds) return ratio # 每輪保留變量數 當前變量數 * ratio向下取整 # 典型運行軌跡從 1000 個變量出發(fā)50 輪后計劃保留約 30 個這里面的min_variables是個超參數一般取2到10之間的值。它并不代表最終一定保留那么多變量而是給EDF一個收斂錨點讓衰減曲線有末端約束。如果設得太小比如1衰減曲線過于陡峭可能在第30輪就把變量數壓到個位數后面的輪次完全退化成矮子里拔將軍如果設得偏大比如50衰減又太緩前幾輪幾乎沒什么淘汰效果計算開銷增大。3.2 強制淘汰與自適應重加權一只腳剎車、一只腳油門EDF決定的是保留多少個——這是剎車ARS決定的是保留哪一些——這是油門。兩者必須配合起來才能讓迭代正常推進。強制淘汰是硬約束即使某個變量之前一直權重很高一旦EDF的保留變量數小于當前變量數權重最低的那一截會被直接移除。這個步驟保證了變量子集規(guī)模的單調遞減是算法收斂的剎車。自適應重加權采樣是軟操作變量不是簡單地按權重比例被抽中而是要經過一個非均勻采樣過程。具體做法是把保留下來的變量按權重歸一化每個變量的被抽中概率等于其權重占總權重的比例然后從這個概率分布里做放回抽樣抽出的變量集合作為下一輪輸入。這一步是油門——它讓權重高的變量在下一輪里被重復選中從而增加其出鏡率權重低的變量也有機會被抽到避免了重要變量被一步錯殺。用一句話概括強制淘汰篩掉確定不行的隨機重加權篩掉概率上不行的。前者是規(guī)則驅動后者是概率驅動。3.3 權重歸一化與相關性保持還有一個經常被忽略的細節(jié)CARS的隨機抽樣是放回式的。放回意味著同一變量可以在一次抽樣中被抽到多次這相當于變相提高了該變量在下一輪中的權重。疊加上權重歸一化高權重變量的影響力會被進一步放大。很多人第一次看CARS會覺得奇怪為什么要放回放回不會導致變量重復嗎實際上放回恰恰是CARS保護協同變量組的手段。在光譜數據里一個有效變量往往與其附近波長的變量高度相關它們是作為一個模塊共同發(fā)揮作用的。如果抽樣改成不放回那么當某個模塊里的多個變量被抽走后模塊的整體貢獻會被削弱而放回抽樣允許模塊里的關鍵成員被多次選中保持模塊在下一輪模型中的結構完整性。理解到這一層CARS和普通逐步回歸的差別就更清晰了逐步回歸靠統計檢驗決定變量的去留而CARS靠的是加權隨機抽樣帶來的模塊級選擇壓力。這種機制在變量高度共線性的光譜數據里特別有效因為它不需要預先判斷變量之間的相關結構算法自己會在競爭中自發(fā)地保留那些互相支撐的變量組。4. 從采樣到收斂CARS完整流程的機制拆解4.1 運行階段N輪循環(huán)里發(fā)生了什么把前兩章的機制拼起來CARS的完整運行流程可以拆成五個步驟每輪迭代都走一遍從校正集樣本中隨機抽取一份子集約80%。用該子集建立PLS模型得到每個變量的回歸系數。取回歸系數絕對值作為變量權重。用EDF計算本輪變量保留數強制淘汰權重最低的變量。在保留變量中按權重做自適應重加權采樣生成下一輪的變量子集。迭代N輪之后算法會得到一個輪次→變量子集的軌跡。每一輪對應的變量子集都能重新建立PLS模型并用交叉驗證評估預測能力。CARS最后做的事情是用交叉驗證去評估每一輪產生的變量子集所建立模型的RMSECV選RMSECV最小的那一輪作為最優(yōu)變量子集。這里的關鍵是最優(yōu)變量子集往往不是最后那一輪。原因在于EDF在最后幾輪會把變量數壓到很小的規(guī)模此時已經出現欠擬合——變量子集漏掉了某些必要的協同信息。所以CARS的價值不是收斂到某個終點而是在收斂路徑上找到一個最佳停留點。4.2 主循環(huán)實現與參數含義下面給出一個結構完整的CARS主循環(huán)包含EDF、強制淘汰和ARS三個核心步驟import numpy as np from sklearn.cross_decomposition import PLSRegression from sklearn.model_selection import cross_val_predict from sklearn.metrics import mean_squared_error def cars(X, y, total_rounds50, sample_ratio0.8, min_variables3, n_components5): n_samples, n_vars X.shape current_idx np.arange(n_vars) # 當前變量索引 results [] # 每一輪的變量子集與RMSEcv for i in range(1, total_rounds 1): # 1. 蒙特卡洛采樣隨機抽樣本 sampled_rows np.random.choice(n_samples, int(n_samples * sample_ratio), replaceFalse) X_s X[sampled_rows][:, current_idx] y_s y[sampled_rows] # 2. 建立PLS模型取回歸系數絕對值作為權重 pls PLSRegression(n_componentsn_components) pls.fit(X_s, y_s) coef np.abs(pls.coef_.ravel()) # 3. EDF計算保留比例得到本輪的保留變量數 ratio (min_variables / n_vars) ** (i / total_rounds) retain_count max(int(len(coef) * ratio), 1) # 4. 強制淘汰只保留權重最高的 retain_count 個變量 top_idx np.argsort(coef)[::-1][:retain_count] selected current_idx[top_idx] # 5. 自適應重加權采樣按權重放回抽樣 weights coef[top_idx] / (coef[top_idx].sum()) sampled np.random.choice(selected, sizelen(selected), pweights, replaceTrue) current_idx np.unique(sampled) # 去重后作為下一輪變量集 # 用當前變量子集做交叉驗證評估 cv_pred cross_val_predict(PLSRegression(n_componentsn_components), X[:, current_idx], y, cv5) rmsecv mean_squared_error(y, cv_pred) ** 0.5 results.append((rmsecv, current_idx.copy())) # 選 RMSECV 最小的輪次作為最終變量子集 best min(results, keylambda r: r[0]) return best[1], best[0]幾個需要注意的參數細節(jié)sample_ratio是單輪采樣的樣本比例對模型穩(wěn)定性影響很大total_rounds是總迭代次數一般50到100之間min_variables是EDF的末端錨點不能單獨看要和total_rounds一起調節(jié)。第5步里np.unique去重是必要的否則放回抽樣可能讓下一輪變量數膨脹導致EDF無法按預期控制規(guī)模。這段代碼也暴露了CARS的一個典型短板每一輪都要重新訓練PLS并進行交叉驗證計算量不小。對于光譜數據動輒幾千個變量、幾百個樣本來說跑50輪通常還好如果數據規(guī)模更大建議用并行方式將各輪的交叉驗證分散到多個計算單元上。4.3 交叉驗證與最終選擇輪次軌跡有什么價值CARS最終的輸出并不是一個普通的變量列表而是一個帶評估記錄的軌跡。這個軌跡信息非常有用第一它可以告訴你模型從過擬合到欠擬合的變化過程。最早的幾輪變量最多、模型最容易過擬合中間的輪次變量數適中RMSECV往往最低最后幾輪變量太少RMSECV重新上升。畫出輪次→RMSECV的曲線你會非常直觀地看到什么規(guī)模的變量子集對這組數據是甜蜜點。第二它可以幫你識別不穩(wěn)定變量。如果一個變量在多輪次中都出現在變量子集里說明它是穩(wěn)定重要的如果某變量只在個別輪次出現且其后迅速消失說明它權重不高、可有可無。實踐中運行多次CARS統計每個變量被選中的頻率挑選出現頻率高的變量組成最終集合是一種比單次運行更穩(wěn)健的做法。第三輪次曲線的形狀還能用來判斷潛變量數n_components設得是否合理。如果曲線非常平坦、所有輪次的RMSECV都差不多說明潛變量數選擇不當模型沒有充分利用變量信息如果曲線在中間輪次出現明顯低谷則說明潛變量數設置是合適的。5. CARS實踐避坑變量篩選中的常見問題與排查5.1 每次運行選出的變量都不一樣現象同一份數據、同樣的參數連續(xù)跑三次CARS三次選出的變量子集重合度不到一半。原因CARS每一輪都做蒙特卡洛采樣隨機性從第一輪就開始累積。如果total_rounds取得偏小比如20輪隨機偏差還沒有被充分平均掉最終結果會高度依賴初始抽樣的運氣。解決把total_rounds提到50以上并多次運行取變量出現頻率。具體做法是先跑10次CARS統計每個變量被選中的次數再按出現頻率排序選出高頻變量。留意一個邊界情況如果樣本量本來就只有40、50個抽樣比例0.8會讓每輪僅抽30多個樣本此時建議降低total_rounds、提高sample_ratio到0.85以上避免樣本代表性不足。5.2 先標準化還是先跑CARS現象CARS選出的變量集中在中高頻波長段而低頻段幾乎沒有變量被選中模型效果卻很差。原因不同波段的信號強度差異很大。CARS的權重基于PLS回歸系數絕對值如果原始光譜沒有做過標準化數值大的波段天然會獲得更高權重算法傾向保留數值大的變量而不是貢獻大的變量。解決先對光譜數據做均值中心化或方差標準化再運行CARS。均值中心化通常就夠了因為PLS本身對數據的列中心化有天然需求如果數據量綱差異極端再疊加方差標準化。經驗上標準化的操作必須在劃分校正集和測試集之前統一完成避免數據泄漏。5.3 校正集和測試集劃分時機不對現象CARS在訓練數據上選出的變量表現很好但在獨立測試集上誤差翻倍。原因如果先把全部樣本混在一起做CARS再劃分校正集和測試集變量選擇過程已經把測試集的信息泄漏進了模型的選變量階段。這屬于典型的后選擇偏差變量選擇時的交叉驗證結果虛高真實泛化能力遠低于預期。解決嚴格按照先劃分、后篩選的流程先把數據按7:3或8:2切成校正集和測試集只在校正集上運行CARS選出的變量固定后再用相同的變量索引去提取測試集特征。CARS的變量選擇結果不能因為加入了測試集樣本而重新計算。5.4 RMSECV最小的輪次太多無法區(qū)分現象RMSECV曲線在很長一段范圍內非常接近最小值前后的輪次波動差別很小難以判斷哪一輪是真正最優(yōu)。原因變量子集之間的預測能力差異可能很小交叉驗證本身的隨機波動就已經掩蓋了差異。這種情況在共線性嚴重、變量數接近的情況下很常見。解決優(yōu)先選變量數更少的那一輪因為模型更簡潔、更容易部署和解釋。另外可以配合變量出現頻率選同時滿足RMSECV接近最優(yōu)和變量出現頻率高的子集。提示CARS選出的變量子集必須經過再驗證。用選出的變量重新建立PLS模型在測試集上計算RMSEP和全變量模型對比確認變量篩選確實帶來了泛化性能提升才算走完完整流程。5.5 數據量太小導致PLS擬合失敗現象某輪迭代時PLS模型無法收斂報出線性代數相關的錯誤。原因蒙特卡洛抽樣后參與建模的樣本數可能少于潛變量數或在某些變量組合下設計矩陣接近奇異導致矩陣求逆失敗。解決檢查n_components是否小于抽樣樣本數的三分之一提前對抽樣后的矩陣做條件數檢查如果條件數過大跳過該輪或重新抽樣。更根本的做法是在數據預處理階段先做簡單的無信息變量剔除把明顯是純噪聲的波長提前刪掉減少CARS在高危區(qū)域掙扎的概率。6. 設計取舍為什么CARS選擇競爭而不是貪心把CARS和同類算法擺在一起會看到一條清晰的設計取舍線。逐步回歸、向前選擇這類貪心算法試圖在每一步做出當前最優(yōu)的決定每步精準砍掉一個或幾個變量參數少、可解釋性強但它們對變量的共線性極度敏感兩個相關性極高的變量貪心算法會先選一個然后再也無法公正評估另一個的獨立貢獻。CARS用隨機性和競爭繞開了這個問題——它不在每一步做最優(yōu)決策而是讓多個變量在反復競爭中自發(fā)分層重要變量自然留在高頻區(qū)冗余變量被隨機淘汰。這個選擇是有代價的CARS的隨機性導致單次運行結果不可完全復現必須靠多次運行或調大N來換取穩(wěn)定。相比貪心算法的一次性確定輸出CARS像是一種統計式的變量選擇它的結果本質上是一個概率分布而不是一個唯一答案。我個人的使用習慣是把CARS當作變量預篩器而非最終決策器。先用CARS把變量從上千壓到幾十再用簡單的手工推理或逐步回歸從幾十里挑出最終的十幾二十個。這樣既利用了CARS對共線性的容忍又保留了貪心算法在最后階段的確定性。另一個值得想的設計點是EDF的強制性。為什么不讓權重直接決定去留而要額外加一個指數衰減的外力因為純按權重隨機抽樣變量的淘汰速度會很慢而且方差大EDF給了整個迭代一個時間表讓變量數在第N輪之前收斂到用戶預設的尺度。這個外力看似粗暴其實是對隨機過程的一種正則化——它保證了收斂速度也讓何時停止這個問題擺脫了對權重閾值的主觀設定。從那以后我每次跑CARS都會做三件事先畫RMSECV曲線看收斂節(jié)奏多跑幾次統計頻率再用最終變量子集做一次獨立的測試集驗證。這套流程每次都能幫我把變量從混亂的物理信號里撈出來。希望幫到你。本文還有配套的精品資源點擊獲取