You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中欠采样优化COVID死亡预测模型效果仍不佳,求改进方案

问题

我有100万条原始COVID患者数据,已完成以下预处理:

  • 因缺失值占比超80%,删除了INTUBED和ICU两个自变量
  • 仅AGE特征用RobustScaler缩放到-1至1,其余分类变量已转为哑变量
  • 仅对训练集做欠采样避免模型偏差

当前模型(Logistic Regression、Random Forest)的F1分数(欠采样后)为[0.94093409, 0.56259895],其中第二类(死亡)的F1分数偏低,目标是提升两类F1分数,重点优化后者。

特征包含性别、年龄、COVID检测分类、患者护理类型等健康与诊疗相关属性,现寻求有效的模型改进方法或替代模型建议。

已实现代码
# Creating the dependent variable "DEATH" 
covid['DEATH']= np.where(covid['DATE_DIED']=="9999-99-99",0,1)
covid['DEATH'].value_counts()
print('Data Shape :', covid.shape)
covid.info()

# Number of Unique Values by column
for col in covid.columns : 
    print('{:<20} => {:>10}'.format(col, len(covid[col].unique())))

# Percentage of missing values    
print('Percentage of missing values')
for col in covid.columns :
    print('{:<20} => {:>10.2f}%'.format(col, len(covid[(covid[col]==98) | (covid[col]==99) | (covid[col]==97)])/len(covid)*100))

covid['INTUBED'].value_counts()
covid['ICU'].value_counts()
covid['PREGNANT'].value_counts()

# Getting rid of the missing values of features except "INTUBED", "PREGNANT", "ICU"
cols = ['PNEUMONIA','DIABETES', 'COPD', 'ASTHMA', 'INMSUPR','HIPERTENSION', 
        'OTHER_DISEASE', 'CARDIOVASCULAR', 'OBESITY','RENAL_CHRONIC', 'TOBACCO']
for col in cols :
    covid = covid[(covid[col] == 1)|(covid[col] == 2)]
# Converting process according to inference above
covid.PREGNANT = covid.PREGNANT.replace(97,2)

# Getting rid of the missing values
covid = covid[(covid.PREGNANT == 1) | (covid.PREGNANT == 2)]

covid.drop(columns=["INTUBED","ICU","DATE_DIED"], inplace=True)

from sklearn.preprocessing import RobustScaler
scaler = RobustScaler()
covid.AGE = scaler.fit_transform(covid.AGE.values.reshape(-1,1))

# Dummy variable processing
corr=covid.corr()

# Creation of the first line in spearman correlation matrix:
corr["first line"]=["USMER","MEDICAL_UNIT","PATIENT_TYPE",                    
"PNEUMONIA","AGE","PREGNANT","DIABETES","COPD","ASTHMA","INMSUPR","HIPERTENSION","OTHER_DISEASE","CARDIOVASCULAR","OBESITY","RENAL_CHRONIC","TOBACCO","CLASIFFICATION_FINAL","GENDER","DEATH"]

corr1=0
var=[]
while (corr1< len(corr['DEATH'])):
     if (corr["DEATH"][corr1]>0.1 or corr["DEATH"][corr1]<-0.1 ):
          var.append(corr["first line"][corr1])
     corr1=corr1+1

print(" The variables that have a significant correlation with the dependant variable are: ",var)   

# Replace values in data by "Value"_variable
df9=covid
other_variables=['AGE','DATE_DIED','DEATH']
col5=df9['USMER']
i=0
for col5 in df9:
  if (col5 not in other_variables and col5 in var): 
    for i in range(1,98):
      head1=df9[col5].head(0)
      head_concate=str(i)+"_"+ str(head1) 
      df9[col5]=df9[col5].replace(i,head_concate)
 
df12=covid["AGE"]
col6=df9['USMER']
for col6 in df9:
  if col6 not in other_variables and col6 in var : 
       Dummy=pd.get_dummies(df9[col6], drop_first = True)
       df12=pd.concat([df12,Dummy],axis = 1)  

y= covid['DEATH']
x= df12

logreg = LogisticRegression()
logreg.fit(train_x,train_y)
y1_pred=logreg.predict(test_x)

print('Logistic regression model accuracy:{:.2f}'.format(logreg.score(test_x,test_y)))
print("Logistic Regression F1 Score :",f1_score(test_y,logreg.predict(test_x),average=None))
print("Logistic Regression F1 Score :",f1_score(test_y,logreg.predict(test_x),average='weighted'))
print('precision before undersampling  : %.2f' % precision_score(test_y, logreg.predict(test_x),average='weighted' ))
print('recall before undersampling : %.2f' % recall_score(test_y, logreg.predict(test_x),average='weighted'))

from sklearn.metrics import confusion_matrix

# undersampling only for the training data
from imblearn.under_sampling import RandomUnderSampler

rus = RandomUnderSampler(random_state=0)
x_train_rus,y_train_rus = rus.fit_resample(train_x,train_y)

logreg_under = LogisticRegression()
logreg_under.fit(x_train_rus,y_train_rus)
print("Logistic Regression Accuracy after undersampling :",logreg_under.score(test_x, test_y))
print("Logistic Regression F1 Score after undersampling :",f1_score(test_y,logreg_under.predict(test_x),average=None))
print('F1_score: %.2f' % f1_score(test_y, logreg_under.predict(test_x),average='weighted'))
print('precision after undersampling  : %.2f' % precision_score(test_y, logreg_under.predict(test_x),average='weighted' ))
print('recall after undersampling : %.2f' % recall_score(test_y, logreg_under.predict(test_x),average='weighted'))

sns.heatmap(confusion_matrix(test_y, logreg_under.predict(test_x)), annot=True, fmt=".0f")
plt.title("Logistic Regression Confusion Matrix",fontsize=18, color="red");
模型运行结果
Percentage of missing values
USMER                =>       0.00%
MEDICAL_UNIT         =>       0.00%
PATIENT_TYPE         =>       0.00%
DATE_DIED            =>       0.00%
INTUBED              =>      81.62%
PNEUMONIA            =>       1.53%
AGE                  =>       0.03%
PREGNANT             =>      50.28%
DIABETES             =>       0.32%
COPD                 =>       0.29%
ASTHMA               =>       0.28%
INMSUPR              =>       0.32%
HIPERTENSION         =>       0.30%
OTHER_DISEASE        =>       0.48%
CARDIOVASCULAR       =>       0.29%
OBESITY              =>       0.29%
RENAL_CHRONIC        =>       0.29%
TOBACCO              =>       0.31%
CLASIFFICATION_FINAL =>       0.00%
ICU                  =>      81.64%
GENDER               =>       0.00%
DEATH                =>       0.00%
Logistic regression model accuracy:0.94
Logistic Regression F1 Score : [0.96769158 0.51907982]

precision before undersampling  : 0.93
recall before undersampling : 0.94


Logistic Regression Accuracy after undersampling : 0.8959226207949275
Logistic Regression F1 Score after undersampling : [0.94093409 0.56259895]

precision after undersampling  : 0.95
recall after undersampling : 0.90

Random Forest模型未取得理想效果。

改进建议

一、数据层面优化

  • 尝试过采样或混合采样:仅用欠采样会损失多数类有效信息,可试试SMOTE、ADASYN等过采样方法,或者SMOTE+ENN、SMOTE+TomekLinks的混合采样,平衡数据的同时保留更多信息。
  • 重新审视缺失值处理:PREGNANT缺失率50.28%直接删除太浪费,可结合GENDER做条件填充(男性的PREGNANT直接设为2),或用模型预测缺失值,避免信息丢失。
  • 特征工程优化:
    • 不要仅用相关性筛选特征,试试互信息、卡方检验,或树模型的特征重要性(比如Random Forest的feature_importances_),避免漏掉非线性相关特征。
    • 构建组合特征,比如AGE与DIABETES的交互项、PATIENT_TYPE与PNEUMONIA的交互项,这类特征可能对死亡预测有强区分度。
    • 对CLASIFFICATION_FINAL这类多分类特征,用目标编码替代哑变量,更能保留类别与目标的关联信息。

二、模型层面优化

  • 调整现有模型参数:
    • Logistic Regression:加入class_weight='balanced'参数自动给少数类更高权重,无需额外采样;用网格搜索优化正则化强度(C参数)。
    • Random Forest:增大n_estimators,调整max_depth、min_samples_split等参数,开启class_weight='balanced_subsample'让每个决策树用平衡样本训练。
  • 尝试更适合不平衡数据的模型:
    • XGBoost/LightGBM/CatBoost:这类梯度提升树自带不平衡数据处理参数(如XGBoost的scale_pos_weight、LightGBM的is_unbalance=True),能捕捉非线性特征,效果通常优于传统模型。
    • 极端随机树(ExtraTrees):比Random Forest随机性更强,可能在不平衡数据上找到更鲁棒的模式。
    • 支持向量机(SVM):配合class_weight='balanced'与RBF核函数,适合高维特征,大数据量下可通过n_jobs参数加速。
  • 模型融合:将多个模型的预测结果做加权平均或投票融合,比如Logistic Regression、XGBoost、Random Forest的预测概率加权,平衡不同模型的优势。

三、评估与调试

  • 调整概率阈值:不要用默认的0.5阈值,通过PR曲线找到最优阈值(比如降低阈值让模型更倾向于预测少数类),提升第二类的F1分数。
  • 分层交叉验证:用Stratified K-Fold确保每次折中的类别分布与整体一致,避免单次拆分带来的评估偏差。
  • 错误样本分析:提取模型预测错误的死亡样本,分析其特征共性(如年轻但有特定并发症),针对性补充特征或调整模型。

内容的提问来源于stack exchange,提问作者kjnk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 17:40:31