df_1_final_test = df_1.loc[list(set(df_1.index.tolist()).difference(set(df_train_1.index.tolist())))] #df_9_final_test = df_9.copy() 使负样本验证集等于正样本的验证集 df_9_final_test = df_9.sample(round(len(df_1_final_test)), random_state=int(cfg_train_dict['random_state'])) df_9_final_test['label'] = 0 df_ft = df_1_final_test.append(df_9_final_test, sort=False) # 随机分训练集和测试集 from sklearn.model_selection import train_test_split x_train, x_test, y_train, y_test = train_test_split(df_train.drop(['号码', 'label'], axis=1), df_train['label'], test_size=0.2, random_state=int(cfg_train_dict['random_state']))
时间: 2024-04-21 14:24:51 浏览: 180
这段代码是将数据集划分为训练集和测试集的代码。
首先,代码根据 df_1 和 df_train_1 的索引的差异,获取了 df_1 中不在训练集中的样本,并将其赋值给 df_1_final_test。
接着,代码从 df_9 数据框中随机抽样数量为 round(len(df_1_final_test)) 的样本作为负例测试集,并给其添加一个名为 'label' 的列,所有行的值都设置为 0。
然后,代码将 df_1_final_test 和 df_9_final_test 两个数据框按行合并成一个新的数据框 df_ft。
接下来,代码使用 train_test_split 函数将 df_train 数据框划分为训练集和测试集。其中,参数 df_train.drop(['号码', 'label'], axis=1) 表示训练集的特征数据,df_train['label'] 表示训练集的标签数据。test_size 参数设置了测试集的比例,这里是 0.2,即 20% 的样本被划分为测试集。random_state 参数用于设置随机种子。
最后,代码将划分好的训练集和测试集分别赋值给 x_train、x_test、y_train、y_test 变量。
这段代码的作用是将数据集划分为训练集和测试集,用于模型的训练和评估。其中,df_train 包含了正例样本和负例样本,df_ft 包含了未在训练集中出现的正例样本和负例样本。x_train、x_test、y_train、y_test 则是划分好的训练集和测试集的特征数据和标签数据。
相关问题
def set_data(df_0, df_1, df_9, cfg_dict): cfg_train_dict = cfg_dict['train'] df_train_1 = df_1.sample(len(df_1) - int(cfg_train_dict['simulate_pos_count']), random_state=int(cfg_train_dict['random_state'])) print('df_train_1 : ',len(df_train_1)) if cfg_train_dict['use_neg_sample'] == 'True': df_train_0 = df_0.copy() if len(df_0) >= len(df_1): df_train_0 = df_0.sample(len(df_1)) #else: # df_train_0 = df_0.append(df_9.sample(len(df_train_1) - len(df_0), # random_state=int(cfg_train_dict['random_state'])), # sort=False) else: df_train_0 = df_9.sample(round(len(df_train_1)), random_state=int(cfg_train_dict['random_state'])) df_train_0['label'] = 0 print('train set: pos_num--%i nag_num--%i' % (len(df_train_1), len(df_train_0))) df_train = df_train_1.append(df_train_0, sort=False) df_1_final_test = df_1.loc[list(set(df_1.index.tolist()).difference(set(df_train_1.index.tolist())))] #df_9_final_test = df_9.copy() 使负样本验证集等于正样本的验证集 df_9_final_test = df_9.sample(round(len(df_1_final_test)), random_state=int(cfg_train_dict['random_state'])) df_9_final_test['label'] = 0 df_ft = df_1_final_test.append(df_9_final_test, sort=False)
这段代码是一个名为 set_data 的函数,它用于设置数据集。
首先,函数从 cfg_dict 字典中获取了一个名为 cfg_train_dict 的子字典,其中包含了训练配置的相关参数。
接着,函数从 df_1 数据框中随机抽样了一部分样本作为训练集 df_train_1,抽样数量为 len(df_1) 减去 cfg_train_dict['simulate_pos_count'],random_state 参数用于设置随机种子。函数打印了 df_train_1 的长度。
然后,根据 cfg_train_dict['use_neg_sample'] 的值,函数决定如何选择负例样本。如果值为 'True',则将 df_0 数据框复制给 df_train_0,并根据 df_1 的长度进行抽样。如果 df_0 的长度大于等于 df_1 的长度,则抽样数量为 len(df_1);否则,函数还会从 df_9 数据框中抽样剩余的样本,抽样数量为 len(df_train_1) 减去 len(df_0),random_state 参数同样用于设置随机种子。
如果 cfg_train_dict['use_neg_sample'] 的值不为 'True',则直接从 df_9 数据框中抽样数量为 round(len(df_train_1)) 的样本作为负例样本,并将其赋值给 df_train_0。
接下来,函数给 df_train_0 添加了一个名为 'label' 的列,并将所有行的值都设置为 0。函数打印了 df_train_1 和 df_train_0 的长度。
然后,函数将 df_train_1 和 df_train_0 两个数据框按行合并成一个新的数据框 df_train。
接着,函数根据 df_train_1 的索引和 df_1 的索引的差异,获取了 df_1 中不在训练集中的样本,并将其赋值给 df_1_final_test。
接下来,函数从 df_9 数据框中随机抽样数量为 round(len(df_1_final_test)) 的样本作为负例测试集,并给其添加一个名为 'label' 的列,所有行的值都设置为 0。
最后,函数将 df_1_final_test 和 df_9_final_test 两个数据框按行合并成一个新的数据框 df_ft。
这段代码的作用是根据配置参数设置训练集和测试集。训练集由正例样本和负例样本组成,而测试集则包含了未在训练集中出现的正例样本和负例样本。
``` import pandas as pd import numpy as np import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False import seaborn as sns from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.preprocessing import StandardScaler from sklearn.feature_selection import SelectKBest, f_classif from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score, classification_report, roc_curve, auc, confusion_matrix import statsmodels.api as sm from sklearn.metrics import precision_score, roc_curve plt.style.use('ggplot') # 读取数据 file_path = r'C:\Users\29930\Desktop\插补数据.csv' data = pd.read_csv(file_path,encoding='GBK') data['性别'] = data['性别'].map({'男': 0, '女': 1}) # 编码性别列 arr = data.to_numpy() # 转换为NumPy数组 # 查看前几行数据 print(data.head()) # 检查是否有缺失值 print(data.isnull().sum()) # 填充缺失值(如果有的话) data.ffill(inplace=True) # 分离特征和目标变量 X = data.drop(columns=['慢阻肺']) # 假设第一列为COPD标签 y = data['慢阻肺'].map({'否': 0, '是': 1}) # 关键修改 # 标准化数值型特征 scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # 将标准化后的数据转回DataFrame格式以便后续操作 X_scaled_df = pd.DataFrame(X_scaled, columns=X.columns) # 使用SelectKBest进行单变量选择 selector = SelectKBest(score_func=f_classif, k='all') # 先全部选出来查看得分情况 fit = selector.fit(X_scaled_df, y) # 打印每个特征的重要性评分 feature_scores = pd.DataFrame(list(zip(X_scaled_df.columns, fit.scores_)), columns=['Feature','Score']) feature_scores.sort_values(by='Score', ascending=False, inplace=True) print(feature_scores) # 绘制特征重要性图 plt.figure(figsize=(10, 6)) sns.barplot(x="Score", y="Feature", data=feature_scores) plt.title('特征重要性评分') plt.xlabel('ANOVA F值') plt.ylabel('特征名称') plt.show() # 选择最重要的几个特征 selected_features = feature_scores[feature_scores.Score >= feature_scores.Score.quantile(0.75)].Feature.tolist() # 选取前75%分位数以上的特征 X_selected = X_scaled_df[selected_features] # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X_selected, y, test_size=0.2, random_state=42) # 定义逻辑回归模型 logreg = LogisticRegression(solver='liblinear') # 超参数调优 - 这里我们只对正则化强度C做网格搜索 param_grid = {'C': [0.01, 0.1, 1, 10, 100]} grid_search = GridSearchCV(logreg, param_grid, cv=5, scoring='accuracy') grid_search.fit(X_train, y_train) # 输出最佳参数组合及对应的成绩 best_logreg = grid_search.best_estimator_ print("Best parameters:", grid_search.best_params_) print("Best CV Score:", grid_search.best_score_) # 在测试集上应用最优模型 y_pred = best_logreg.predict(X_test) # 计算性能指标 acc = accuracy_score(y_test, y_pred) report = classification_report(y_test, y_pred) conf_mat = confusion_matrix(y_test, y_pred) print(f"Accuracy: {acc:.4f}") print(report) # 绘制混淆矩阵热力图 plt.figure(figsize=(8, 6)) sns.heatmap(conf_mat, annot=True, fmt='d', cmap='Blues') plt.title('分类结果混淆矩阵') plt.xlabel('预测类别') plt.ylabel('真实类别') plt.show() # ROC曲线 fpr, tpr, _ = roc_curve(y_test, best_logreg.decision_function(X_test)) roc_auc = auc(fpr, tpr) plt.figure(figsize=(8, 6)) plt.plot(fpr, tpr, color='darkorange', lw=2, label=f'ROC Curve (area = {roc_auc:.2f})') plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--') plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('ROC曲线(AUC = %0.2f)' % roc_auc) plt.legend(loc="lower right") plt.show() # 添加常数项 X_const = sm.add_constant(X_selected) # 构建OLS线性回归模型(用于展示线性关系) model = sm.Logit(y, X_const).fit() print(model.summary()) # 获取最终模型方程 coefs = list(best_logreg.coef_[0]) + [best_logreg.intercept_[0]] features_with_intercept = ['const'] + selected_features formula_parts = [] for coef, feat in zip(coefs, features_with_intercept): formula_parts.append(f"{coef:+.4f}*{feat}") final_formula = " + ".join(formula_parts) print("\nFinal Early Screening Formula:") print(final_formula.replace('+', ' + ').replace('-', ' - '))```将特征重要性图,混淆矩阵热力图,和ROC曲线画的更精美
<think>嗯,用户希望将他们的Python代码中的三个图表——特征重要性图、混淆矩阵热力图和ROC曲线——画得更精美。我需要仔细分析他们现有的代码,然后找出可以优化的地方。首先,我应该回忆一下matplotlib和seaborn的高级定制方法,看看有哪些参数可以调整来提升图表的美观度。
特征重要性图现在用的是seaborn的barplot,可能可以调整颜色、字体大小、添加更多的标签信息,或者改变背景样式。比如,使用更现代的颜色渐变,增加标题的字体大小,或者调整坐标轴的标签位置。另外,特征重要性可能需要排序,让最重要的特征排在前面,不过原代码已经按分数排序了,所以这点可能已经处理好了。
混淆矩阵热力图,用户现在用的是sns.heatmap,可能需要添加更多的注释,比如百分比而不仅仅是数量,或者调整颜色映射,使其更清晰。另外,可以设置更合适的图例位置,或者调整单元格的大小,让图表看起来更专业。
至于ROC曲线,当前的代码已经绘制了曲线和虚线参考线,但可能需要调整线条的粗细、颜色,或者添加阴影效果来突出AUC值。坐标轴的标签字体、图例的位置和样式也可以优化,比如使用更大的字体,或者将图例放在更合适的位置。
接下来,我需要检查用户现有的代码,看看哪些参数已经设置,哪些可以进一步调整。例如,在特征重要性图中,是否使用了合适的调色板?是否添加了数据标签?在混淆矩阵中,是否对数值进行了标准化,以便更直观地显示比例?
另外,用户可能希望图表在学术论文或报告中展示,所以需要更高的分辨率和更清晰的输出。可能需要调整plt.figure的参数,比如dpi,或者保存为矢量图格式如PDF或SVG。
在代码层面,可能需要为每个图表单独设置不同的样式,比如使用sns.set_style来改变背景网格,或者调整字体类型。同时,要确保中文字体正确显示,用户已经设置了SimHei,但可能需要检查是否在所有图表中都应用了该设置。
对于特征重要性图,可以考虑使用水平条形图,并给每个条形添加数值标签,这样更易读。在seaborn中,可以通过annotate函数或者修改barplot的参数来实现。
混淆矩阵方面,除了数量,还可以显示每个类别的百分比,特别是在数据不平衡的情况下,这样更直观。可以通过计算百分比矩阵来实现,并在热力图中显示。
ROC曲线方面,可以填充曲线下的面积,增加AUC值的显示位置,调整线条样式,或者添加阈值标签,但可能过于复杂。保持简洁的同时提升视觉效果是关键。
最后,要确保所有修改后的代码与用户现有的代码兼容,不会引起错误。例如,数据预处理步骤是否正确,特征选择是否影响了后续的模型训练等。需要逐步测试每个图表的代码调整,确保输出正确无误。
总结一下,优化方向包括:调整颜色和样式、添加数据标签、优化布局和字体、调整坐标轴和标题、使用更专业的图表元素。需要逐一针对每个图表进行这些调整,并在回答中详细说明修改的代码部分及其作用。</think>我将分步骤说明如何优化这三个图的绘制效果,并提供修改后的代码段:
一、特征重要性图优化方案(增强可读性与美观度)
```python
plt.figure(figsize=(12, 8), dpi=120) # 提高分辨率和尺寸
sns.set_style("whitegrid") # 使用白色网格背景
# 创建渐变色条
bar_plot = sns.barplot(x="Score", y="Feature", data=feature_scores,
palette="viridis_r",
edgecolor="0.2",
linewidth=1.5)
# 添加数据标签
for index, value in enumerate(feature_scores.Score):
bar_plot.text(value + 0.05, index, f'{value:.1f}',
va='center',
fontsize=10,
color='#2d3436')
plt.title('特征重要性评分(ANOVA F值)',
fontsize=16,
pad=20,
fontweight='bold') # 增加标题格式
plt.xlabel('ANOVA F值',
fontsize=12,
labelpad=15) # 调整标签间距
plt.ylabel('特征名称',
fontsize=12,
labelpad=15)
plt.xticks(fontsize=10)
plt.yticks(fontsize=10, rotation=0)
# 添加参考线
plt.axvline(x=np.mean(feature_scores.Score),
color='#e74c3c',
linestyle='--',
linewidth=1.5,
alpha=0.7)
# 添加图例说明
plt.text(np.mean(feature_scores.Score)+0.5, 0.5,
f'平均得分: {np.mean(feature_scores.Score):.1f}',
color='#e74c3c',
fontsize=10)
plt.tight_layout() # 自动调整边距
plt.show()
```
二、混淆矩阵热力图优化方案(增强信息量和可视化效果)
```python
plt.figure(figsize=(10, 8), dpi=120)
sns.set(font_scale=1.2) # 统一字体缩放比例
# 计算百分比矩阵
conf_mat_perc = conf_mat.astype('float') / conf_mat.sum(axis=1)[:, np.newaxis]
# 自定义注释标签
annot_labels = np.array([["{0:0.0f}\n({1:.1%})".format(num,perc)
for num, perc in zip(row, per_row)]
for row, per_row in zip(conf_mat, conf_mat_perc)])
# 创建热力图
heatmap = sns.heatmap(conf_mat,
annot=annot_labels,
fmt='', # 使用自定义格式
cmap='YlGnBu', # 更换色系
linewidths=2,
linecolor='grey',
cbar_kws={'label': '样本数量'},
annot_kws={'size':14,
'color':'#2d3436',
'va':'center'})
plt.title('分类结果混淆矩阵\n',
fontsize=16,
fontweight='bold')
plt.xlabel('预测类别',
fontsize=12)
plt.ylabel('真实类别',
fontsize=12)
# 优化颜色条
cbar = heatmap.collections[0].colorbar
cbar.ax.tick_params(labelsize=10)
cbar.ax.set_ylabel('样本数量',
rotation=270,
labelpad=20,
fontsize=12)
# 调整刻度标签
heatmap.set_xticklabels(['非慢阻肺', '慢阻肺'],
fontsize=12)
heatmap.set_yticklabels(['非慢阻肺', '慢阻肺'],
fontsize=12,
rotation=0)
plt.tight_layout()
plt.show()
```
三、ROC曲线优化方案(提升专业展示效果)
```python
plt.figure(figsize=(10, 8), dpi=120)
plt.style.use('seaborn-darkgrid') # 使用深色网格样式
# 绘制主曲线
plt.plot(fpr, tpr,
color='#3498db',
lw=3,
alpha=0.8,
label=f'ROC曲线 (AUC = {roc_auc:.2f})')
# 填充曲线下方区域
plt.fill_between(fpr, tpr,
alpha=0.15,
color='#3498db')
# 绘制参考线
plt.plot([0, 1], [0, 1],
linestyle='--',
lw=2,
color='#e74c3c',
alpha=0.7,
label='随机猜测')
# 标注最佳阈值点
optimal_idx = np.argmax(tpr - fpr)
plt.scatter(fpr[optimal_idx], tpr[optimal_idx],
s=100,
color='#f1c40f',
edgecolor='#2d3436',
zorder=3,
label=f'最佳阈值点\n(FPR={fpr[optimal_idx]:.2f}, TPR={tpr[optimal_idx]:.2f})')
# 坐标轴设置
plt.xlim([-0.02, 1.02])
plt.ylim([-0.02, 1.02])
plt.xticks(np.arange(0, 1.1, 0.1),
fontsize=10)
plt.yticks(np.arange(0, 1.1, 0.1),
fontsize=10)
# 标签和标题
plt.xlabel('False Positive Rate (1 - Specificity)',
fontsize=12,
labelpad=15)
plt.ylabel('True Positive Rate (Sensitivity)',
fontsize=12,
labelpad=15)
plt.title('ROC曲线 - 慢阻肺筛查模型',
fontsize=16,
pad=20,
fontweight='bold')
# 图例设置
plt.legend(loc='lower right',
frameon=True,
fontsize=10,
framealpha=0.9,
edgecolor='#2d3436')
# 添加网格线
plt.grid(True,
alpha=0.3,
linestyle='--')
plt.tight_layout()
plt.show()
```
主要优化点说明(使用无序列表表示):
- 特征重要性图
- 添加渐变色系(`viridis_r`)增强视觉层次
- 精确到小数点后1位的数据标签
- 红色虚线标出平均分参考线
- 调整字体大小和边距提升可读性
- 混淆矩阵
- 同时显示绝对数量和百分比
- 使用蓝绿色系(`YlGnBu`)更符合医疗主题
- 添加单元格边框线增强结构感
- 优化颜色条说明文字
- ROC曲线
- 填充曲线下方区域增强表现力
- 标注最佳阈值点提供决策参考
- 使用深色网格背景提升对比度
- 添加详细的轴刻度(0.1间隔)
- 专业级的图例排版和标签说明
建议在代码前添加以下样式初始化:
```python
# 全局样式设置
plt.style.use('seaborn')
sns.set_palette("husl") # 使用统一色板
plt.rcParams['font.family'] = 'SimHei' # 确保中文显示
plt.rcParams['axes.titlepad'] = 20 # 标题间距
```
这些修改通过以下方式提升专业性:
1. 增加信息密度(如同时显示数值和百分比)
2. 优化色彩对比度(使用科学可视化常用色系)
3. 增强可解释性(添加参考线和阈值点)
4. 统一视觉风格(字体、间距、边距)
5. 提高输出分辨率(dpi=120)
6. 添加辅助决策信息(如最佳阈值点)
阅读全文
相关推荐







