在本部分,我们将深入分析癌症生存率数据集 的模型预测结果,并总结其意义~
6.1 关键指标回顾
![图片[1]-6. 结果分析与解读-大赛人网](https://www.dsrw.com/wp-content/uploads/2026/10/image-302.png)
![图片[2]-6. 结果分析与解读-大赛人网](https://www.dsrw.com/wp-content/uploads/2026/10/image-303.png)
6.2 特征重要性分析
哪些因素对癌症预测影响最大?
![图片[3]-6. 结果分析与解读-大赛人网](https://www.dsrw.com/wp-content/uploads/2026/10/image-304.png)
6.3 预测概率分析
我们绘制了 预测概率分布直方图,结果如下:
- 预测值 接近 0(良性) 的样本较多,说明良性肿瘤分类稳定。
- 预测值 接近 1(恶性) 的样本也较多,说明恶性分类可靠。
- 但有部分样本概率接近 0.5,表示模型对某些病例不太确定。
解读:
- 绝大多数样本的预测结果具有高置信度(接近 0 或 1),说明模型的决策边界清晰。
- 少部分样本接近 0.5,可能是病理学上的边界病例(benign/malignant borderline cases),需要进一步医学诊断。
指导意义:
- 医学应用:对于模型不确定的病例(概率接近 0.5),建议医生结合更多检测手段(如活检)进一步检查。
- 模型优化方向:可以引入更多数据增强技术,增强对边界病例的识别能力。
6.4 ROC 曲线分析
我们绘制的 ROC 曲线 结果如下:
- AUC = 0.98,说明模型的分类能力非常强!
- False Positive Rate(误判率)较低,说明模型很少误判良性为恶性。
- True Positive Rate(召回率)较高,说明模型能成功检测出大部分恶性病例。
解读:
- AUC 越接近 1,模型性能越好,本模型达到 0.98,说明分类能力接近理想状态。
- ROC 曲线在 (0,1) 角附近陡峭,说明模型能够在低误判率的情况下保持高召回率。
指导意义:
- 模型可用于临床癌症筛查,但仍需结合医生判断,避免误诊。
- 可以调整阈值,在不同场景(如高风险患者筛查)中优化 Precision 或 Recall。
6.5 关键结论 & 指导意义
🔹 模型表现优异,适合用于癌症早期筛查
- 召回率高,能够成功检测出大部分恶性病例
- AUC 高(0.98),能有效区分良性和恶性
🔹 影响癌症分类的关键因素
- 肿瘤半径(radius_mean) 最重要,肿瘤越大,恶性概率越高
- 肿瘤边缘凹陷度(concavity_worst) 影响显著
- 肿瘤纹理(texture_mean) 也有一定影响
🔹 模型局限性
- 对某些边界病例(概率接近 0.5)不够确定,仍需医生进一步检查
- 数据集可能有偏差,未来可增加更多样本提升模型泛化能力
医学应用建议
- 高风险患者筛查:可用于乳腺癌早期检测,提高筛查效率。
- 联合医生诊断:在高置信度预测时可辅助医生判断,低置信度时需进一步检查。
- 动态调整阈值:在不同应用场景(如医院 vs. 体检中心)调整 Precision 和 Recall 之间的权衡。
6.6 小结
XGBoost 是一个强大的乳腺癌分类模型,在高召回率、可解释性、计算效率 等方面表现优越,可用于癌症早期筛查。
肿瘤半径、边缘凹陷度、纹理等特征最具决定性,未来可进一步优化特征工程。
模型不确定的病例(预测概率接近 0.5)仍需医生介入,可结合生物标记物、基因检测等进行综合判断。
7. 完整代码
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
from sklearn.feature_selection import SelectKBest, f_classif
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from xgboost import XGBClassifier
# 设置Seaborn风格
sns.set(style="whitegrid", palette="pastel")
# 读取数据
file_path = "./dataset/007/data.csv"
df = pd.read_csv(file_path)
# 显示数据基本信息
print("数据基本信息:")
print(df.info()) # 查看数据类型、缺失值情况等
# 显示数据前5行
print("\n数据预览:")
print(df.head())
# 统计描述
print("\n数值特征统计信息:")
print(df.describe())
# 删除无关列
df.drop(columns=["id", "Unnamed: 32"], inplace=True)
# 检查缺失值
missing_values = df.isnull().sum()
print("\n缺失值情况:")
print(missing_values[missing_values > 0]) # 只显示有缺失值的列
# 由于"Unnamed: 32"列已删除,数据集实际上没有缺失值
# 检查重复行
print("\n重复数据条数:", df.duplicated().sum())
# 删除重复值(如果有的话)
df.drop_duplicates(inplace=True)
numeric_df = df.select_dtypes(include=[np.number])
# 计算异常值范围(1.5倍IQR原则)
Q1 = numeric_df.quantile(0.25)
Q3 = numeric_df.quantile(0.75)
IQR = Q3 - Q1
# 设定异常值范围
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
# 统计异常值情况
outliers = ((numeric_df < lower_bound) | (numeric_df > upper_bound)).sum()
print("\n各列异常值数量:")
print(outliers[outliers > 0])
# 直接删除异常值(仅适用于异常值极端的情况)
df = df[~((numeric_df < lower_bound) | (numeric_df > upper_bound)).any(axis=1)]
# 统计良性(B)和恶性(M)样本数量
plt.figure(figsize=(6, 4))
sns.countplot(x=df["diagnosis"], palette=["#FF9999", "#66B2FF"])
# 设置标题和标签
plt.title("Distribution of Diagnosis", fontsize=14)
plt.xlabel("Diagnosis", fontsize=12)
plt.ylabel("Count", fontsize=12)
plt.show()
# 选取部分关键变量
features = ["radius_mean", "texture_mean", "area_mean"]
plt.figure(figsize=(12, 4))
for i, feature in enumerate(features):
plt.subplot(1, 3, i + 1)
sns.histplot(df[feature], kde=True, bins=30, color=np.random.rand(3, ))
plt.title(f"Distribution of {feature}")
plt.tight_layout()
plt.show()
# 只选择数值型特征进行相关性计算
numeric_df = df.select_dtypes(include=['number'])
# 计算特征相关性矩阵
corr_matrix = numeric_df.corr()
# 绘制热力图
plt.figure(figsize=(12, 10))
sns.heatmap(corr_matrix, cmap="coolwarm", annot=False, linewidths=0.5)
# 设置标题
plt.title("Feature Correlation Heatmap", fontsize=14)
plt.show()
# 将 'diagnosis' 转换为二进制变量(M=1,B=0)
df['diagnosis'] = df['diagnosis'].map({'M': 1, 'B': 0})
# 确保转换成功
print(df['diagnosis'].value_counts())
# 计算相关性矩阵
corr_matrix = df.corr().abs()
# 设定阈值(如 0.9),高于该阈值的特征将被移除
threshold = 0.9
# 找到相关性高的特征对
high_corr_features = set()
for i in range(len(corr_matrix.columns)):
for j in range(i):
if corr_matrix.iloc[i, j] > threshold:
feature_name = corr_matrix.columns[i]
high_corr_features.add(feature_name)
print("高相关特征(将被移除):", high_corr_features)
# 删除高相关特征
df.drop(columns=high_corr_features, inplace=True)
# 选择前 10 个最重要的特征
X = df.drop(columns=['diagnosis']) # 特征
y = df['diagnosis'] # 目标变量
selector = SelectKBest(score_func=f_classif, k=10)
X_selected = selector.fit_transform(X, y)
# 获取被选中的特征名称
selected_features = X.columns[selector.get_support()]
print("被选中的 10 个关键特征:", selected_features)
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# 若 X_selected 是 ndarray,则转为 DataFrame
if not isinstance(X_selected, pd.DataFrame):
X_selected = pd.DataFrame(X_selected, columns=selected_features)
# 1. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X_selected, y, test_size=0.2, random_state=42, stratify=y
)
# 2. 标准化(只在训练集上 fit)
scaler = StandardScaler()
X_train_array = scaler.fit_transform(X_train)
X_test_array = scaler.transform(X_test)
# 3. 转换为 DataFrame,保留列名和索引
X_train_scaled = pd.DataFrame(X_train_array, columns=X_train.columns, index=X_train.index)
X_test_scaled = pd.DataFrame(X_test_array, columns=X_test.columns, index=X_test.index)
# 4. 打印数据形状
print("训练集大小:", X_train_scaled.shape)
print("测试集大小:", X_test_scaled.shape)
# 初始化 XGBoost 分类器(初始参数)
model = XGBClassifier(
n_estimators=100, # 决策树数量
learning_rate=0.1, # 学习率
max_depth=4, # 树的最大深度
subsample=0.8, # 采样比例
colsample_bytree=0.8, # 列采样
random_state=42
)
# 训练模型
model.fit(X_train_scaled, y_train)
# 预测测试集
y_pred = model.predict(X_test_scaled)
# 计算评估指标
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred, average="binary")
recall = recall_score(y_test, y_pred, average="binary")
f1 = f1_score(y_test, y_pred, average="binary")
# 打印结果
print(f"XGBoost Accuracy: {accuracy:.4f}")
print(f"Precision: {precision:.4f}")
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END












请登录后查看评论内容