2025國賽C題創新論文+代碼可視化 NIPT 的時點選擇與胎兒的異常判定
基于多通道LED光譜優化的人體節律調節與睡眠質量評估模型
摘要
無創產前檢測(NIPT)通過分析孕婦血漿中胎兒游離DNA來篩查染色體異常,其準確性很大程度上依賴于胎兒Y染色體濃度的達標情況。本研究旨在建立Y染色體濃度與孕婦生理指標的關系模型,優化不同BMI分組的最佳檢測時點,并構建女胎異常判定方法。
數據處理方面,對Y染色體濃度進行Arcsine Square Root變換以符合正態分布假設,采用嚴格的數據清洗策略去除異常值和缺失值,并對連續變量進行標準化處理。針對類別不平衡問題,采用代價敏感學習和SMOTE過采樣技術進行處理。
問題一分析了Y染色體濃度與孕周、BMI等指標的相關特性。通過15個BMI細分組,分別擬合15種數學模型(線性、二次多項式、指數、對數、冪函數、Sigmoid等),采用R2、RMSE、AIC、BIC等指標進行模型選擇。結果顯示三次多項式和混合指數模型在多數分組中表現最優,孕周與Y染色體濃度呈顯著正相關(p<0.001),BMI與濃度呈負相關關系。
問題二建立了BMI分組和最佳檢測時點的優化模型。以最小化加權平均最早達標時間為目標函數,約束條件包括每組最小樣本量、80%達標概率閾值和10-25周檢測窗口。采用粒子群優化算法求解得到5個最優BMI分組區間,各組推薦檢測時點在11.2-14.8周之間,低BMI組需要更晚的檢測時間。敏感性分析表明檢測誤差每增加50%,達標概率平均下降12%。
問題三擴展為五變量綜合優化模型,同時考慮年齡、身高、體重、BMI、孕周對Y染色體濃度的影響。采用五變量二次多項式模型(14個參數)進行擬合,結合約束優化求解最佳分組和檢測時點。結果顯示綜合模型的擬合精度比單純BMI模型提高15%,各組檢測時點相比問題二有0.5-1.2周的調整,體現了多因素綜合考慮的優勢。
問題四構建了女胎異常判定分類模型。首先通過Spearman相關分析從13個候選指標中篩選出BMI、孕周、重復率、原始讀段數、體重等5個關鍵指標。比較了邏輯回歸、支持向量機、決策樹、隨機森林、樸素貝葉斯、集成學習6種分類算法,隨機森林模型表現最優(AUC=0.856)。通過ROC分析確定最優判定閾值為0.347,在該閾值下敏感性為82.3%,特異性為78.9%。
本研究建立了從單因素到多因素、從回歸到分類的完整NIPT優化分析框架,創新性地將約束優化理論應用于臨床檢測時點確定,首次提出了基于多指標綜合評分的女胎異常判定方法。研究成果為個性化NIPT檢測方案制定提供了科學依據,具有重要的臨床應用價值。
關鍵詞:無創產前檢測;Y染色體濃度;檢測時點優化;異常判定;非線性回歸模型
一、問題重述
1.1 問題背景
無創產前檢測(Non-invasive Prenatal Testing,簡稱 NIPT)作為近年來發展迅速的產前篩查技術,正逐漸成為孕期檢測的重要手段。與傳統的羊水穿刺、絨毛取樣等侵入性檢查相比,NIPT 通過采集孕婦外周血中的游離 DNA(cell-free DNA,cfDNA),對胎兒染色體進行分析,從而判斷胎兒是否存在染色體異常。這一方法安全性高、創傷小、孕婦依從性好,能夠在孕早期及中期有效地為孕婦及醫生提供重要的遺傳學信息,因此在臨床產前篩查與診斷領域具有重要意義。
在臨床實踐中,NIPT 的主要檢測目標集中在三種最常見且危害嚴重的染色體非整倍體疾病:唐氏綜合征(21-三體綜合征)、愛德華氏綜合征(18-三體綜合征)以及帕陶氏綜合征(13-三體綜合征)。唐氏綜合征患兒通常表現為智力障礙和多系統發育異常,生存質量顯著降低;愛德華氏綜合征和帕陶氏綜合征則常伴隨嚴重的多器官畸形和極高的圍產期死亡率。這些疾病一旦發生,將對家庭和社會帶來沉重負擔。因此,如何在孕期盡早、準確地發現胎兒是否存在上述染色體異常,是產前醫學的核心目標之一。
NIPT 的核心原理在于對母體血液中胎兒來源的游離 DNA 片段進行高通量測序與統計學分析。由于胎兒DNA 在母體血漿中的比例較低,檢測的準確性在很大程度上依賴于胎兒 cfDNA 的濃度,尤其是性染色體的檢測情況。臨床經驗表明,若檢測對象為男胎,則當 Y 染色體 DNA 濃度達到或高于 4% 時,可以較為可靠地反映胎兒染色體比例,從而保證檢測結果的可信度;若為女胎,則需通過 X 染色體 DNA 濃度是否異常來輔助判斷。若胎兒性染色體濃度不足,則檢測結果的準確性將受到明顯影響,可能出現假陰性或假陽性結果,降低臨床參考價值。
此外,檢測時機的選擇對結果的臨床意義也至關重要。一般而言,NIPT 適用于孕 10 周至 25 周 的孕婦,其中在孕 12 周以內進行檢測,能夠實現對胎兒染色體異常的早期發現,從而在醫療干預、妊娠管理及家庭決策等方面為孕婦及家庭爭取更多時間和空間。若在孕中期(13-27 周)才發現異常,治療和干預的難度和風險將顯著增加;若延遲至孕晚期(28 周以后),不僅診斷和處理的選擇有限,還可能因錯過最佳干預窗口而導致母嬰面臨極高風險。因此,早發現、早干預是提高 NIPT 臨床價值的關鍵。
綜上所述,NIPT 作為一種安全、便捷且準確率較高的產前檢測方法,在臨床上具有廣闊
代碼部分:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from scipy.optimize import curve_fit
from sklearn.metrics import r2_score
import warningswarnings.filterwarnings('ignore')def calc_metrics(y_true, y_pred, num_params):"""計算擬合評價指標"""n = len(y_true)# R2r2 = r2_score(y_true, y_pred)# RMSErmse = np.sqrt(np.mean((y_true - y_pred) ** 2))# AICmse = np.mean((y_true - y_pred) ** 2)aic = n * np.log(mse) + 2 * num_params# BICbic = n * np.log(mse) + num_params * np.log(n)return r2, rmse, aic, bicdef define_models():"""定義15種擬合模型"""models = {}# 模型1: 線性模型models['線性模型'] = {'func': lambda x, p1, p2, p3: p1 * x[:, 0] + p2 * x[:, 1] + p3,'p0': [0.01, 0.01, 0.5],'equation_template': 'Y = {:.6f}*BMI + {:.6f}*yz + {:.6f}'}# 模型2: 二次多項式模型models['二次多項式'] = {'func': lambda x, p1, p2, p3, p4, p5, p6: p1 * x[:, 0] ** 2 + p2 * x[:, 1] ** 2 + p3 * x[:, 0] * x[:,1] + p4 * x[:,0] + p5 * x[:,1] + p6,'p0': [0.001, 0.001, 0.001, 0.01, 0.01, 0.5],'equation_template': 'Y = {:.6f}*BMI2 + {:.6f}*yz2 + {:.6f}*BMI*yz + {:.6f}*BMI + {:.6f}*yz + {:.6f}'}# 模型3: 指數模型models['指數模型'] = {'func': lambda x, p1, p2, p3, p4: p1 * np.exp(p2 * x[:, 0] + p3 * x[:, 1]) + p4,'p0': [0.5, 0.01, 0.01, 0.1],'equation_template': 'Y = {:.6f}*exp({:.6f}*BMI + {:.6f}*yz) + {:.6f}'}# 模型4: 對數模型models['對數模型'] = {'func': lambda x, p1, p2, p3, p4: p1 * np.log(x[:, 0]) + p2 * np.log(x[:, 1]) + p3 * np.log(x[:, 0]) * np.log(x[:, 1]) + p4,'p0': [0.01, 0.01, 0.001, 0.5],'equation_template': 'Y = {:.6f}*ln(BMI) + {:.6f}*ln(yz) + {:.6f}*ln(BMI)*ln(yz) + {:.6f}','requires_positive': True}# 模型5: Sigmoid模型models['Sigmoid模型'] = {'func': lambda x, p1, p2, p3, p4, p5: p1 / (1 + np.exp(-(p2 * x[:, 0] + p3 * x[:, 1] + p4))) + p5,'p0': [0.5, 0.01, 0.01, -1, 0.1],'equation_template': 'Y = {:.6f}/(1+exp(-({:.6f}*BMI+{:.6f}*yz+{:.6f}))) + {:.6f}'}# 模型6: 三次多項式模型models['三次多項式'] = {'func': lambda x, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10: (p1 * x[:, 0] ** 3 + p2 * x[:, 1] ** 3 +p3 * x[:, 0] ** 2 * x[:, 1] + p4 * x[:, 0] * x[:,1] ** 2 + p5 * x[:,0] ** 2 + p6 * x[:,1] ** 2 +p7 * x[:, 0] * x[:, 1] + p8 * x[:, 0] + p9 * x[:,1] + p10),'p0': [0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.01, 0.01, 0.5],'equation_template': 'Y = {:.6f}*BMI3 + {:.6f}*yz3 + {:.6f}*BMI2*yz + {:.6f}*BMI*yz2 + {:.6f}*BMI2 + {:.6f}*yz2 + {:.6f}*BMI*yz + {:.6f}*BMI + {:.6f}*yz + {:.6f}','min_points': 15}# 模型7: 雙曲正切模型models['雙曲正切模型'] = {'func': lambda x, p1, p2, p3, p4, p5: p1 * np.tanh(p2 * x[:, 0] + p3 * x[:, 1] + p4) + p5,'p0': [0.5, 0.01, 0.01, 0, 0.5],'equation_template': 'Y = {:.6f}*tanh({:.6f}*BMI + {:.6f}*yz + {:.6f}) + {:.6f}'}# 模型8: 平方根模型models['平方根模型'] = {'func': lambda x, p1, p2, p3, p4, p5, p6: p1 * np.sqrt(x[:, 0]) + p2 * np.sqrt(x[:, 1]) + p3 * np.sqrt(x[:, 0]) * np.sqrt(x[:, 1]) + p4 * x[:, 0] + p5 * x[:, 1] + p6,'p0': [0.01, 0.01, 0.001, 0.001, 0.001, 0.5],'equation_template': 'Y = {:.6f}*√BMI + {:.6f}*√yz + {:.6f}*√BMI*√yz + {:.6f}*BMI + {:.6f}*yz + {:.6f}','requires_non_negative': True}# 模型9: 高斯函數模型models['高斯函數模型'] = {'func': lambda x, p1, p2, p3, p4, p5, p6: p1 * np.exp(-((x[:, 0] - p2) ** 2 / p3 ** 2 + (x[:, 1] - p4) ** 2 / p5 ** 2)) + p6,'p0': [0.5, 25, 5, 20, 5, 0.1],'equation_template': 'Y = {:.6f}*exp(-((BMI-{:.6f})2/{:.6f}2 + (yz-{:.6f})2/{:.6f}2)) + {:.6f}'}# 模型10: 復合指數模型models['復合指數模型'] = {'func': lambda x, p1, p2, p3, p4, p5: p1 * np.exp(p2 * x[:, 0]) + p3 * np.exp(p4 * x[:, 1]) + p5,'p0': [0.5, 0.01, 0.5, 0.01, 0.1],'equation_template': 'Y = {:.6f}*exp({:.6f}*BMI) + {:.6f}*exp({:.6f}*yz) + {:.6f}'}# 模型11: 混合多項式-指數模型models['混合多項式-指數'] = {'func': lambda x, p1, p2, p3, p4, p5, p6: (p1 * x[:, 0] + p2 * x[:, 1] + p3) * np.exp(p4 * x[:, 0] + p5 * x[:, 1]) + p6,'p0': [0.01, 0.01, 1, 0.001, 0.001, 0.1],'equation_template': 'Y = ({:.6f}*BMI + {:.6f}*yz + {:.6f})*exp({:.6f}*BMI + {:.6f}*yz) + {:.6f}'}# 模型12: 雙Sigmoid模型models['雙Sigmoid模型'] = {'func': lambda x, p1, p2, p3, p4, p5, p6, p7: p1 / (1 + np.exp(-(p2 * x[:, 0] + p3))) + p4 / (1 + np.exp(-(p5 * x[:, 1] + p6))) + p7,'p0': [0.25, 0.1, -2.5, 0.25, 0.1, -2, 0.1],'equation_template': 'Y = {:.6f}/(1+exp(-({:.6f}*BMI+{:.6f}))) + {:.6f}/(1+exp(-({:.6f}*yz+{:.6f}))) + {:.6f}'}# 模型13: 有理函數模型models['有理函數模型'] = {'func': lambda x, p1, p2, p3, p4, p5, p6, p7, p8, p9: (p1 * x[:, 0] ** 2 + p2 * x[:, 1] ** 2 + p3 * x[:, 0] * x[:,1] + p4 * x[:,0] + p5 * x[:,1] + p6) / (p7 * x[:, 0] + p8 * x[:, 1] + p9),'p0': [0.001, 0.001, 0.001, 0.01, 0.01, 0.5, 0.001, 0.001, 1],'equation_template': 'Y = ({:.6f}*BMI2 + {:.6f}*yz2 + {:.6f}*BMI*yz + {:.6f}*BMI + {:.6f}*yz + {:.6f})/({:.6f}*BMI + {:.6f}*yz + {:.6f})'}# 模型14: 分數冪混合模型models['分數冪混合模型'] = {'func': lambda x, p1, p2, p3, p4, p5, p6, p7, p8: p1 * x[:, 0] ** p2 + p3 * x[:, 1] ** p4 + p5 * x[:,0] ** p6 * x[:,1] ** p7 + p8,'p0': [1, 0.5, 1, 0.5, 0.1, 0.3, 0.3, 0.5],'equation_template': 'Y = {:.6f}*BMI^{:.6f} + {:.6f}*yz^{:.6f} + {:.6f}*BMI^{:.6f}*yz^{:.6f} + {:.6f}','requires_positive': True}# 模型15: 冪函數模型(使用線性回歸擬合對數變換)models['冪函數模型'] = {'func': 'power_law', # 特殊標記'equation_template': 'Y = {:.6f}*BMI^{:.6f}*yz^{:.6f}','requires_positive': True}return modelsdef fit_power_law_model(X, Y):"""冪函數模型的特殊擬合方法"""try:# Y = a * BMI^b * yz^c# ln(Y) = ln(a) + b*ln(BMI) + c*ln(yz)log_Y = np.log(Y)log_X = np.column_stack([np.ones(len(Y)), np.log(X[:, 0]), np.log(X[:, 1])])coeffs = np.linalg.lstsq(log_X, log_Y, rcond=None)[0]a = np.exp(coeffs[0])b = coeffs[1]c = coeffs[2]Y_pred = a * (X[:, 0] ** b) * (X[:, 1] ** c)return Y_pred, [a, b, c], Trueexcept:return None, None, Falsedef fit_single_model(X, Y, model_name, model_info):"""擬合單個模型"""try:# 檢查數據要求if model_info.get('requires_positive', False):if not (np.all(X > 0) and np.all(Y > 0)):return None, None, None, Falseif model_info.get('requires_non_negative', False):if not (np.all(X >= 0) and np.all(Y >= 0)):return None, None, None, Falseif model_info.get('min_points', 0) > len(Y):return None, None, None, False# 特殊處理冪函數模型if model_info['func'] == 'power_law':Y_pred, params, success = fit_power_law_model(X, Y)if not success:return None, None, None, Falseequation = model_info['equation_template'].format(*params)return Y_pred, params, equation, True# 標準擬合流程popt, _ = curve_fit(model_info['func'], X, Y, p0=model_info['p0'], maxfev=5000)Y_pred = model_info['func'](X, *popt)equation = model_info['equation_template'].format(*popt)return Y_pred, popt, equation, Trueexcept Exception as e:return None, None, None, Falsedef main():print("% BMI分組雙變量非線性擬合分析")print("正在讀取數據...")# 讀取Excel數據filename = 'q11.xlsx'try:data = pd.read_excel(filename)except FileNotFoundError:print(f"錯誤:找不到文件 {filename}")return# 提取數據列BMI = data['BMI'].valuesyz = data['yz'].values # 孕婦本次檢測時的孕周Y_raw = data['Y'].values # Y染色體游離DNA片段的比例# 數據清洗 - 去除NaN值valid_idx = ~(np.isnan(BMI) | np.isnan(yz) | np.isnan(Y_raw))BMI = BMI[valid_idx]yz = yz[valid_idx]Y_raw = Y_raw[valid_idx]# 對Y染色體濃度進行Arcsine Square Root變換Y = np.arcsin(np.sqrt(Y_raw))print(f"\n原始數據概況:")print(f"有效數據點數: {len(BMI)}")print(f"BMI范圍: {BMI.min():.2f} - {BMI.max():.2f}")print(f"孕周范圍: {yz.min():.2f} - {yz.max():.2f}")print(f"Y染色體濃度范圍: {Y.min():.4f} - {Y.max():.4f} (變換后)")# BMI分組定義(15個區間)BMI_groups = [([20.0, 21.4], '[20.0,21.4)'),([21.4, 22.9], '[21.4,22.9)'),([22.9, 24.3], '[22.9,24.3)'),([24.3, 25.7], '[24.3,25.7)'),([25.7, 27.1], '[25.7,27.1)'),([27.1, 28.6], '[27.1,28.6)'),([28.6, 30.0], '[28.6,30.0)'),([30.0, 31.4], '[30.0,31.4)'),([31.4, 32.9], '[31.4,32.9)'),([32.9, 34.3], '[32.9,34.3)'),([34.3, 35.7], '[34.3,35.7)'),([35.7, 37.1], '[35.7,37.1)'),([37.1, 38.6], '[37.1,38.6)'),([38.6, 40.0], '[38.6,40.0)'),([40.0, np.inf], '40以上')
其中更詳細的思路、各題目思路、代碼、講解視頻、成品論文及其他相關內容,可以點擊下方群名片!