戰(zhàn):從環(huán)境配置到算法調(diào)優(yōu)的避坑指南)
簡介《美賽各題型常見參考代碼匯總.zip》是一套面向數(shù)學(xué)建模競賽選手的代碼與案例資源包覆蓋從線性回歸、數(shù)據(jù)擬合等基礎(chǔ)統(tǒng)計(jì)方法到遺傳算法改進(jìn)神經(jīng)網(wǎng)絡(luò)等智能優(yōu)化算法適合美賽、國賽及各類數(shù)學(xué)建模實(shí)戰(zhàn)場景。壓縮包共2000個文件以bmp圖像、m腳本、mat數(shù)據(jù)、txt說明、fig圖表為主要類型混合了源碼、可視化結(jié)果、訓(xùn)練樣例與輔助說明便于對照運(yùn)行或二次改造整體大小約109.72MB。資源目前已有4062人學(xué)習(xí)下載內(nèi)容圍繞常見題型組織包含基礎(chǔ)模型完整示例、改進(jìn)算法多種實(shí)現(xiàn)以及配套的圖形文件和說明文檔。讀者可按圖索驥快速定位所需的建模模塊理解算法設(shè)計(jì)與數(shù)據(jù)流并直接復(fù)用或改造代碼特別適合希望系統(tǒng)提升建模實(shí)戰(zhàn)能力、從入門走向進(jìn)階的競賽選手。1. 美賽各題型常見參考代碼匯總這份 zip 不是資料庫是改裝件“美賽各題型常見參考代碼匯總”這類資源下載過的人不少真正在賽前跑通過的人不多。整個 zip 的價值不在于“里面有什么算法”而在于把連續(xù)、離散、優(yōu)化、評價、預(yù)測這幾類題型的常用代碼按參考形態(tài)收在一處數(shù)據(jù)分析、智能算法、神經(jīng)網(wǎng)絡(luò)三個方向都有對應(yīng)腳本。它解決的不是“不會建?!倍恰坝兴悸返珌聿患鞍汛a跑通”。適合時間緊、需要先有一份能跑通的基線模型再迭代的隊(duì)伍。我的建議是把它當(dāng)改裝件用先不改算法只換數(shù)據(jù)和目標(biāo)函數(shù)確認(rèn)輸出能做成一頁圖表再往下調(diào)參數(shù)。2. 打開壓縮包先不急著跑目錄、環(huán)境和數(shù)據(jù)路徑一次理順2.1 目錄結(jié)構(gòu)與文件類型先分清參考代碼、樣例數(shù)據(jù)和說明文檔大多數(shù)情況下解壓出來的內(nèi)容不是一個大亂燉而是按題型分好的文件夾。以我拆過的類似資源為例通常會有 01_連續(xù)型、02_離散型、03_優(yōu)化類這類目錄每個目錄里放著參考代碼.py 或 .m、示例數(shù)據(jù).csv 或 .xlsx以及一個說明文檔。有些包還會把繪圖腳本單獨(dú)放一個文件夾避免主程序和畫圖混在一起。拿到壓縮包第一步是不要在 IDE 里直接點(diǎn)運(yùn)行而是先看一遍目錄。我習(xí)慣先敲一句tree -L 2 -F這樣能在一屏內(nèi)看清哪個文件是入口、哪個文件是數(shù)據(jù)。如果系統(tǒng)沒有 treeWindows 下可以用dir /s /b代替。說明文檔可能叫“00_使用說明.txt”或 README多數(shù)整理者會寫清每個腳本的作用、運(yùn)行前要裝什么庫、數(shù)據(jù)文件放在哪。重點(diǎn)看三件事。腳本末尾是否有if __name__ __main__:有這一行說明可以單獨(dú)運(yùn)行。是否有硬編碼的絕對路徑。是否引用了相對路徑下的數(shù)據(jù)文件。參考代碼和樣例數(shù)據(jù)放在同一級目錄是最理想的因?yàn)榇a大多按相對路徑讀數(shù)據(jù)。如果說明里寫了“請將數(shù)據(jù)放到 data 文件夾”最好原樣保留目錄結(jié)構(gòu)不要為了整潔亂挪文件。挪完以后再跑大概率報(bào) FileNotFoundError這是第一腳踩坑的常見來源。我一般還會在解壓后先做一次完整性檢查不是驗(yàn)算數(shù)據(jù)而是確認(rèn) zip 本身沒壞。如果解壓時遇到 invalid zip archive、could not find EOCD 這類報(bào)錯通常是文件沒下完整重新下一遍比折騰解壓工具更快。確認(rèn)沒問題后再把“參考代碼”整目錄復(fù)制一份作為工作副本不在原始文件上改。復(fù)制工作副本花不了兩分鐘但能在后續(xù)反復(fù)改參數(shù)時提供一張后悔藥。2.2 Python 環(huán)境與依賴用 venv 隔離避免“在我機(jī)器上能跑”參考代碼最怕的不是程序本身難而是環(huán)境不一致。很多代碼是 Python 3.6 ~ 3.9 時代寫的現(xiàn)在用 3.12 直接打開可能連 numpy 都進(jìn)不去。我一般會為這類資源單獨(dú)建一個虛擬環(huán)境不讓它污染平時做項(xiàng)目的主環(huán)境。python -m venv venv source venv/bin/activate pip install --upgrade pip pip install -r requirements.txtWindows 下激活命令換成venv\Scripts\activate。如果壓縮包里沒有 requirements.txt先用最小依賴集跑通主程序pip install numpy pandas scipy matplotlib scikit-learn解釋一下venv創(chuàng)建的是獨(dú)立環(huán)境包版本不會互相覆蓋升級 pip 是因?yàn)榕f版 pip 解析復(fù)雜依賴時容易失敗requirements.txt 里如果寫著 numpy1.19.5 這種老版本先別急著照單全收等主程序跑起來以后再決定要不要降級。注意tensorflow 和 keras 相關(guān)的代碼不要一上來就裝。參考代碼里如果只是用多層感知機(jī)scikit-learn 就夠。確實(shí)要用 LSTM 再單獨(dú)裝 tensorflowCPU 版在賽題數(shù)據(jù)量下也足夠不需要一開始就折騰 GPU。裝完以后做一個最小驗(yàn)證python -c import numpy, pandas, sklearn; print(ok)這一句能快速排除“環(huán)境白裝了”的情況。還有一類坑藏在依賴約束里如果 requirements 里寫著 tensorflow2.10在老機(jī)器上會因?yàn)?CPU 指令集問題裝不上。遇到這種情況常見做法是改用 conda 裝讓 conda 挑一個與當(dāng)前硬件匹配的包。如果還不行就用 CPU 版代替代價只是訓(xùn)練慢一點(diǎn)不影響正確性。部分包里的 .m 文件是 MATLAB 代碼Python 環(huán)境管不了它們先跳過4.3 會講替代路線。2.3 數(shù)據(jù)路徑約定為什么相對路徑比絕對路徑靠譜參考代碼里常見兩種讀數(shù)據(jù)方式一種是寫死pd.read_excel(C:/Users/xxx/data.xlsx)一種是os.path.join(os.getcwd(), data)拼路徑。前者換臺電腦就廢后者換啟動目錄就廢。自己改的時候我一般統(tǒng)一換成基于當(dāng)前腳本文件算路徑的方案from pathlib import Path # 當(dāng)前腳本所在目錄不是命令行所在目錄 BASE_DIR Path(__file__).resolve().parent data_path BASE_DIR / data / data.csv df pd.read_csv(data_path, encodingutf-8) print(路徑檢查:, data_path, 存在:, data_path.exists())邏輯說明__file__是當(dāng)前文件的路徑resolve()把相對路徑轉(zhuǎn)成絕對路徑parent取上一級目錄再往下拼數(shù)據(jù)文件。這樣不管 zip 解壓到哪個位置只要內(nèi)部目錄結(jié)構(gòu)不變代碼就能找到數(shù)據(jù)。打印路徑和exists()是為了在找不到文件時立刻看到實(shí)際指向。我還會在開頭加一個檢查路徑不存在就打印提示并返回。很多參考代碼翻車不是算法問題而是數(shù)據(jù)沒讀進(jìn)來后面所有矩陣都是空。路徑問題一次理順能省掉一整天的排查時間。還要多一句嘴盡量把 Excel 轉(zhuǎn)成 CSV 再喂給 pandas。Excel 讀取本身沒問題但多行表頭、合并單元格、日期格式都會在讀入時產(chǎn)生意外CSV 沒有這些花樣出問題也好查。如果代碼讀的是 xlsx而你的數(shù)據(jù)在多個 sheet 里最簡單的處理是先把目標(biāo) sheet 另存為 CSV再改路徑。不要在參考代碼上做太多自由度很高的改動改動越多邊界越難查。3. 把題型和代碼模板對上先判斷它到底該用哪份參考代碼3.1 題型分類與算法選型一張表說明映射關(guān)系美賽題型從建模角度大致分成五類連續(xù)、離散、優(yōu)化、評價、預(yù)測。參考代碼包通常是按這個分類組織的。拿到題目以后先判斷題型再找對應(yīng)參考代碼順序不要反過來。題型常見背景默認(rèn)參考算法包里對應(yīng)方向連續(xù)型物理變化、增長曲線、流量趨勢微分方程 插值擬合01_連續(xù)型離散型網(wǎng)絡(luò)、狀態(tài)轉(zhuǎn)移、排隊(duì)圖論最短路/流、狀態(tài)轉(zhuǎn)移矩陣02_離散型優(yōu)化類資源分配、路徑規(guī)劃、生產(chǎn)調(diào)度遺傳算法、粒子群、模擬退火03_優(yōu)化評價類方案比選、風(fēng)險排序、多指標(biāo)評分熵權(quán)法、TOPSIS、層次分析04_評價預(yù)測類未來趨勢、回歸、時序線性回歸、MLP、LSTM05_預(yù)測選型邏輯很簡單。連續(xù)型題目給的是變化過程要找函數(shù)關(guān)系優(yōu)先擬合和參數(shù)估計(jì)。離散型題目涉及狀態(tài)和路徑圖論模型更直接。優(yōu)化類題目如果變量少、約束簡單窮舉或線性規(guī)劃就行變量一多啟發(fā)式算法更現(xiàn)實(shí)。評價類題目沒有標(biāo)準(zhǔn)答案關(guān)鍵是權(quán)重怎么來熵權(quán)法屬于數(shù)據(jù)驅(qū)動比拍腦袋定權(quán)重有說服力。預(yù)測類題目要的是未來值先跑一個簡單回歸當(dāng)基線再看要不要上神經(jīng)網(wǎng)絡(luò)??磪⒖即a時不要上來就挑最“高級”的算法。對一場三到四天的比賽而言能跑通、能穩(wěn)定復(fù)現(xiàn)結(jié)果的基線遠(yuǎn)比一個只在理想例子上好看的高級模型重要。假如題目還沒審?fù)昃痛蜷_ LSTM 腳本復(fù)制粘貼后續(xù)只會花大量時間在調(diào)參而不是解題上。參考代碼包的意義是提供起點(diǎn)不是終點(diǎn)。我一般會把“能找到基線結(jié)果”作為第一目標(biāo)確認(rèn)它能輸出圖表和指標(biāo)再談優(yōu)化。3.2 智能算法參考代碼遺傳算法怎么改適應(yīng)度函數(shù)優(yōu)化類題目對應(yīng)的智能算法多數(shù)是基于種群的啟發(fā)式搜索。壓縮包里這類代碼的結(jié)構(gòu)大同小異一個主函數(shù)負(fù)責(zé)初始化種群和迭代一個適應(yīng)度函數(shù)負(fù)責(zé)評價個體。真正需要你改的只有適應(yīng)度函數(shù)其他部分幾乎不用動。下面這段是能直接跑的簡化框架import numpy as np def fitness(x): # 以最小化 f x^2 2 為例 return x[0] ** 2 2 def ga(fn, lb-10.0, ub10.0, pop_size50, max_gen100, pc0.8, pm0.05): dim 1 pop np.random.uniform(lb, ub, (pop_size, dim)) for g in range(max_gen): scores np.array([fn(ind) for ind in pop]) order np.argsort(scores) pop pop[order] new_pop [pop[0].copy()] # 精英保留 while len(new_pop) pop_size: # 錦標(biāo)賽只從前一半隨機(jī)取兩個 a pop[np.random.randint(0, pop_size // 2)] b pop[np.random.randint(0, pop_size // 2)] # 算術(shù)交叉 child 0.5 * (a b) if np.random.rand() pc else a.copy() # 高斯變異 if np.random.rand() pm: child np.clip(child np.random.normal( 0, 0.5 * (ub - lb)), lb, ub) new_pop.append(child) pop np.array(new_pop) idx int(np.argmin([fn(ind) for ind in pop])) return pop[idx], fn(pop[idx]) best, val ga(fitness) print(最優(yōu)解:, best, 最優(yōu)值:, val)邏輯說明初始化階段用均勻分布在上下界之間生成種群。每輪迭代先按適應(yīng)度排序適應(yīng)度越小排名越靠前錦標(biāo)賽機(jī)制只從排序前一半個體里隨機(jī)取兩個做交叉保證優(yōu)質(zhì)個體更容易被選中精英保留策略把上一代最優(yōu)解直接復(fù)制進(jìn)下一代防止最優(yōu)解丟失。變異用高斯擾動np.clip把子代限制在邊界內(nèi)。代碼以最小化問題為例如果賽題是最大化收益在適應(yīng)度函數(shù)里加個負(fù)號即可。參數(shù)說明pop_size是種群規(guī)模一般取 30~200越大收斂越穩(wěn)但越慢max_gen是迭代代數(shù)建議從 100 開始看收斂曲線不夠再加pc是交叉概率0.6~0.9 是常見區(qū)間pm是變異概率太小容易早熟太大退化成隨機(jī)搜索0.05~0.2 可以先用。邊界lb和ub要跟決策變量的物理含義走比如資源分配問題里變量不能為負(fù)lb就設(shè)為 0。改適應(yīng)度函數(shù)時最常犯的錯誤是把賽題里的幾個目標(biāo)直接塞進(jìn)一個返回值而不考慮量綱。既要成本最小又要時間最短直接相加會讓數(shù)值大的那項(xiàng)主導(dǎo)搜索。常見做法是先歸一化再加權(quán)把原始目標(biāo)分別除以各自的最大值再乘權(quán)重相加。參考代碼里只留了一個適應(yīng)度函數(shù)入口的話你的工作量就集中在這一處。3.3 神經(jīng)網(wǎng)絡(luò)參考代碼從 MLP 到 LSTM 的兩級方案預(yù)測類代碼一般分兩類同一時刻輸入輸出用 MLP按時間先后輸入輸出用 LSTM。很多參考代碼包會把兩層都放進(jìn)去但先別急著用深度學(xué)習(xí)。先用 MLP 建立基線跑通了再換 LSTM這個順序能避免陷入黑匣子調(diào)參的泥潭。下面是 MLP 參考代碼的常見形態(tài)import numpy as np import pandas as pd from sklearn.neural_network import MLPRegressor from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler df pd.read_csv(data/train.csv) X df.iloc[:, :-1].values y df.iloc[:, -1].values X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42) scaler StandardScaler() X_train scaler.fit_transform(X_train) X_test scaler.transform(X_test) model MLPRegressor( hidden_layer_sizes(64, 32), activationrelu, max_iter500, random_state0 ) model.fit(X_train, y_train) print(train R2:, model.score(X_train, y_train)) print(test R2:, model.score(X_test, y_test))邏輯說明df.iloc[:, :-1]取所有行除最后一列默認(rèn)最后一列是標(biāo)簽train_test_split按八二劃分StandardScaler先 fit 再 transform測試集只做 transform不做 fit。這個順序是為了防止信息泄漏如果測試集也參與計(jì)算均值方差相當(dāng)于把測試集信息暴露給模型。model.score在回歸問題里輸出的是 R2越接近 1 越好。參數(shù)說明hidden_layer_sizes(64, 32)表示兩個隱藏層神經(jīng)元數(shù)分別 64 和 32。層數(shù)和神經(jīng)元數(shù)不是越大越好賽題數(shù)據(jù)通常只有幾千行兩層 32~64 足夠。max_iter是最大迭代次數(shù)如果訓(xùn)練還沒收斂就停了會看到警告調(diào)大到 800。activation保持 relu除非有特殊理由。random_state0保證每次跑的結(jié)果一致。時序類題目再用 LSTM。參考代碼里常見的是這種構(gòu)造窗口的寫法import numpy as np def build_sequences(x, look_back10): Xs, ys [], [] for i in range(len(x) - look_back): Xs.append(x[i:i look_back]) ys.append(x[i look_back]) return np.array(Xs), np.array(ys) # 數(shù)據(jù)一維窗口 10 步 data np.loadtxt(data/series.csv) X, y build_sequences(data, 10) # LSTM 輸入要求 (樣本數(shù), 時間步, 特征數(shù)) X X.reshape(X.shape[0], X.shape[1], 1) print(X.shape, y.shape)邏輯說明look_back決定用過去多少步預(yù)測下一步Xs里每個元素是一個長度為窗口的片段ys是對應(yīng)的下一個值。最后一定要把二維輸入 reshape 成三維第三維是特征數(shù)。這是 LSTM 參考代碼里最常見的結(jié)構(gòu)門檻。這里有個容易翻車的細(xì)節(jié)時序數(shù)據(jù)生成序列時不能隨機(jī)打亂否則時間順序就沒了。MLP 那一步可以用train_test_splitLSTM 這步只能按時間前后切分。參考代碼里如果用random.shuffle處理時序數(shù)據(jù)說明它只適合做回歸示例不能直接套到趨勢預(yù)測上。壓縮包里如果給的是 LSTM 腳本先檢查它的數(shù)據(jù)預(yù)處理里有沒有打亂時序再決定要不要用。4. 避坑參考代碼運(yùn)行時的五個典型坑與排查順序4.1 中文路徑和 Excel 編碼導(dǎo)致的讀取失敗現(xiàn)象pd.read_csv(數(shù)據(jù).csv)直接報(bào) UnicodeDecodeError或者報(bào) FileNotFoundError但文件明明在。這兩種報(bào)錯都讓人很煩躁因?yàn)閱栴}不在代碼邏輯而在文件本身。原因Windows 下很多 Excel 另存的 CSV 是 GBK 或 GB2312 編碼而 pandas 默認(rèn)用 UTF-8 讀路徑里的中文還可能被腳本當(dāng)作亂碼處理。參考代碼通常是整理者在自己電腦上跑通的他可能從來沒遇到過編碼問題。解決讀取時指定編碼或者加一次兜底重試。try: df pd.read_csv(path, encodingutf-8) except UnicodeDecodeError: df pd.read_csv(path, encodinggbk)邏輯說明先按 UTF-8 讀讀不了再退回 GBK。這套邏輯能覆蓋絕大多數(shù)從中文 Excel 導(dǎo)出的 CSV。如果兩種編碼都失敗直接用文本編輯器把 CSV 另存為帶 BOM 的 UTF-8是最省事的方案。路徑里有中文導(dǎo)致的 FileNotFoundError比編碼問題更隱蔽排查時先打印os.path.abspath(path)看實(shí)際路徑再檢查文件名里的全角字符。4.2 NumPy 語法差異老代碼在新環(huán)境里報(bào)錯的替換寫法現(xiàn)象代碼里np.bool、np.float直接報(bào) AttributeError或者程序停在一句類型判斷上提示 module numpy has no attribute xxx。原因參考代碼大多寫于 NumPy 1.24 發(fā)布之前老版本把np.float這類別名暴露在命名空間里新版本把它們刪掉了。參考代碼整理者通常不會為每個腳本做版本適配這類問題只能自己動手。解決把下面這個表記在心里遇到什么換什么。老寫法新寫法np.boolbool 或 np.bool_np.floatfloat 或 np.float64np.intint 或 np.int64np.objectobject替換完大多數(shù)情況就能跑。還有 pandas 的df.append在 2.0 里被移除老代碼如果用一句df df.append(new_row)會報(bào)屬性缺失改成pd.concat([df, new_row], ignore_indexTrue)。這些改動屬于機(jī)械替換不算改業(yè)務(wù)邏輯。如果替換完還報(bào)錯優(yōu)先看報(bào)錯堆棧最下面一行那才是真正出問題的地方不要在 warnings 里找原因。4.3 MATLAB 方案在沒裝 MATLAB 的機(jī)器上的替代路線現(xiàn)象.m文件雙擊打不開或者好不容易裝了個環(huán)境發(fā)現(xiàn)腳本用到某些工具箱函數(shù)報(bào)“函數(shù)未定義”。原因壓縮包里的部分參考代碼是 MATLAB 工作流寫的依賴統(tǒng)計(jì)工具箱或優(yōu)化工具箱而多數(shù)隊(duì)伍沒有正版授權(quán)網(wǎng)上找的替代品又容易在版本上出問題。解決用 Octave 跑大部分.m文件或者在包里找對應(yīng)的 Python 實(shí)現(xiàn)。octave-cli model.m如果 Octave 報(bào)某個函數(shù)不存在八成是fitnlm、ga這類工具箱函數(shù)。處理辦法有兩個一是手動把這個函數(shù)翻譯成 scipy.optimize 里對應(yīng)的接口二是直接放棄這批 MATLAB 代碼改用包里的 Python 版本。我的習(xí)慣是優(yōu)先找 Python 版本比賽時沒有時間花在翻譯語法上。還要注意一點(diǎn)MATLAB 和 Python 混在同一個文件夾時data.mat和data.csv可能同時存在腳本讀的未必是你以為的那個文件。跑之前看一眼代碼里的文件名不要想當(dāng)然。4.4 矩陣維度與數(shù)據(jù)順序shape 不一致比報(bào)錯更隱蔽現(xiàn)象程序不報(bào)錯結(jié)果卻很奇怪比如所有預(yù)測值都接近同一常數(shù)或者優(yōu)化結(jié)果明顯偏離常識。這類問題最難查因?yàn)殄e誤不會直接彈出來。原因最常見的是標(biāo)簽和特征列順序不對、X 和 y 行數(shù)不一致、Excel 表頭被讀成一行數(shù)據(jù)。這三個問題都會讓模型在錯誤維度上訓(xùn)練。解決在訓(xùn)練前強(qiáng)制打印并斷言關(guān)鍵數(shù)據(jù)的形狀。print(X shape:, X.shape, y shape:, y.shape) assert len(X) len(y) assert X.shape[0] 1如果 X 是二維(n, 1)而算法要求(n, m)模型有可能把一個特征當(dāng)多特征用數(shù)值上不報(bào)錯但預(yù)測結(jié)果會集中在均值附近。原因在于每個樣本攜帶的信息太少模型只能學(xué)到標(biāo)簽均值。查法是這樣把特征名打印出來確認(rèn)第一列不是序號再把第一行打印出來確認(rèn)沒混入表頭。還要注意數(shù)據(jù)順序預(yù)測類題目按天給數(shù)據(jù)如果用隨機(jī)打亂的方式劃分訓(xùn)練集和驗(yàn)證集時間規(guī)律會被打散。參考代碼里如果帶了 shuffle要格外小心。時序數(shù)據(jù)只能按時間切分先看有沒有時間列有就按時間排序后再切。我見過有人把訓(xùn)練集和驗(yàn)證集混在一起標(biāo)準(zhǔn)化結(jié)果驗(yàn)證時指標(biāo)很好看提交后發(fā)現(xiàn)完全不可用這就是信息泄漏屬于數(shù)據(jù)順序問題里最傷的一種。4.5 隨機(jī)種子與結(jié)果復(fù)現(xiàn)為什么第二次跑結(jié)果不一樣現(xiàn)象同一份代碼第一次跑出 R20.83第二次變成 0.79遺傳算法兩次最優(yōu)解完全不同。很多隊(duì)伍在結(jié)果里寫“模型 R2 為 0.83”實(shí)際上這個數(shù)字根本不可復(fù)現(xiàn)。原因參考代碼沒有固定隨機(jī)種子初始化、劃分、變異都受隨機(jī)數(shù)影響。嚴(yán)格來說不可復(fù)現(xiàn)的結(jié)果不能作為論證依據(jù)。解決程序入口處固定種子。import random import numpy as np random.seed(0) np.random.seed(0) # sklearn 內(nèi)部還在 random_state 參數(shù)里固定 # tensorflow/keras 固定方式不同 import tensorflow as tf tf.random.set_seed(0)說明Python 標(biāo)準(zhǔn)庫random影響部分腳本numpy 影響大部分科學(xué)計(jì)算sklearn 基本靠random_state參數(shù)tensorflow 要單獨(dú)設(shè)種子。只固定一處不夠三處都要固定。固定種子以后前后兩次結(jié)果一致才能放心比較參數(shù)。如果固定完還是有浮動檢查代碼里有沒有在循環(huán)里調(diào)用np.random且沒有走同一個種子分支。5. 從參考代碼到自己的模型文件賽前 48 小時的驗(yàn)證流程5.1 用一道舊題把四個模板跑通拿到參考代碼后最有效的第一個動作不是讀代碼而是找一道往年賽題把連續(xù)、優(yōu)化、預(yù)測三個模板分別套一次。目標(biāo)不是得高分而是確認(rèn)每個腳本都能輸入、運(yùn)行、輸出結(jié)果。我會記錄每個腳本的運(yùn)行時間超過十分鐘的算法文件先縮小數(shù)據(jù)規(guī)模跑通再決定要不要全量跑。這個預(yù)跑過程相當(dāng)于給后面的比賽上保險。5.2 參數(shù)掃描參考代碼不夠好就調(diào)這些旋鈕跑通基線后不要再憑感覺調(diào)參直接做一個小網(wǎng)格搜索results [] for lr in [0.01, 0.001]: for hidden in [(32,), (64, 32)]: model MLPRegressor( hidden_layer_sizeshidden, learning_rate_initlr, max_iter500, random_state0 ) model.fit(X_train, y_train) results.append((lr, hidden, model.score(X_test, y_test))) for r in sorted(results, keylambda t: -t[2]): print(r)邏輯說明兩層循環(huán)遍歷學(xué)習(xí)率和隱藏層結(jié)構(gòu)把每組參數(shù)對應(yīng)的測試集 R2 記錄下來最后按從高到低排序。這樣選參數(shù)是有依據(jù)的而不是靠“感覺上次跑得好”。注意固定random_state0否則不同參數(shù)組之間的差異會被隨機(jī)噪聲干擾。如果參考代碼里已經(jīng)有 main 函數(shù)把它改造成接受參數(shù)的版本能省不少事。最后對每個提交結(jié)果做一次輸出檢查圖有沒有數(shù)據(jù)、坐標(biāo)軸有沒有標(biāo)簽、單位有沒有寫、參數(shù)表是不是和正文一致。有一次我為了趕時間把訓(xùn)練集和驗(yàn)證集一起標(biāo)準(zhǔn)化驗(yàn)證集結(jié)果非常好看提交后才發(fā)現(xiàn)信息泄漏后悔藥都沒地方買。從那以后我每次跑參考代碼都強(qiáng)制走一遍固定種子、標(biāo)準(zhǔn)化只對訓(xùn)練集 fit、結(jié)果先復(fù)現(xiàn)再提指標(biāo)這三步。希望這套流程能幫到你。本文還有配套的精品資源點(diǎn)擊獲取