유방암 진단 데이터세트의 머신러닝 분류 예측 튜토리얼

1. 튜토리얼 개요

도구/소프트웨어 소개

  1. 핵심 도구: R 언어(통계 컴퓨팅 및 머신 러닝 플랫폼) 및 주요 라이브러리
    • 데이터 처리:tidyverse(포함하다 dplyr 데이터 조작, ggplot2 시각화 등)
    • 모델링 도구:caret(통합 모델링 프로세스) glmnet(정규화된 로지스틱 회귀), ranger(효율적 랜덤 포레스트), class(KNN 기본 알고리즘 지원)
    • 시각화 도구:corrplot(상관관계 열지도), GGally(다변량 데이터 시각화)
  2. 개발 배경:이 논문은 위스콘신 유방암 진단 데이터 세트(WDBC)를 기반으로 이진 분류 문제에 대한 전체 머신 러닝 프로세스(데이터 전처리부터 모델 배포 및 평가까지)를 완벽하게 설명합니다.

학습 목표

  1. 의료 데이터 세트의 표준화된 전처리 프로세스(중복 기능 제거, 높은 상관관계 기능 스크리닝, 데이터 분할 및 표준화 포함)를 숙지합니다.
  2. 정규화된 로지스틱 회귀(glmnet), 랜덤 포레스트(효율적인 레인저 구현 포함), KNN이라는 세 가지 고전적 분류 모델을 능숙하게 구축하고 해당 모델에 적용 가능한 시나리오를 이해합니다.
  3. 특징 상관관계 히트맵, 주성분 분산 기여도 플롯, 모델 성능 비교 플롯, 특징 중요도 순위 플롯과 같은 핵심 시각화 결과를 생성하고 해석합니다.
  4. 유방암 진단의 주요 특징 식별(예: area_worst , perimeter_worst)과 그 임상적 의의.

2. 몇 가지 사전 준비 사항(openbayes에서 공개한 튜토리얼을 통해 복제 가능)

코어 파일 설명

  1. 데이터세트:data.csv(569개 샘플, 30개 핵심 특징, 양성(B)/악성(M)으로 표시됨, 포함) id(샘플 번호), diagnosis(진단 결과) 및 30가지 형태학적 특징).
  2. 코드 파일: 데이터 로딩 → 전처리 → EDA → 기능 엔지니어링 → 모델링 → 평가를 위한 전체 R 스크립트가 포함되어 있습니다(직접 실행 가능, 데이터 경로를 바꿔야 함).
  3. 종속성 라이브러리 목록(설치 명령):
install.packages(c("tidyverse", "caret", "ranger", "corrplot", "GGally", "glmnet"))

핵심 기술 프로세스

  1. 데이터 전처리: 데이터 로드 → 중복된 열 제거(예: X , id) → 라벨 유형 변환(인수분해) → 누락값 검사.
  2. 피처 엔지니어링: 특성 상관 행렬을 계산합니다 → 높은 상관 관계가 있는 특성을 선별합니다(임계값 0.9) → 주성분 분석(PCA) 차원 축소 및 시각화.
  3. 모델링 프로세스:데이터셋 분할(8:2 학습셋/테스트셋) → 10겹 교차 검증 매개변수 튜닝 → 3개 모델의 병렬 학습 → 혼동 행렬 및 성능 지표 평가.
  4. 평가 지표:정확도, ROC 곡선 아래의 면적(AUC), 민감도(Sensitivity, 악성 검출률), 특이도(Specificity, 양성 검출률).

3. 실제 작동 단계

환경 설정

  1. R 설치 (공식 홈페이지에서 다운로드) 및 RStudio(권장 IDE,공식 홈페이지에서 다운로드).
  2. 종속 라이브러리를 설치합니다(위의 "종속 라이브러리 목록" 참조).

데이터 로딩 및 전처리

# 加载库
library(tidyverse)  # 数据处理核心库
library(caret)      # 建模与评价工具

加载数据(替换为实际路径)
data <- read.csv("path/to/data.csv")  
预处理:移除冗余列(X 为索引列,id 为样本编号,均非特征)
data <- data %>% select(-X, -id)  
标签转换:将 diagnosis(B/M)转为因子类型(分类模型要求)
data$diagnosis <- as.factor(data$diagnosis)  
查看数据结构(确认特征类型与样本量)
str(data)  
检查缺失值(该数据集无缺失,实际场景可补充插补步骤)
colSums(is.na(data))

탐색적 데이터 분석(EDA)

핵심 목표: 특성 분포와 상관관계를 이해하고 다중공선성 문제를 식별합니다.

library(corrplot)  # 相关性热图工具

计算特征相关性矩阵(排除标签列)
data_corr <- cor(data %>% select(-diagnosis))  
绘制聚类排序的相关性热图(便于识别高相关特征群)
corrplot(data_corr, order = "hclust", tl.cex = 0.6, addrect = 8)

결과 해석:

  • 반지름(radius),둘레(perimeter),영역(area) 및 기타 기능의 상관관계가 0.9보다 크며, 이는 심각한 다중공선성을 나타내며 중복을 제거하기 위해 기능 검토가 필요합니다.

주성분 분석(PCA)

핵심 목표:차원을 줄여 데이터 구조를 단순화하고, 핵심 정보를 보존하고 시각화합니다.

library(GGally)  # 多元可视化工具

步骤 1:移除高相关特征(阈值 0.9)
high_corr_indices <- findCorrelation(data_corr, cutoff = 0.9)  # 筛选高相关特征索引 
data2 <- data %>% select(-all_of(names(data)[high_corr_indices])) # 移除冗余特征 步骤 2:执行 PCA(需标准化与中心化) pca_data2 <- prcomp(data2, scale = TRUE, center = TRUE) 步骤 3:可视化方差贡献(确定核心主成分) explained_variance <- pca_data2$sdev^2 / sum(pca_data2$sdev^2) # 单个主成分方差占比
cumulative_variance <- cumsum(explained_variance) # 累积方差占比 variance_data <- data.frame(
PC = 1:length(explained_variance),
ExplainedVariance = explained_variance,
CumulativeVariance = cumulative_variance
)
ggplot(variance_data, aes(x = PC)) +
geom_bar(aes(y = ExplainedVariance), stat = "identity", fill = "skyblue", alpha = 0.7) +
geom_line(aes(y = CumulativeVariance), color = "red", size = 1) +
geom_point(aes(y = CumulativeVariance), color = "red") +
labs(
title = "主成分方差贡献图",
x = "主成分",
y = "方差解释比例"
) +
scale_y_continuous(sec.axis = sec_axis(~., name = "累积方差解释比例")) +
theme_minimal()

결과 해석: 처음 세 가지 주성분의 누적 설명 분산은 약 70%-80%로, 이를 사용하여 모델을 단순화할 수 있습니다.

4단계: 주요 구성 요소와 진단 레이블 간의 연관성 시각화

# 提取前 3 个主成分得分,关联诊断标签
pca_scores <- as.data.frame(pca_data2$x[, 1:3])  # 前 3 个主成分
pca_scores$diagnosis <- data$diagnosis  # 加入诊断标签

绘制散点矩阵(含相关性、密度分布)
ggpairs(
pca_scores,
columns = 1:3,
mapping = aes(color = diagnosis, fill = diagnosis),
upper = list(continuous = wrap("cor", size = 3)), # 上三角:相关性
lower = list(continuous = "points"), # 下三角:散点图
diag = list(continuous = wrap("densityDiag")) # 对角线:密度分布
) +
theme_minimal() +
scale_color_manual(values = c("B" = "salmon", "M" = "cyan3")) +
scale_fill_manual(values = c("B" = "salmon", "M" = "cyan3"))

결과 해석: 악성(M) 샘플과 양성(B) 샘플의 첫 번째 세 가지 주성분 분포는 상당히 다르며, 이는 PCA가 분류 정보를 효과적으로 유지한다는 것을 나타냅니다.

모델 학습

데이터 세트 분할(8:2)

set.seed(123)  # 固定随机种子,保证结果可复现

组合标签与处理后特征(便于建模)
data3 <- cbind(diagnosis = data$diagnosis, data2)  
按标签分层抽样(维持训练集/测试集类别比例一致)
data_sampling_index <- createDataPartition(data3$diagnosis, times = 1, p = 0.8, list = FALSE)
data_training <- data3[data_sampling_index, ] # 训练集(80%)
data_testing <- data3[-data_sampling_index, ] # 测试集(20%) 定义交叉验证策略(10 折交叉验证,计算分类概率与二分类指标)
data_control <- trainControl(
method = "cv",
number = 10,
classProbs = TRUE,
summaryFunction = twoClassSummary # 输出 ROC 、灵敏度、特异度
)

1. 정규화된 로지스틱 회귀(glmnet)

# 训练模型(带 L1/L2 正则化,自动调优参数)
model_glmnet <- train(
  diagnosis ~ ., 
  data = data_training, 
  method = "glmnet",  # 正则化逻辑回归
  metric = "ROC",  # 以 ROC 为优化目标
  preProcess = c("scale", "center"),  # 特征标准化
  tuneLength = 20,  # 20 组参数候选
  trControl = data_control
)

2. 랜덤 포레스트(2가지 구현)

방법 1:ranger 패키지(효율적 구현)

library(ranger)  # 快速随机森林工具

model_rf_ranger <- ranger(
diagnosis ~ .,
data = data_training,
probability = TRUE, # 输出概率
importance = "impurity", # 计算特征重要性(不纯度)
num.trees = 500 # 500 棵决策树
)

방법 2:caret 패키지 통합 rf(교차 검증을 위해)

model_rf_caret <- train(
  diagnosis ~ ., 
  data = data_training, 
  method = "rf",  # 传统随机森林
  metric = "ROC", 
  trControl = data_control,
  ntree = 500  # 500 棵决策树
)

3. KNN(K 최근접 이웃)

# 训练模型(优化邻居数 k)
model_knn <- train(
  diagnosis ~ ., 
  data = data_training, 
  method = "knn", 
  metric = "ROC", 
  preProcess = c("scale", "center"),  # KNN 对距离敏感,必须标准化
  trControl = data_control, 
  tuneLength = 31  # 测试 k= 1 到 31 的最优值
)

可视化不同 k 值的 ROC 表现(确定最优 k)
plot(model_knn, main = "KNN 模型不同邻居数的 ROC 表现")

모델 예측 및 평가

1. 예측 결과 및 혼동 행렬

로지스틱 회귀를 예로 들어 보겠습니다.:

# 测试集预测
prediction_glmnet <- predict(model_glmnet, data_testing)

生成混淆矩阵(评估分类准确性)
cm_glmnet <- confusionMatrix(prediction_glmnet, data_testing$diagnosis, positive = "M")
cm_glmnet # 输出准确率、灵敏度、特异度等指标

혼동 행렬 시각화:

# 转换为数据框用于绘图
cm_table <- as.table(cm_glmnet$table)
cm_df <- as.data.frame(cm_table)
colnames(cm_df) <- c("实际标签", "预测标签", "频数")

ggplot(cm_df, aes(x = 实际标签, y = 预测标签, fill = 频数)) +
geom_tile(color = "white") +
scale_fill_gradient(low = "lightblue", high = "blue") +
geom_text(aes(label = 频数), color = "black", size = 6) +
labs(title = "逻辑回归混淆矩阵", x = "实际诊断", y = "预测诊断") +
theme_minimal()

2. 기능 중요도 분석

랜덤 포레스트 피처 중요도:

# 提取前 10 个重要特征
importance_rf <- model_rf_ranger$variable.importance  # ranger 模型结果
importance_df <- data.frame(
  特征 = names(importance_rf), 
  重要性 = importance_rf
) %>% arrange(desc(重要性)) %>% slice(1:10)  # 取前 10

可视化
ggplot(importance_df, aes(x = reorder(特征, 重要性), y = 重要性)) +
geom_bar(stat = "identity", fill = "skyblue") +
coord_flip() + # 横向条形图,便于阅读特征名
labs(title = "随机森林 Top10 重要特征", x = "特征", y = "重要性(不纯度下降)") +
theme_minimal()

주요 결과:area_worst(최대 종양 면적), perimeter_worst(종양의 최대 둘레)는 양성 종양과 악성 종양을 구별하는 핵심적인 특징으로, 임상적 인지와 일치합니다.

IV. 모델 비교 및 결과 해석

다중 모델 성능 비교

# 汇总所有模型
model_list <- list(
  逻辑回归 = model_glmnet, 
  随机森林 = model_rf_caret, 
  KNN = model_knn
)

提取交叉验证结果
results <- resamples(model_list)
输出性能指标(ROC 、灵敏度、特异度)
summary(results)

시각적 비교:

# 箱线图:展示各模型 ROC 分布
bwplot(results, metric = "ROC", main = "模型 ROC 性能对比(10 折交叉验证)")

点图:带 95% 置信区间的性能指标
dotplot(results, metric = c("ROC", "Sens", "Spec"), main = "模型性能指标对比")

결과 해석:

  • 로지스틱 회귀 분석이 가장 좋은 성과를 보였습니다(ROC = 0.993, 민감도 = 0.989). 기준 모델로 적합했습니다.
  • 랜덤 포레스트는 로지스틱 회귀와 비슷한 성능을 보이지만, 계산 비용이 더 높습니다.
  • KNN은 특이성이 약간 낮고(0.888) 양성 샘플에 대한 오분류율이 약간 높습니다.

5. 고급 작업

매개변수 최적화

  1. 랜덤 포레스트 튜닝(최적화 mtry 매개변수, 즉 분할당 기능 수):
model_rf_tuned <- train(
  diagnosis ~ ., 
  data = data_training, 
  method = "rf",
  metric = "ROC", 
  trControl = data_control,
  tuneGrid = expand.grid(mtry = seq(5, 15, 2))  # 测试 mtry=5,7,...,15
)
  1. 확장 모델: 지원 벡터 머신(SVM) 추가
model_svm <- train(
  diagnosis ~ ., 
  data = data_training, 
  method = "svmRadial",  # 径向核 SVM
  metric = "ROC", 
  trControl = data_control
)

VI. 부록

공통 코드 빠른 조회 테이블

기능코드 샘플
데이터 읽기read.csv("data.csv")
상관관계 히트맵corrplot(cor(data), order = "hclust")
10겹 교차 검증 설정trainControl(method = "cv", number = 10)
혼동 행렬 계산confusionMatrix(pred, actual)
PCA 차원 축소prcomp(data, scale = TRUE)

일반적인 문제 해결

  1. 오류 신고 could not find function "corrplot"→ 해결 방법: 설치 corrplot 가방(install.packages("corrplot")).
  2. 피처 치수 오류 → 누락되었는지 확인하세요 select(-id, -diagnosis)단계(비특징 열 제외)
  3. 모델 학습이 느립니다 → 감소 ntree(랜덤 포레스트 나무의 수) 또는 tuneLength(매개변수 후보의 수).

이 튜토리얼을 통해 의료 이진 분류 문제의 머신 러닝 프로세스를 익히고, 기능 스크리닝, 모델 튜닝, 결과 시각화의 핵심 논리를 이해하는 데 집중하며, 다른 질병 진단을 모델링하기 위한 참고 자료를 제공할 수 있습니다.