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这类多分类特征,用目标编码替代哑变量,更能保留类别与目标的关联信息。
- 不要仅用相关性筛选特征,试试互信息、卡方检验,或树模型的特征重要性(比如Random Forest的
二、模型层面优化
- 调整现有模型参数:
- Logistic Regression:加入
class_weight='balanced'参数自动给少数类更高权重,无需额外采样;用网格搜索优化正则化强度(C参数)。 - Random Forest:增大
n_estimators,调整max_depth、min_samples_split等参数,开启class_weight='balanced_subsample'让每个决策树用平衡样本训练。
- Logistic Regression:加入
- 尝试更适合不平衡数据的模型:
- XGBoost/LightGBM/CatBoost:这类梯度提升树自带不平衡数据处理参数(如XGBoost的
scale_pos_weight、LightGBM的is_unbalance=True),能捕捉非线性特征,效果通常优于传统模型。 - 极端随机树(ExtraTrees):比Random Forest随机性更强,可能在不平衡数据上找到更鲁棒的模式。
- 支持向量机(SVM):配合
class_weight='balanced'与RBF核函数,适合高维特征,大数据量下可通过n_jobs参数加速。
- XGBoost/LightGBM/CatBoost:这类梯度提升树自带不平衡数据处理参数(如XGBoost的
- 模型融合:将多个模型的预测结果做加权平均或投票融合,比如Logistic Regression、XGBoost、Random Forest的预测概率加权,平衡不同模型的优势。
三、评估与调试
- 调整概率阈值:不要用默认的0.5阈值,通过PR曲线找到最优阈值(比如降低阈值让模型更倾向于预测少数类),提升第二类的F1分数。
- 分层交叉验证:用Stratified K-Fold确保每次折中的类别分布与整体一致,避免单次拆分带来的评估偏差。
- 错误样本分析:提取模型预测错误的死亡样本,分析其特征共性(如年轻但有特定并发症),针对性补充特征或调整模型。
内容的提问来源于stack exchange,提问作者kjnk
相关产品推荐
相关产品推荐

