癌癥預(yù)后預(yù)測系統(tǒng):從數(shù)據(jù)預(yù)處理到模型融合的完整實踐)
多組學(xué)癌癥預(yù)后預(yù)測系統(tǒng)做了大半年從最初拍腦袋想“把幾個組學(xué)數(shù)據(jù)拼起來不就完了”到后面老老實實把數(shù)據(jù)清洗、特征篩選、融合模型、系統(tǒng)部署整個鏈路走通中間踩了不少坑。這套系統(tǒng)最后落地成一個小型Web服務(wù)輸入基因表達(dá)、甲基化、拷貝數(shù)變異這些公共數(shù)據(jù)幾秒鐘返回風(fēng)險分?jǐn)?shù)、風(fēng)險分層和1/3/5年生存概率。這篇文章就把整體設(shè)計、核心技術(shù)環(huán)節(jié)、實現(xiàn)細(xì)節(jié)、驗證方法原原本本拆給大家適合正在做腫瘤生信分析、或者準(zhǔn)備把深度學(xué)習(xí)模型工程化交付的同學(xué)參考。1. 項目要解決什么問題為什么單組學(xué)模型做到頭了先交代一下背景。我之前做過很多單組學(xué)預(yù)后模型基本都是“一個基因表達(dá)矩陣 一個Cox回歸調(diào)一調(diào)特征C-index到0.7左右就上不去了”。最初以為是樣本量不夠后來發(fā)現(xiàn)即使樣本加到六七百例性能還是在那個水平徘徊。這時候才意識到問題出在數(shù)據(jù)維度上——單一組學(xué)只反映了腫瘤生物學(xué)的一個側(cè)面信息量存在天花板。1.1 單組學(xué)預(yù)測模型的上限在哪里以轉(zhuǎn)錄組為例基因表達(dá)數(shù)據(jù)本身噪音很大測序平臺不同、批次不同、樣本異質(zhì)性這些都會讓模型的泛化能力受損。單純依靠幾百個表達(dá)基因去預(yù)測患者兩年后是否復(fù)發(fā)生物學(xué)上也不合理。腫瘤的發(fā)生發(fā)展是一個從突變累積、表觀修飾改變、轉(zhuǎn)錄失調(diào)到蛋白功能異常的多層次過程你只截取其中一個層面當(dāng)然會有信息盲區(qū)。我做過一個對比實驗同一批腫瘤樣本只用表達(dá)數(shù)據(jù)訓(xùn)練DeepSurvC-index穩(wěn)定在0.71加上甲基化特征后同一套訓(xùn)練流程提高到0.78再加拷貝數(shù)變異和miRNA數(shù)據(jù)后內(nèi)測能到0.82左右。這組數(shù)字說明一個事實——組學(xué)之間的互補(bǔ)信息是真實存在的關(guān)鍵是你能不能把它們科學(xué)地整合起來。1.2 多組學(xué)不是簡單堆數(shù)據(jù)信息互補(bǔ)與維度爆炸并存這里要給一個明確警告直接把幾個組學(xué)矩陣橫向拼接幾乎必翻車。原因有三個。第一維度爆炸。轉(zhuǎn)錄組兩萬多個基因甲基化探針?biāo)氖迦f個位點拷貝數(shù)變異也有數(shù)萬個片段區(qū)域拼接完的特征向量幾十萬維樣本量卻只有幾百這種“高維小樣本”問題對神經(jīng)網(wǎng)絡(luò)模型來說是災(zāi)難性的過擬合。第二數(shù)據(jù)缺失嚴(yán)重。公共數(shù)據(jù)庫里不是每個樣本都同時有表達(dá)、甲基化、拷貝數(shù)和miRNA數(shù)據(jù)樣本做交集之后總量從一千多例直接縮到四五百例是常態(tài)。你需要提前想清楚怎么處理缺失樣本人群。第三各組學(xué)數(shù)據(jù)的分布特征不同。表達(dá)數(shù)據(jù)經(jīng)過log值處理后近似正態(tài)甲基化Beta值在0到1之間有雙峰分布拷貝數(shù)變異有大量0值直接喂進(jìn)同一個歸一化流程非常不妥。所以多組學(xué)項目的第一課就是整合分析不等同于數(shù)組拼接前面有兩條很長很長的路要走——數(shù)據(jù)預(yù)處理和特征篩選。2. 數(shù)據(jù)準(zhǔn)備一臺機(jī)器90%的時間耗在預(yù)處理上這部分的經(jīng)驗是我血淚換來的。系統(tǒng)設(shè)計時模型選型只花了一周但數(shù)據(jù)預(yù)處理斷斷續(xù)續(xù)搞了一個多月。公共數(shù)據(jù)倉庫下載、樣本篩選、格式統(tǒng)一、歸一化、批次校正、求交集每一步都有坑。2.1 數(shù)據(jù)來源與樣本篩選邏輯多組學(xué)數(shù)據(jù)首選公共腫瘤數(shù)據(jù)庫通常會用TCGA和GEO這類公開數(shù)據(jù)源。TCGA的特點是樣本量大、臨床隨訪信息相對完整而且同一批樣本通常有多個組學(xué)平臺的測序結(jié)果非常適合做多組學(xué)整合。GEO的好處是數(shù)據(jù)來源分散、可以拿到外部獨立驗證集。樣本篩選這一步很多人忽略其實直接影響模型質(zhì)量。我用的篩選規(guī)則如下只保留原發(fā)腫瘤樣本剔除正常組織樣本和轉(zhuǎn)移灶樣本。正常組織在甲基化層面和腫瘤差異極大混在一起模型會學(xué)到“這是不是腫瘤”而不是“腫瘤預(yù)后如何”。刪除生存時間缺失、生存狀態(tài)缺失的樣本。刪除隨訪時間小于30天的樣本。隨訪太短的患者大概率還沒觀察到事件就被截尾留在數(shù)據(jù)集里會給模型帶來混亂信息。生存時間單位統(tǒng)一成“月”。我遇到過一版數(shù)據(jù)里天數(shù)、月數(shù)混用模型損失函數(shù)直接異常波動。這些規(guī)則不復(fù)雜但每一條都是真實問題。特別是隨訪時間篩除很多公開數(shù)據(jù)集里確實有“診斷后兩周死亡”這種樣本它們對標(biāo)準(zhǔn)的生存分析損失函數(shù)影響極大。2.2 多維組學(xué)數(shù)據(jù)的規(guī)范化處理要點下表匯總了四類常見組學(xué)數(shù)據(jù)的處理要點數(shù)據(jù)類型原始數(shù)據(jù)形態(tài)常用歸一化方法關(guān)鍵預(yù)處理動作轉(zhuǎn)錄組表達(dá)原始count矩陣或FPKMTMM歸一化后轉(zhuǎn)log2低表達(dá)基因過濾基因名去重miRNA表達(dá)count矩陣同轉(zhuǎn)錄組邏輯注意成熟體命名規(guī)范去批次DNA甲基化Beta值0到1之間轉(zhuǎn)M值后標(biāo)準(zhǔn)化去性染色體探針去SNP相關(guān)探針拷貝數(shù)變異GISTIC2.0分段值直接標(biāo)準(zhǔn)化或離散化大批量0值保留分段水平轉(zhuǎn)錄組表達(dá)我最常用的是edgeR包的TMMtrimmed mean of M-values歸一化然后做log2(x1)變換。注意RNA-seq的count矩陣和芯片的熒光信號強(qiáng)度矩陣統(tǒng)計特性完全不同如果在同一數(shù)據(jù)集中混用了兩種平臺后續(xù)批次校正會更難處理。甲基化數(shù)據(jù)是重災(zāi)區(qū)。450K或EPIC芯片有約四十五萬個CpG位點但其中有很多探針是落在性染色體上的還有一些和已知SNP位點重疊、容易受基因型影響的探針這些都需要在預(yù)處理階段刪掉。另外Beta值分布偏斜通常轉(zhuǎn)成M值M log2(Beta / (1 - Beta))再做后續(xù)分析M值更接近正態(tài)分布比較適合做線性建模。拷貝數(shù)變異數(shù)據(jù)相對簡單GISTIC2.0輸出的是每個樣本每個片段的拷貝數(shù)狀態(tài)大量位點是0值。直接數(shù)值化時我一般保留連續(xù)的GISTIC分值不做離散化讓模型自己去學(xué)0值背后的分布規(guī)律。2.3 批次效應(yīng)校正和樣本配對問題這批樣本來自不同測序中心、不同時期、不同平臺批次效應(yīng)無可避免。我用的標(biāo)準(zhǔn)工具是sva包的ComBat函數(shù)核心思想是假設(shè)不同批次之間存在一個系統(tǒng)性偏移用經(jīng)驗貝葉斯方法估計并去除這個偏移。這里必須強(qiáng)調(diào)所有批次校正都必須在訓(xùn)練集內(nèi)部完成并且要把校正參數(shù)保存下來后續(xù)外部驗證數(shù)據(jù)應(yīng)用的是完全相同的參數(shù)不能重新擬合。這一點和標(biāo)準(zhǔn)化問題很像做錯了就是數(shù)據(jù)泄露。樣本配對是另一個大坑。不同組學(xué)數(shù)據(jù)的樣本ID寫法可能不同有的是TCGA-XX-XXXX有的是純數(shù)字序號還有的是GEO平臺的GSM編號。我寫了一個統(tǒng)一的清洗腳本先做ID格式規(guī)范化再做交集合并。同時強(qiáng)烈建議在合并前看一眼各平臺的樣本重疊情況。我遇到過某數(shù)據(jù)集表達(dá)平臺有1100個樣本甲基化只有650個最后配對完只剩520個。這種掉樣本現(xiàn)象是合理的但你要心里有數(shù)樣本量縮水的速度比你想象中快得多。3. 特征篩選決定模型上限的環(huán)節(jié)預(yù)處理做完之后各組學(xué)數(shù)據(jù)還是幾十萬維。這個規(guī)模直接送進(jìn)神經(jīng)網(wǎng)絡(luò)大概率是災(zāi)難。我用到的策略是分層篩選每層用一個相對輕量的算法砍掉大量無關(guān)特征最后把特征數(shù)量控制在可管理范圍內(nèi)。3.1 第一層過濾差異分析 單因素Cox第一步是降維目標(biāo)很簡單把明顯沒有區(qū)分能力的特征刪掉。對轉(zhuǎn)錄組數(shù)據(jù)先做低表達(dá)過濾保留在超過20%樣本中表達(dá)量大于某個閾值的基因。這一步就能砍掉不少背景噪音。然后做差異表達(dá)分析比較高風(fēng)險組和低風(fēng)險組的表達(dá)差異。但這里有個容易混淆的地方——預(yù)后模型更需要的是“與生存時間相關(guān)的基因”不只是“差異表達(dá)的基因”。所以更主流的做法是直接做單因素Cox回歸對每個基因單獨擬合一個比例風(fēng)險模型看p值是否顯著。具體操作上可以用lifelines庫或者R里的survival包對標(biāo)準(zhǔn)化后的特征逐個建模保留p值小于0.05的特征。做這一步時要注意表達(dá)量接近零的基因它們的HR會出現(xiàn)極端的離群值比如幾百甚至上萬因為cox模型的指數(shù)函數(shù)對數(shù)值太敏感。所以務(wù)必先過濾低表達(dá)/低變異特征再跑單因素Cox。3.2 第二層壓縮LASSO-Cox交叉驗證單因素Cox篩完后特征數(shù)量通常還在幾千到一萬之間。下一步我推薦LASSO-CoxL1正則化的Cox回歸它對高維特征有多重共線性下壓縮變量的能力通過懲罰項把無關(guān)特征的系數(shù)壓成零得到稀疏解。LASSO-Cox實現(xiàn)上我用的是R中g(shù)lmnet包的cv.glmnet函數(shù)選擇lambda時有兩個常見選擇——lambda.min和lambda.1se。lambda.min是交叉驗證誤差最小的lambda值特征保留相對多擬合能力強(qiáng)但稍微復(fù)雜。lambda.1se是在最小誤差一個標(biāo)準(zhǔn)差范圍內(nèi)的最大lambda特征更稀疏模型更穩(wěn)定。建議默認(rèn)用lambda.1se尤其后面還要接神經(jīng)網(wǎng)絡(luò)融合模塊前面特征別再留太多冗余。做完LASSO之后我還會跑一遍隨機(jī)生存森林Random Survival Forest用它的特征重要性做交叉驗證。兩套算法都保留下來的特征才是最終進(jìn)入融合模型的候選集。3.3 一個可以直接抄的篩選流水線整個特征篩選流水線可以總結(jié)成下面這幾個步驟每一步的輸入輸出都是前一步的下游方差過濾去掉近零方差特征。對甲基化數(shù)據(jù)尤其重要幾十萬探針里很大一部分在所有樣本中都沒有變化。差異分析高風(fēng)險組vs低風(fēng)險組挑出組間差異明顯的特征。單因素Cox每個特征獨立做生存關(guān)聯(lián)分析保留p小于0.05的特征。LASSO-Cox交叉驗證用lambda.1se選擇最終的稀疏特征集。RSF重要性核對確認(rèn)LASSO選出的特征與隨機(jī)生存森林的重要性排名方向一致。經(jīng)過這套流程轉(zhuǎn)錄組通常保留50到150個基因甲基化保留30到80個CpG位點拷貝數(shù)和miRNA各保留20到50個。總體控制在150到300個特征之間這時候再做多組學(xué)融合維度才合理。注意特征篩選全過程只使用訓(xùn)練集。很多項目在外部隊列上性能崩盤就是因為篩選特征時用了全量數(shù)據(jù)相當(dāng)于讓驗證集的信息提前進(jìn)入了模型。4. 多組學(xué)融合模型設(shè)計為什么不能簡單拼接特征準(zhǔn)備好之后接下來的核心問題就是怎么融合。這塊我認(rèn)真比較過三種方案早期拼接、中期融合、晚期集成。4.1 三種融合策略選型早期融合最簡單把各組學(xué)特征拼成一個長向量直接喂給模型。好處是容易實現(xiàn)壞處也很明顯一方面各組學(xué)內(nèi)部的結(jié)構(gòu)信息被淹沒在長向量里另一方面不同組學(xué)特征數(shù)量差異巨大數(shù)量多的組學(xué)容易主導(dǎo)模型訓(xùn)練。中期融合是給每個組學(xué)單獨一個編碼器各自學(xué)出特征表示然后通過一個融合模塊組合各個表示向量。這種方案的優(yōu)點是各組學(xué)先做了一次信息壓縮融合模塊可以更公平地對待每個組學(xué)。晚期集成則是每組學(xué)單獨訓(xùn)練模型最后把預(yù)測打分平均或加權(quán)。這個方案實現(xiàn)獨立性最強(qiáng)但組學(xué)之間的交互信息完全丟失性能相對受限。融合策略實現(xiàn)難度組學(xué)交互可解釋性實測效果早期拼接低低差一般中期融合中高高較好最好晚期集成低無好中等我最后選了中期融合并在融合模塊上加了注意力機(jī)制讓模型自己學(xué)習(xí)不同組學(xué)在預(yù)測時的重要性權(quán)重。4.2 自適應(yīng)注意力融合模塊的實現(xiàn)細(xì)節(jié)融合模塊的設(shè)計思路比較簡單每組學(xué)特征先進(jìn)過一個兩層的MLP編碼器把不同維度的特征壓縮到同一維度的表示向量然后計算每個組學(xué)表示向量的注意力權(quán)重加權(quán)求和。為了深度我再包了一層多頭注意力加殘差連接。這里給出核心部分的偽代碼import torch import torch.nn as nn class OmicsEncoder(nn.Module): def __init__(self, input_dim, hidden_dim128, output_dim128): super().__init__() self.net nn.Sequential( nn.Linear(input_dim, hidden_dim), nn.BatchNorm1d(hidden_dim), nn.ReLU(), nn.Dropout(0.3), nn.Linear(hidden_dim, output_dim) ) def forward(self, x): return self.net(x) class AttentionFusion(nn.Module): def __init__(self, omics_dims, hidden_dim128): super().__init__() # omics_dims 是每個組學(xué)篩選后的特征維度列表 self.encoders nn.ModuleList([ OmicsEncoder(dim, hidden_dim) for dim in omics_dims ]) # 注意力打分網(wǎng)絡(luò) self.attn nn.Linear(hidden_dim, 1) def forward(self, omics_list): representations [] for encoder, x in zip(self.encoders, omics_list): representations.append(encoder(x)) # representations: list of tensors, each (batch, hidden_dim) reps torch.stack(representations, dim1) # (batch, n_omics, hidden_dim) scores self.attn(reps).squeeze(-1) # (batch, n_omics) weights torch.softmax(scores, dim1) fused torch.sum(weights.unsqueeze(-1) * reps, dim1) return fused, weights這個模塊在實際運行中非常穩(wěn)定而且訓(xùn)練完可以直接輸出每個樣本的組學(xué)注意力權(quán)重能用來分析“這個患者是哪類組學(xué)數(shù)據(jù)主導(dǎo)了風(fēng)險預(yù)測”。我在系統(tǒng)里把這些權(quán)重一起展示出來臨床老師看了也覺得有價值。4.3 生存損失函數(shù)與訓(xùn)練策略融合表示向量后面接一個輸出層得到風(fēng)險分?jǐn)?shù)h(x)訓(xùn)練目標(biāo)用Cox偏似然損失。公式是L -Σ_{i: event_i1} [ h(x_i) - log Σ_{j: t_j t_i} exp(h(x_j)) ]這里每個事件樣本的風(fēng)險集是該時點仍存活的所有樣本分母對風(fēng)險集中的樣本求和。這個損失直接優(yōu)化排序目標(biāo)比用分類模型預(yù)測“會不會復(fù)發(fā)”更合理。實現(xiàn)時要注意數(shù)值穩(wěn)定性常見的做法是先對h(x)做max減法再算logsumexp。PyTorch里頭直接用torch.logsumexp就行。訓(xùn)練配置我給了個常規(guī)方案AdamW優(yōu)化器學(xué)習(xí)率1e-3weight_decay 1e-4批大小64訓(xùn)練最多200個epoch早停patience設(shè)為15監(jiān)控驗證集的C-index。所有編碼器的輸出維度統(tǒng)一設(shè)成128dropout設(shè)0.3防止多層結(jié)構(gòu)過擬合。有一點需要強(qiáng)調(diào)生存數(shù)據(jù)有大量右刪失樣本損失函數(shù)只對事件樣本的偏似然做求和但刪失樣本仍然參與風(fēng)險集計算所以訓(xùn)練時不需要刻意做類別平衡。真正需要注意的反而是刪失比例過高比如超過80%時模型很難學(xué)到有效信號這時候更要依賴特征篩選階段保留那些與生存強(qiáng)相關(guān)的特征。5. 系統(tǒng)落地從Jupyter到可交付API模型在Jupyter里跑通只是一半工作后面要把它封裝成別人能用的系統(tǒng)。這個環(huán)節(jié)看上去瑣碎但直接決定了項目能不能真正交付。5.1 模型封裝與預(yù)處理參數(shù)固化最核心的思路是“把整個預(yù)處理流程固化成一次性的配置文件”。不能幻想部署時再跑一遍歸一化腳本必須把下面這些內(nèi)容全部序列化保存特征名單每個組學(xué)最終入選的特征名列表存成JSON。標(biāo)準(zhǔn)化參數(shù)每個特征的均值和標(biāo)準(zhǔn)差注意是訓(xùn)練集上的值。批次校正參數(shù)ComBat的估計參數(shù)。編碼器和融合模型的權(quán)重統(tǒng)一的torch checkpoint。推理版本信息記錄模型訓(xùn)練時的數(shù)據(jù)處理邏輯。推理函數(shù)接受原始數(shù)據(jù)作為輸入內(nèi)部按順序處理匹配特征名、缺失值用中位數(shù)填充、按保存的參數(shù)做標(biāo)準(zhǔn)化、調(diào)用模型得到風(fēng)險分?jǐn)?shù)。缺失值處理這里也特別說一下公共數(shù)據(jù)庫的輸入數(shù)據(jù)幾乎不可能特征全齊常見的單個樣本會有百分之幾的基因缺失。我實測下來用整個訓(xùn)練集中位數(shù)填充的效果比行刪除好很多模型穩(wěn)定性明顯提升。5.2 后端API實現(xiàn)我用FastAPI搭了一個輕量級后端提供一個POST接口接收樣本數(shù)據(jù)返回風(fēng)險分?jǐn)?shù)、風(fēng)險分層和生存概率。from fastapi import FastAPI from pydantic import BaseModel app FastAPI() class SampleRequest(BaseModel): sample_id: str expression: dict # 基因名 - 表達(dá)值 methylation: dict # CpG位點 - Beta值 cnv: dict # 片段名 - 拷貝數(shù)值 app.post(/predict) async def predict(req: SampleRequest): features preprocess(req) # 內(nèi)部含特征對齊、缺失填充、標(biāo)準(zhǔn)化 risk_score model.risk(features) prob_1y, prob_3y, prob_5y model.survival_probability(features) return { sample_id: req.sample_id, risk_score: risk_score, risk_level: high if risk_score cutoff else low, survival_prob: { 1y: prob_1y, 3y: prob_3y, 5y: prob_5y } }這里有一個必須提到的輸入校驗如果提交數(shù)據(jù)的特征缺失率超過10%直接返回錯誤提示而不是默默填一堆中位數(shù)進(jìn)去。缺失太多時填充分?jǐn)?shù)失真預(yù)測結(jié)果不可信。演示界面我用了Gradio三分鐘就能搭一個上傳CSV、返回可視化結(jié)果的交互頁面。它非常適合給非工程背景的課題組成員做演示比直接丟API方便得多。5.3 可解釋性輸出SHAP與KM曲線一個預(yù)測系統(tǒng)只輸出一個風(fēng)險分?jǐn)?shù)對臨床合作方來說遠(yuǎn)遠(yuǎn)不夠。他們一定會問“為什么這個患者被判成高風(fēng)險”。所以我額外加了一個可解釋性模塊。SHAP分析可以計算每個特征對風(fēng)險分?jǐn)?shù)的貢獻(xiàn)而且能在樣本級別給出解釋。轉(zhuǎn)錄組特征、甲基化位點、拷貝數(shù)值各自的影響一目了然。同時按風(fēng)險分?jǐn)?shù)中位數(shù)把患者分為高低風(fēng)險兩組畫出Kaplan-Meier生存曲線并輸出log-rank檢驗的p值。這條曲線在論文和匯報中都是最有說服力的單圖。還有校準(zhǔn)曲線和決策曲線分析DCA。校準(zhǔn)曲線看的是模型預(yù)測的生存概率和實際觀察概率是否一致DCA則衡量模型在不同閾值下的臨床凈獲益。這兩個指標(biāo)是我交付時必出的圖也是很多審稿人關(guān)注的對象??山忉屝阅K看起來不算核心功能但在實際項目評審時的價值甚至超過了預(yù)測精度本身。這條經(jīng)驗值得認(rèn)真體會。6. 效果驗證與踩坑實錄模型好不好不能只看訓(xùn)練集指標(biāo)。驗證環(huán)節(jié)如果做得不嚴(yán)謹(jǐn)整個系統(tǒng)就是空中樓閣。6.1 內(nèi)部驗證和外部驗證分別該看什么內(nèi)部驗證方面我用分層劃分的方式按7比3拆分訓(xùn)練集和測試集保持刪失比例兩組近似然后做五折重復(fù)實驗。報告指標(biāo)時C-index要給出均值和標(biāo)準(zhǔn)差最好也附95%置信區(qū)間。只看一個最好試次的數(shù)字那絕對是對自己耍流氓。時間依賴AUC也要報告1年、3年、5年的數(shù)值不能只報一個C-index。C-index是全局一致性指標(biāo)它無法告訴你模型在短期預(yù)后預(yù)測是否準(zhǔn)確。我系統(tǒng)里的最終內(nèi)部測試結(jié)果穩(wěn)定在C-index約0.821年AUC約0.803年AUC約0.835年AUC約0.78。外部驗證是真正的試金石。公共數(shù)據(jù)庫里找一個獨立數(shù)據(jù)源應(yīng)用之前保存的完整預(yù)處理參數(shù)和模型權(quán)重只做特征映射和標(biāo)準(zhǔn)化不做任何重新擬合。外部數(shù)據(jù)集的C-index比內(nèi)部低0.05到0.1是非常正常的這反映了域偏移。如果外部驗證下降幅度超過0.15就要懷疑特征篩選階段是否發(fā)生過數(shù)據(jù)泄露或者訓(xùn)練集過擬合太嚴(yán)重。6.2 實測中踩過的三個坑第一個坑標(biāo)準(zhǔn)化數(shù)據(jù)泄露。早期版本我在全數(shù)據(jù)集上計算了每個特征的均值標(biāo)準(zhǔn)差然后再拆分訓(xùn)練測試集。結(jié)果內(nèi)部C-index虛高了0.05。這個問題非常隱蔽因為指標(biāo)看起來一切正常直到換新數(shù)據(jù)做外部驗證才發(fā)現(xiàn)慘不忍睹。第二個坑甲基化特征沒做好預(yù)篩直接把數(shù)千個探針?biāo)瓦M(jìn)編碼器。模型訓(xùn)練C-index沖到0.95測試集只有0.65這是典型的過擬合。問題出在甲基化特征經(jīng)過單因素Cox篩選后仍然保留了太多位點而樣本量只有四百多編碼器參數(shù)一多就立刻開始背答案。第三個坑外部驗證平臺的批次效應(yīng)。我用一個RNA-seq平臺訓(xùn)練的模型去驗證另一個芯片平臺的數(shù)據(jù)ID對齊之后發(fā)現(xiàn)表達(dá)值分布差異巨大特征縮放到同一尺度后仍然有系統(tǒng)性偏差。后來我干脆在系統(tǒng)上明確區(qū)分了適用平臺類型并在輸入校驗中加入了分布偏移預(yù)警。6.3 常見問題速查表現(xiàn)象可能原因解決方法訓(xùn)練C-index極高測試集暴跌過擬合或數(shù)據(jù)泄露檢查是否在全數(shù)據(jù)上做過標(biāo)準(zhǔn)化加大dropout和正則化外部驗證C-index遠(yuǎn)低于內(nèi)部批次效應(yīng)、平臺差異檢查預(yù)處理參數(shù)是否復(fù)用用ComBat校正后統(tǒng)一參數(shù)損失函數(shù)一開始就是NaN生存時間單位混亂統(tǒng)一用月檢查有無0或負(fù)生存時間組學(xué)注意力權(quán)重嚴(yán)重偏向某一種特征數(shù)量不平衡調(diào)整編碼器輸出維度各組學(xué)特征數(shù)盡量均衡刪失樣本太多模型不收斂風(fēng)險集信息不足加強(qiáng)特征篩選考慮換排序損失或DeepHit輸入樣本缺失率過高結(jié)果異常填充失真添加缺失率校驗缺失超10%直接拒絕預(yù)測我在交付前還會加一道數(shù)據(jù)完整性測試用完全不相關(guān)的隨機(jī)輸入跑一遍推理確認(rèn)系統(tǒng)不會崩潰并對輸入數(shù)據(jù)的特征分布做分布偏移檢測。這些防御性邏輯是系統(tǒng)工程項目和實驗代碼的區(qū)別也是花時間打磨的地方。最后再分享一點個人體會這套多組學(xué)系統(tǒng)從頭到尾走下來我最大的感受是在多組學(xué)項目里數(shù)據(jù)理解和特征工程的重要性遠(yuǎn)大于模型結(jié)構(gòu)本身。同一個融合模型前面數(shù)據(jù)處理差一步最終指標(biāo)能差出十個點。后來再接到新的癌種需求我基本都是老路徑先跑預(yù)處理流程照搬特征篩選快速重跑模型結(jié)構(gòu)幾乎不需要改動。系統(tǒng)交付時最受歡迎的不是那個創(chuàng)新模型而是帶可視化解釋的Web界面和清晰的驗證報告。做項目做系統(tǒng)最終評價標(biāo)準(zhǔn)永遠(yuǎn)是能不能讓使用者真正理解和信任這個模型。