踐:合成醫(yī)療數(shù)據(jù)解決隱私與樣本不均衡難題)
最近幫某團(tuán)隊(duì)做醫(yī)療AI項(xiàng)目碰到一個(gè)很現(xiàn)實(shí)的難題模型效果已經(jīng)到瓶頸想再提升就得拿更多真實(shí)病歷來訓(xùn)練可醫(yī)院那邊的數(shù)據(jù)管理非常嚴(yán)格別說導(dǎo)出原始數(shù)據(jù)連在開發(fā)機(jī)上查看脫敏后的樣本都要走審批流程跑一輪下來一周時(shí)間就沒了。后來我們換了思路讓原始數(shù)據(jù)留在內(nèi)網(wǎng)先用字段統(tǒng)計(jì)和分布分析把數(shù)據(jù)規(guī)律摸清楚再用CTGAN訓(xùn)練一個(gè)生成模型把模型參數(shù)帶出來批量生成合成醫(yī)療數(shù)據(jù)用于后續(xù)開發(fā)。整個(gè)過程走完我最大的感受是合成數(shù)據(jù)不是“憑空造數(shù)據(jù)”而是把真實(shí)數(shù)據(jù)的統(tǒng)計(jì)規(guī)律“遷移”出來。這篇文章會(huì)把我的方案選型、訓(xùn)練配置、質(zhì)量評(píng)估方法、隱私風(fēng)險(xiǎn)控制以及幾次翻車后總結(jié)的排查經(jīng)驗(yàn)都整理出來給正在做同類事情的讀者一份能直接抄作業(yè)的參考。1. 項(xiàng)目背景與整體設(shè)計(jì)思路1.1 醫(yī)療數(shù)據(jù)為什么這么難用醫(yī)療數(shù)據(jù)有兩個(gè)天然痛點(diǎn)隱私等級(jí)高和樣本分布極不均衡。我參與的這個(gè)項(xiàng)目屬于慢病管理方向原始數(shù)據(jù)集來自某合作醫(yī)院的信息系統(tǒng)字段包括年齡、性別、主診斷、合并癥數(shù)量、收縮壓、空腹血糖、總膽固醇、是否30天內(nèi)再入院等??倶颖玖考s為12000條聽起來不算少但真正“再入院”的陽性樣本只有800條左右。直接把這種不平衡數(shù)據(jù)丟給模型訓(xùn)練模型很容易偷懶把所有樣本都預(yù)測(cè)成“不再入院”因?yàn)檫@樣準(zhǔn)確率也能到百分之九十以上。想解決樣本不均衡常規(guī)做法是先做上采樣或者過采樣。但問題是醫(yī)療字段之間不是簡(jiǎn)單的線性關(guān)系比如血糖異常和主診斷類別之間、合并癥數(shù)量與再入院風(fēng)險(xiǎn)之間都存在復(fù)雜的交互。用傳統(tǒng)插值方式生造出來的樣本醫(yī)生一眼就能看出不合理放到模型里反而會(huì)引入噪聲。另一個(gè)更棘手的問題是數(shù)據(jù)出不了內(nèi)網(wǎng)。醫(yī)院允許你在內(nèi)網(wǎng)環(huán)境里查看統(tǒng)計(jì)結(jié)果但原始記錄級(jí)數(shù)據(jù)不能直接拷貝到外部開發(fā)環(huán)境。這就意味著要么開發(fā)團(tuán)隊(duì)全部搬進(jìn)醫(yī)院駐場(chǎng)要么找到一種能把“數(shù)據(jù)規(guī)律”帶出來但不暴露個(gè)體記錄的方法。合成數(shù)據(jù)正好卡在這個(gè)需求點(diǎn)上。1.2 合成數(shù)據(jù)在項(xiàng)目里的實(shí)際定位很多人對(duì)合成數(shù)據(jù)有誤解以為它是用來“以假亂真”糊弄項(xiàng)目的。其實(shí)不是。在我們這個(gè)項(xiàng)目里合成數(shù)據(jù)的定位非常明確作為研發(fā)階段的模型訓(xùn)練原料和算法調(diào)試數(shù)據(jù)而絕對(duì)不替代真實(shí)數(shù)據(jù)做臨床驗(yàn)證。具體用途有三個(gè)第一個(gè)是模型訓(xùn)練。我們把合成數(shù)據(jù)下發(fā)到外部GPU服務(wù)器上用來做特征篩選、超參數(shù)搜索、模型結(jié)構(gòu)對(duì)比。這些實(shí)驗(yàn)每天要跑幾十輪如果都用真實(shí)數(shù)據(jù)光審批流程就夠讓人崩潰。第二個(gè)是算法演示。項(xiàng)目要做成果匯報(bào)需要跑一個(gè)交互式demo給業(yè)務(wù)方看。真實(shí)數(shù)據(jù)不能出現(xiàn)在演示環(huán)境里合成數(shù)據(jù)可以放心展示字段結(jié)構(gòu)、統(tǒng)計(jì)分布都跟真實(shí)數(shù)據(jù)高度接近演示效果不打折扣。第三個(gè)是跨團(tuán)隊(duì)協(xié)作。標(biāo)注團(tuán)隊(duì)、算法團(tuán)隊(duì)、測(cè)試團(tuán)隊(duì)分散在不同地點(diǎn)原始數(shù)據(jù)無法共享。合成數(shù)據(jù)作為“公共數(shù)據(jù)集”讓各團(tuán)隊(duì)在統(tǒng)一的數(shù)據(jù)形態(tài)下工作避免每個(gè)人都去申請(qǐng)?jiān)紨?shù)據(jù)權(quán)限。但這里必須提醒一句合成數(shù)據(jù)再怎么逼真也不能用于診斷決策支持系統(tǒng)的最終臨床驗(yàn)證。它保住了分布的“形”但未必保住了所有醫(yī)學(xué)邏輯的“神”尤其是罕見并發(fā)癥、極端生理狀態(tài)這些長(zhǎng)尾情況合成數(shù)據(jù)很難覆蓋完整。項(xiàng)目里一定要把這條邊界劃清楚。1.3 為什么最終選了CTGAN而不是其他方案做表格式合成數(shù)據(jù)的方案其實(shí)不少我在項(xiàng)目初期也做過一輪對(duì)比包括SMOTE、VAE、貝葉斯網(wǎng)絡(luò)和CTGAN。簡(jiǎn)單說下我的判斷依據(jù)。SMOTE的原理是在現(xiàn)有樣本的近鄰之間做線性插值適合處理連續(xù)值主導(dǎo)的小規(guī)模不平衡數(shù)據(jù)但它幾乎不會(huì)產(chǎn)生“新組合”只是在已有樣本的鄰域內(nèi)打轉(zhuǎn)而且對(duì)離散特征的支持很差。放在醫(yī)療數(shù)據(jù)這種離散列多、類別組合復(fù)雜的場(chǎng)景里效果不好。VAE訓(xùn)練穩(wěn)定生成速度也快但生成的數(shù)值普遍偏“糊”連續(xù)變量的分布會(huì)被過度平滑類別變量容易出現(xiàn)模棱兩可的概率輸出。對(duì)于需要精確模擬多峰分布的場(chǎng)景VAE不夠用。貝葉斯網(wǎng)絡(luò)這類方法擅長(zhǎng)描述離散變量之間的條件依賴可一旦連續(xù)變量占比高網(wǎng)絡(luò)結(jié)構(gòu)學(xué)習(xí)就會(huì)變得困難而且對(duì)字段間復(fù)雜非線性交互的表達(dá)能力有限。CTGAN屬于GAN家族專門為表格數(shù)據(jù)設(shè)計(jì)。它最大的優(yōu)勢(shì)是同時(shí)處理離散列和連續(xù)列連續(xù)列的多峰分布有對(duì)應(yīng)的歸一化機(jī)制離散列的稀有類別有專門的條件生成策略。雖然訓(xùn)練不穩(wěn)定、調(diào)參成本高但在生成質(zhì)量上限上明顯優(yōu)于前面幾種方案。方案連續(xù)值多峰分布離散稀有類別生成新組合訓(xùn)練穩(wěn)定性SMOTE差差差穩(wěn)定VAE中中中穩(wěn)定貝葉斯網(wǎng)絡(luò)中中中穩(wěn)定CTGAN好好好需調(diào)參實(shí)際項(xiàng)目里我們也不是完全排斥其他方法。數(shù)據(jù)量只有幾百條時(shí)貝葉斯網(wǎng)絡(luò)反而比CTGAN更實(shí)用但如果要生成幾萬條且要求分布接近真實(shí)數(shù)據(jù)CTGAN是更合適的選擇。2. CTGAN核心機(jī)制拆解它到底改進(jìn)了什么2.1 把GAN用到表格數(shù)據(jù)上難在哪GAN的基本思路是讓兩個(gè)網(wǎng)絡(luò)互相博弈生成器負(fù)責(zé)從隨機(jī)噪聲中偽造樣本判別器負(fù)責(zé)分辨輸入是真實(shí)樣本還是偽造樣本。訓(xùn)練的目標(biāo)是讓生成器產(chǎn)出的數(shù)據(jù)越來越接近真實(shí)分布直到判別器分不出來。打個(gè)通俗的比方生成器是印假鈔的判別器是驗(yàn)鈔的假鈔印得越真驗(yàn)鈔的水平也被逼得越高最后兩邊達(dá)到動(dòng)態(tài)平衡。但圖像GAN可以直接把像素矩陣當(dāng)作連續(xù)向量處理表格數(shù)據(jù)就不一樣了。表格里每一列都有明確的業(yè)務(wù)含義變量類型混合有的列是連續(xù)值比如血糖的數(shù)值有的列是離散值比如性別、診斷類別。離散值不能直接走梯度下降因?yàn)椤叭∧膫€(gè)類別”是一個(gè)不可微的選擇。更麻煩的是連續(xù)變量往往不是簡(jiǎn)單的高斯分布血糖數(shù)據(jù)可能出現(xiàn)“低、正常、高”三個(gè)峰訓(xùn)練時(shí)如果拿單一正態(tài)分布去擬合生成出來的數(shù)值大概率都會(huì)聚集在平均值附近完全丟失多峰信息。CTGAN在論文里提出了三個(gè)關(guān)鍵設(shè)計(jì)來應(yīng)對(duì)這些問題模式歸一化、條件生成、以及離散列的softmax映射。下面逐個(gè)說。2.2 模式歸一化先選“峰”再定“值”模式歸一化是CTGAN處理連續(xù)列的核心手段也是它區(qū)別于普通GAN的關(guān)鍵設(shè)計(jì)。面對(duì)一個(gè)多峰的連續(xù)變量CTGAN不會(huì)嘗試用一個(gè)高斯分布去描述整個(gè)分布而是先用變分高斯混合模型估計(jì)這個(gè)變量的概率密度分布自動(dòng)找出若干個(gè)高斯分量每個(gè)分量對(duì)應(yīng)一個(gè)“模式”。以空腹血糖為例模型可能學(xué)出“低血糖區(qū)間”“正常空腹區(qū)間”“偏高區(qū)間”三個(gè)模式每個(gè)模式都有自己的均值和方差。生成數(shù)據(jù)時(shí)分成兩步第一步根據(jù)模式權(quán)重隨機(jī)選擇一個(gè)模式第二步在選定模式對(duì)應(yīng)的歸一化空間里生成一個(gè)連續(xù)數(shù)值再逆變換回真實(shí)范圍。這樣一來生成器不需要直接預(yù)測(cè)血糖數(shù)值而是先做一次“模式選擇”再在模式內(nèi)部做精細(xì)的數(shù)值生成多峰特性就能被保留下來。這里有一個(gè)人工干預(yù)的小技巧如果業(yè)務(wù)上你知道某個(gè)連續(xù)變量的峰數(shù)或者大概分布形態(tài)可以在預(yù)處理階段做一次對(duì)數(shù)變換或者分組統(tǒng)計(jì)幫助模型更穩(wěn)定地?cái)M合。但別做過頭比如手動(dòng)把連續(xù)變量強(qiáng)制分箱會(huì)讓CTGAN的模式歸一化失去意義生成質(zhì)量反而變差。2.3 條件生成與按頻率采樣保住稀有類別醫(yī)療數(shù)據(jù)里類別不平衡是常態(tài)。比如“30天內(nèi)再入院”這個(gè)標(biāo)簽只有6.7%的陽性率再比如某個(gè)主診斷類別只出現(xiàn)了十幾次。傳統(tǒng)GAN訓(xùn)練時(shí)生成器會(huì)傾向于只生成高頻類別因?yàn)檫@樣最容易騙過判別器結(jié)果是合成數(shù)據(jù)里罕見類別幾乎消失相當(dāng)于把本來就稀少的信息又丟掉了一部分。CTGAN的做法是引入條件生成機(jī)制。每一條訓(xùn)練樣本都對(duì)應(yīng)一個(gè)條件向量用來指定當(dāng)前批次里應(yīng)該生成哪個(gè)類別。訓(xùn)練時(shí)不是按原始頻率均勻抽樣而是按類別頻率的對(duì)數(shù)來采樣讓稀有類別被“強(qiáng)制”分配到訓(xùn)練批次中。這就是log_frequencyTrue這個(gè)參數(shù)背后的邏輯原始頻率做log變換后高頻類別和低頻類別的采樣差距被壓縮稀有類別不再被淹沒。我直觀測(cè)試過一次同一份數(shù)據(jù)集log_frequency關(guān)閉時(shí)占比0.5%的某個(gè)診斷類別在生成數(shù)據(jù)里幾乎消失只剩幾條打開之后能恢復(fù)到接近真實(shí)比例。如果你發(fā)現(xiàn)合成數(shù)據(jù)的離散列分布明顯偏離真實(shí)數(shù)據(jù)第一排查點(diǎn)就是這里。2.4 離散列如何參與反向傳播離散列的問題在于“選擇類別”這個(gè)動(dòng)作不可微。CTGAN讓生成器為每個(gè)離散列輸出一個(gè)softmax概率分布代表各個(gè)類別的概率再用Gumbel-softmax之類的技巧做近似采樣從而讓梯度能穿過離散選擇回流到生成器。判別器側(cè)也做了配套處理連續(xù)變量和離散變量經(jīng)過嵌入映射后拼接在一起再送入全連接網(wǎng)絡(luò)。這里的目的是讓離散列不再以孤立的one-hot向量形式參與計(jì)算而是先映射到一個(gè)稠密向量空間便于神經(jīng)網(wǎng)絡(luò)捕捉類別之間的潛在關(guān)系。理解了這套機(jī)制你就明白為什么CTGAN的輸入不能帶空值、不能帶純粹的文本長(zhǎng)字符串。它本質(zhì)上是一個(gè)數(shù)值和類別概率的處理框架文本字段必須先做編碼或者直接剔除。3. 數(shù)據(jù)準(zhǔn)備與關(guān)鍵預(yù)處理3.1 字段設(shè)計(jì)不是越多越好很多人在做合成數(shù)據(jù)的第一步就栽了跟頭把能拿到的字段全塞進(jìn)去幾十列往CTGAN里面一丟訓(xùn)練時(shí)間翻倍生成質(zhì)量還稀爛。表格GAN對(duì)字段數(shù)量非常敏感。字段越多生成器需要學(xué)習(xí)的聯(lián)合分布就越復(fù)雜但訓(xùn)練樣本沒有等比例增加最后每個(gè)字段都學(xué)了個(gè)皮毛。我在項(xiàng)目里的做法是先明確業(yè)務(wù)問題需要哪些字段再做回退。比如項(xiàng)目模型預(yù)測(cè)的是“是否30天內(nèi)再入院”那么核心輸入字段就是年齡、性別、主診斷、合并癥數(shù)量、收縮壓、空腹血糖、總膽固醇、再入院標(biāo)簽共8個(gè)字段。其它像住院編號(hào)、科室代碼、醫(yī)生編號(hào)這類純標(biāo)識(shí)性字段統(tǒng)計(jì)意義不大全部剔除。一個(gè)實(shí)用的字段清單示例字段名數(shù)據(jù)類型說明ageint年齡genderstr性別diagnosisstr主診斷類別comorbidity_countint合并癥數(shù)量blood_pressure_systolicfloat收縮壓glucosefloat空腹血糖cholesterolfloat總膽固醇readmissionbool是否30天內(nèi)再入院布爾字段要轉(zhuǎn)成字符串類別“是”/“否”或者0/1CTGAN對(duì)離散列和連續(xù)列的識(shí)別方式不同分類邏輯要明確。3.2 清洗原則別把缺失模式也“洗掉”CTGAN本身不接收空值所以缺失值必須提前處理。但處理方式?jīng)Q定了生成數(shù)據(jù)能否保留真實(shí)數(shù)據(jù)的缺失規(guī)律。我見過兩種極端做法一種是把所有含缺失值的行直接刪掉簡(jiǎn)單粗暴但樣本量小的場(chǎng)景會(huì)損失太多信息另一種是用均值填充所有缺失結(jié)果缺失比例較高的字段被強(qiáng)行填成一個(gè)人為的集中值分布被人為拉瘦。更推薦的做法是把“是否缺失”本身作為一個(gè)類別特征保留。比如“血糖”字段缺失的樣本不要填血糖均值而是給血糖設(shè)一個(gè)“missing”類別或者在另一個(gè)字段上標(biāo)記。這樣CTGAN能學(xué)到“什么情況下血糖容易缺失”這種真實(shí)模式生成的合成數(shù)據(jù)里缺失分布會(huì)更貼近原始數(shù)據(jù)。還有一個(gè)細(xì)節(jié)離群值的處理尺度要控制。血壓值超過300、血糖值為負(fù)數(shù)這類物理上不可能的值直接過濾掉但年齡偏大、血糖偏高等業(yè)務(wù)合理性范圍內(nèi)的“看似異?!辈灰p易刪它們往往是長(zhǎng)尾分布的重要組成刪除后生成數(shù)據(jù)會(huì)把極端風(fēng)險(xiǎn)人群丟掉后續(xù)建模反而會(huì)偏樂觀。3.3 分布檢查提前知道數(shù)據(jù)長(zhǎng)什么樣訓(xùn)練前我會(huì)做一張單變量分布概覽把每個(gè)連續(xù)字段的直方圖和離散字段的柱狀圖打印出來先做到心里有數(shù)。重點(diǎn)關(guān)注三件事連續(xù)字段是否多峰、是否嚴(yán)重右偏、離散字段的類別是否過于稀疏??辞宄笤?zèng)Q定是否需要預(yù)處理。CTGAN自帶的模式歸一化能處理多峰所以一般不需要手動(dòng)分桶但是如果某個(gè)連續(xù)字段嚴(yán)重右偏比如住院費(fèi)用這種動(dòng)輒偏到幾百倍的字段生成器擬合起來還是有壓力。這種字段可以提前做log變換讓分布更集中。不過要注意變換后的數(shù)值在生成之后還要逆變換回原始業(yè)務(wù)單位否則業(yè)務(wù)方拿到的不倫不類。3.4 樣本量參考幾百條和幾萬條策略完全不同CTGAN對(duì)樣本量的容忍度比想象中高但質(zhì)量分水嶺很明顯。樣本量低于500條時(shí)生成結(jié)果幾乎沒有實(shí)用價(jià)值模式學(xué)不完整類別組合稀疏。500到5000條時(shí)能跑通但需要反復(fù)調(diào)參產(chǎn)出只能用于粗篩。5000條以上時(shí)生成的合成數(shù)據(jù)基本可以在研發(fā)階段替代真實(shí)數(shù)據(jù)使用。我們這次用12000條原始數(shù)據(jù)生成了50000條合成樣本分布對(duì)比各項(xiàng)指標(biāo)都達(dá)標(biāo)。如果你的數(shù)據(jù)量很少建議先用貝葉斯網(wǎng)絡(luò)生成一版做基線不要一上來就硬上CTGAN。4. 完整實(shí)操過程訓(xùn)練、生成與評(píng)估4.1 環(huán)境準(zhǔn)備和安裝安裝CTGAN只需要Python環(huán)境和pip但它依賴PyTorch所以機(jī)器的顯卡驅(qū)動(dòng)和CUDA環(huán)境要提前確認(rèn)。如果有GPU訓(xùn)練速度快很多沒有GPU也能跑只是epoch要適當(dāng)減少。pip install ctgan我用的Python版本是3.9。需要注意ctgan的版本差異0.x版本和1.x版本的API有些許變化比如個(gè)別參數(shù)名不同、默認(rèn)值不同。建議安裝后先輸出一下版本再對(duì)著版本查文檔避免看著別人的老代碼報(bào)錯(cuò)。4.2 訓(xùn)練代碼與關(guān)鍵參數(shù)直接放核心訓(xùn)練代碼這段是從項(xiàng)目里抽出來的可用版本。import pandas as pd from ctgan import CTGAN # 讀取原始數(shù)據(jù) real_data pd.read_csv(medical_data.csv) # 指定離散列 discrete_columns [ gender, diagnosis, readmission ] # 初始化CTGAN ctgan CTGAN( epochs300, batch_size500, log_frequencyTrue, verboseTrue, cudaTrue, ) # 訓(xùn)練 ctgan.fit(real_data, discrete_columnsdiscrete_columns) # 生成50000條合成數(shù)據(jù) syn_data ctgan.sample(50000) # 保存 syn_data.to_csv(synthetic_medical.csv, indexFalse)參數(shù)選擇這里說下我的經(jīng)驗(yàn)。epochs不是越大越好。300輪在這個(gè)數(shù)據(jù)規(guī)模下已經(jīng)足夠繼續(xù)增加到500輪以上生成質(zhì)量提升非常有限訓(xùn)練時(shí)間卻成倍增加。判斷標(biāo)準(zhǔn)不是loss而是看生成數(shù)據(jù)的分布指標(biāo)是否收斂。我試過一輪200場(chǎng)的實(shí)驗(yàn)真實(shí)數(shù)據(jù)和合成數(shù)據(jù)在各項(xiàng)指標(biāo)上的差異在300輪之后幾乎沒有變化。batch_size建議在256到1024之間嘗試。醫(yī)學(xué)數(shù)據(jù)字段不多的話500是一個(gè)比較穩(wěn)妥的中間值。batch太小生成器容易被單批次帶偏batch太大訓(xùn)練過程變慢而且稀有類別的條件生成效果會(huì)下降。log_frequencyTrue一定要開上一節(jié)已經(jīng)解釋過原因這里不再重復(fù)。cudaTrue在有GPU的環(huán)境下打開。CPU環(huán)境下也能訓(xùn)只是同一份數(shù)據(jù)可能要多等幾個(gè)小時(shí)。4.3 生成樣本時(shí)的兩個(gè)注意事項(xiàng)sample()函數(shù)接收你想要的條數(shù)但一次性生成幾十萬條可能會(huì)把內(nèi)存吃爆。建議分批次生成每次生成一兩萬條然后拼接保存對(duì)后續(xù)處理也更友好。另外CTGAN的生成過程還依賴隨機(jī)種子。如果你希望實(shí)驗(yàn)結(jié)果可復(fù)現(xiàn)在訓(xùn)練前設(shè)置好隨機(jī)種子import numpy as np import torch np.random.seed(42) torch.manual_seed(42)不過要說明受PyTorch底層并發(fā)影響即使設(shè)了種子跨機(jī)器環(huán)境也不保證完全復(fù)現(xiàn)但同一環(huán)境下基本穩(wěn)定。這個(gè)特性在做實(shí)驗(yàn)對(duì)比時(shí)很重要。4.4 訓(xùn)練過程中的觀察點(diǎn)CTGAN訓(xùn)練時(shí)會(huì)打印一個(gè)個(gè)epoch的進(jìn)度但GAN的loss不像普通分類任務(wù)那樣單調(diào)下降。生成器和判別器在互相博弈loss上下抖動(dòng)是正常的。我見過很多人在這個(gè)階段被嚇到以為模型崩了。實(shí)際上你更應(yīng)該關(guān)注的是每訓(xùn)練幾十輪后生成一批樣本人工看一下字段分布有沒有逐漸向真實(shí)數(shù)據(jù)靠攏。loss數(shù)值本身沒有絕對(duì)意義生成結(jié)果才是檢驗(yàn)標(biāo)準(zhǔn)。實(shí)操中還有一個(gè)冒煙測(cè)試的思路拿真實(shí)數(shù)據(jù)里隨機(jī)抽200條做一個(gè)極小規(guī)模訓(xùn)練把整個(gè)pipeline跑通確認(rèn)代碼沒報(bào)錯(cuò)、生成數(shù)據(jù)能保存再上全量數(shù)據(jù)。這樣能省下大量排錯(cuò)時(shí)間。5. 質(zhì)量評(píng)估與隱私風(fēng)險(xiǎn)控制5.1 相似度評(píng)估從三個(gè)層面打分很多人覺得合成數(shù)據(jù)“看起來像”就行了這不夠。我用三個(gè)層面的指標(biāo)來評(píng)估缺一個(gè)都不放心。第一層是單變量分布。對(duì)連續(xù)字段比較真實(shí)數(shù)據(jù)和合成數(shù)據(jù)的均值、標(biāo)準(zhǔn)差、分位數(shù)再用KS檢驗(yàn)看分布是否一致p值大于0.05通常說明沒有顯著差異。對(duì)離散字段對(duì)比每個(gè)類別的占比計(jì)算相對(duì)誤差。第二層是多變量相關(guān)性。單變量分布一致不代表變量之間的關(guān)系也一致。我計(jì)算真實(shí)數(shù)據(jù)和合成數(shù)據(jù)的Pearson相關(guān)系數(shù)矩陣然后對(duì)比兩者差值。比如真實(shí)數(shù)據(jù)中“年齡”和“再入院”之間有0.3的正相關(guān)如果合成數(shù)據(jù)里這個(gè)相關(guān)系數(shù)變成0.05說明變量關(guān)系丟了。出現(xiàn)這種情況通常要回去調(diào)整epochs和網(wǎng)絡(luò)結(jié)構(gòu)。第三層是模型效用。這是最貼近業(yè)務(wù)的一關(guān)把合成數(shù)據(jù)當(dāng)作訓(xùn)練集真實(shí)數(shù)據(jù)當(dāng)作測(cè)試集跑一個(gè)簡(jiǎn)單的邏輯回歸或者樹模型看AUC表現(xiàn)是否接近真實(shí)數(shù)據(jù)訓(xùn)練出來的基準(zhǔn)。如果能達(dá)到基準(zhǔn)的90%以上說明合成數(shù)據(jù)保留了足夠的預(yù)測(cè)信息。如果連60%都不到說明合成數(shù)據(jù)只是“形態(tài)像”內(nèi)在關(guān)系沒學(xué)好。5.2 隱私風(fēng)險(xiǎn)評(píng)估別只看分布像不像合成數(shù)據(jù)項(xiàng)目的出發(fā)點(diǎn)往往是為了保護(hù)隱私但如果不做風(fēng)險(xiǎn)評(píng)估可能會(huì)鬧出“偽匿名”的笑話。我主要做兩類風(fēng)險(xiǎn)測(cè)試。第一類是最近鄰距離檢查計(jì)算每一條合成記錄到所有真實(shí)記錄的最小歐氏距離。如果大量合成記錄與某條真實(shí)記錄的距離幾乎為零說明生成器把原始樣本“背下來了”這屬于嚴(yán)重的記憶泄露。正常情況下合成數(shù)據(jù)和真實(shí)數(shù)據(jù)的最小距離分布應(yīng)該與真實(shí)數(shù)據(jù)內(nèi)部的最小距離分布接近不能出現(xiàn)大量距離遠(yuǎn)小于正常水平的點(diǎn)。第二類是成員推斷測(cè)試。拿一部分真實(shí)數(shù)據(jù)訓(xùn)練一個(gè)簡(jiǎn)單的二分類器特征保持不變標(biāo)簽是“該樣本是否在訓(xùn)練集中”用合成數(shù)據(jù)和剩下的真實(shí)數(shù)據(jù)做對(duì)照看分類器能不能猜中樣本來源。如果準(zhǔn)確率明顯高于隨機(jī)水平說明合成數(shù)據(jù)攜帶了太多容易被識(shí)別的個(gè)體特征。如果你打算把合成數(shù)據(jù)對(duì)外公開這些測(cè)試必須做。如果只在公司內(nèi)部研發(fā)使用風(fēng)險(xiǎn)等級(jí)可以適當(dāng)降低但對(duì)極端值字段還是建議做一次最近鄰檢查。5.3 差分隱私擴(kuò)展什么時(shí)候值得上CTGAN本身不提供數(shù)學(xué)意義上的隱私保證它只是“讓數(shù)據(jù)不那么容易被還原”。如果業(yè)務(wù)方要求強(qiáng)隱私保證比如對(duì)外發(fā)布數(shù)據(jù)集那就得考慮差分隱私版本。差分隱私的核心思想是在模型訓(xùn)練過程中加入受控噪聲讓輸出結(jié)果對(duì)“某一條具體樣本是否存在”不敏感。聽起來很完美但代價(jià)是生成質(zhì)量明顯下降。我們項(xiàng)目評(píng)估過DP方案的合成數(shù)據(jù)單變量分布還行多變量相關(guān)性損失較大模型效用比普通CTGAN版本低了差不多十個(gè)百分點(diǎn)。我的態(tài)度是內(nèi)部研發(fā)用普通CTGAN數(shù)據(jù)不出內(nèi)網(wǎng)的前提下風(fēng)險(xiǎn)可控外部共享或發(fā)布再上DP方案同時(shí)接受效果折損。不要一上來就追求最強(qiáng)隱私否則業(yè)務(wù)效果可能會(huì)被犧牲到?jīng)]法用。6. 常見問題與排查技巧實(shí)錄6.1 生成結(jié)果全是同一類樣本這是典型的模式崩潰。CTGAN的訓(xùn)練本質(zhì)上是對(duì)抗博弈如果生成器找到一個(gè)能穩(wěn)定騙過判別器的“捷徑”它就會(huì)放棄探索其它模式只輸出同一種樣本。排查時(shí)先確認(rèn)判別器和生成器的結(jié)構(gòu)是否平衡??梢栽龃骲atch_size讓判別器看到更多樣的真實(shí)樣本也可以調(diào)整discriminator_steps參數(shù)增加判別器每輪更新的次數(shù)逼它變得更強(qiáng)迫使生成器提高多樣性。還有一個(gè)笨但有效的辦法把embedding_dim和gen_dim調(diào)小一點(diǎn)限制生成器的容量減少它“死記硬背”的能力。6.2 連續(xù)變量生成出負(fù)值或離譜數(shù)值如果生成數(shù)據(jù)里出現(xiàn)血糖負(fù)數(shù)、收縮壓3000這種物理上不可能的值多半是預(yù)處理階段出了問題。最常見的原因是原數(shù)據(jù)里的離群值沒有清干凈模式歸一化被極端值帶偏導(dǎo)致某個(gè)高斯模式的方差被拉得過大。另一個(gè)原因是對(duì)連續(xù)字段做了過度變換。比如先做z-score標(biāo)準(zhǔn)化再訓(xùn)練CTGAN自己會(huì)再做歸一化一來一回反而放大誤差。建議只保留業(yè)務(wù)上必要的變換比如log變換其他交給模型自己學(xué)。6.3 類別占比和原始數(shù)據(jù)差異大出現(xiàn)這種情況優(yōu)先檢查log_frequency是否開啟。我在項(xiàng)目里做過對(duì)照實(shí)驗(yàn)關(guān)閉后低頻類別在合成數(shù)據(jù)中的占比會(huì)顯著下降。如果已經(jīng)開啟但問題依舊考慮把樣本量過少的類別適度合并。比如某種主診斷只有幾十條可以合并到“其他”類別里先讓主干分布學(xué)對(duì)再去補(bǔ)細(xì)節(jié)。6.4 訓(xùn)練速度慢得離譜訓(xùn)練慢通常不是機(jī)器的錯(cuò)而是參數(shù)和數(shù)據(jù)規(guī)模不匹配。字段數(shù)量多、batch_size大、epochs高都會(huì)讓訓(xùn)練時(shí)間成倍增長(zhǎng)。我的做法是先用1000條數(shù)據(jù)、50個(gè)epoch跑通流程確認(rèn)管線沒有問題再用全量數(shù)據(jù)正式訓(xùn)練。正式訓(xùn)練時(shí)初始epochs不要直接飆到1000先用200一輪的配置跑一遍質(zhì)量評(píng)估如果分布指標(biāo)還在明顯提升再往上加。醫(yī)學(xué)數(shù)據(jù)字段間的非線性關(guān)系并不像圖像那樣復(fù)雜多數(shù)場(chǎng)景300輪已經(jīng)夠用。6.5 問題排查速查表現(xiàn)象可能原因建議解決方式生成樣本類別單一模式崩潰調(diào)大batch_size增加判別器更新次數(shù)限制生成器容量連續(xù)值范圍異常離群值未處理或過度變換清洗極端離群值減少不必要的歸一化/標(biāo)準(zhǔn)化稀有類別比例偏低條件生成未生效確認(rèn)log_frequencyTrue合并過少類別訓(xùn)練loss嚴(yán)重震蕩GAN對(duì)抗正?,F(xiàn)象不只看loss定期生成樣本并檢查分布訓(xùn)練時(shí)間過長(zhǎng)參數(shù)或字段設(shè)置不合理用少量數(shù)據(jù)冒煙測(cè)試先跑200輪看趨勢(shì)模型效用差距大變量關(guān)系學(xué)得不充分增加epochs檢查關(guān)鍵字段之間的相關(guān)性指標(biāo)最后再分享一個(gè)這幾個(gè)月積累下來的習(xí)慣每次訓(xùn)練完我不會(huì)直接拿生成數(shù)據(jù)往下游業(yè)務(wù)丟而是先跑一遍“真實(shí)數(shù)據(jù)內(nèi)距離分布”和“合成數(shù)據(jù)到真實(shí)數(shù)據(jù)最近距離分布”的對(duì)比圖如果后者出現(xiàn)明顯的左移峰值說明模型開始記憶個(gè)別樣本了需要重新清洗或調(diào)整訓(xùn)練策略。合成數(shù)據(jù)這件事把它當(dāng)成一個(gè)統(tǒng)計(jì)工具來用比把它當(dāng)成“數(shù)據(jù)魔術(shù)”要踏實(shí)得多。你可以先從小規(guī)模項(xiàng)目試起把分布對(duì)比和質(zhì)量評(píng)估流程固定下來再去挑戰(zhàn)更復(fù)雜的場(chǎng)景。