Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

유방암 진단

사이킷런이 제공하는 유방암 진단(breast cancer) 데이터로 분류를 실습합니다. 종양의 여러 측정값으로 양성/악성을 가리는 문제입니다. 데이터를 살펴보고 단위를 맞춘 뒤, 여러 분류 알고리즘을 같은 기준으로 비교합니다.

import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer

X_cancer, y_cancer = load_breast_cancer(as_frame=True, return_X_y=True)
print('표본수, 특성수:', X_cancer.shape)
y_cancer.value_counts()
표본수, 특성수: (569, 30)
target 1 357 0 212 Name: count, dtype: int64

목표값은 0과 1 두 범주로, 양성과 악성의 개수가 어느 정도 균형을 이룹니다. 특성들의 크기를 살펴보겠습니다.

X_cancer.describe().loc[['mean', 'min', 'max']].round(2).T.head(8)
Loading...

특성마다 값의 범위가 크게 다릅니다(어떤 것은 0~1, 어떤 것은 수백~수천). 거리나 가중치에 민감한 알고리즘은 큰 값에 휘둘릴 수 있으므로, 단위 변환을 함께 묶어 평가합니다.

1알고리즘 비교

같은 데이터에 여러 분류 알고리즘을 적용해 성능을 비교합니다. 단위에 민감한 로지스틱 회귀·SVM·kNN은 표준화를 파이프라인으로 함께 묶고, 트리 계열은 단위 변환이 필요 없으므로 그대로 사용합니다.

from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
from sklearn.model_selection import train_test_split

훈련데이터, 시험데이터, 훈련정답, 시험정답 = train_test_split(
    X_cancer, y_cancer, random_state=0)

모델들 = {
    '로지스틱 회귀': make_pipeline(StandardScaler(), LogisticRegression(max_iter=10000)),
    'SVM': make_pipeline(StandardScaler(), SVC()),
    'kNN': make_pipeline(StandardScaler(), KNeighborsClassifier()),
    '결정 트리': DecisionTreeClassifier(random_state=0),
    '랜덤 포레스트': RandomForestClassifier(random_state=0),
}

점수 = {}
for 이름, model in 모델들.items():
    model.fit(훈련데이터, 훈련정답)
    점수[이름] = {'train': model.score(훈련데이터, 훈련정답),
               'test': model.score(시험데이터, 시험정답)}
pd.DataFrame(점수).T.round(3)
Loading...

표에서 각 알고리즘의 훈련·시험 정확도를 한눈에 비교할 수 있습니다. 결정 트리는 훈련 정확도가 1.0에 가깝지만 시험 정확도는 낮아 과적합 경향을 보이고, 랜덤 포레스트와 단위 변환을 거친 선형·거리 기반 모델들은 더 안정적인 시험 성능을 냅니다. 데이터에 어떤 알고리즘이 적합한지는 이렇게 여러 모델을 같은 기준으로 비교해 판단합니다.

2중요한 특성

랜덤 포레스트는 분류에 각 특성이 얼마나 기여했는지 특성 중요도로 알려 줍니다. 진단에 가장 큰 영향을 주는 특성을 상위 몇 개만 살펴보겠습니다.

숲 = RandomForestClassifier(random_state=0).fit(훈련데이터, 훈련정답)
중요도 = pd.Series(숲.feature_importances_, index=X_cancer.columns)
중요도.sort_values(ascending=False).head(8).round(3)
worst perimeter 0.160 worst concave points 0.117 worst radius 0.117 mean concave points 0.103 worst area 0.063 mean concavity 0.055 mean perimeter 0.054 mean area 0.049 dtype: float64

상위 특성들이 양성·악성 판정에 큰 역할을 합니다. 이렇게 응용에서는 데이터를 살펴보고 가공한 뒤, 여러 알고리즘을 비교해 가장 적합한 모델과 중요한 특성을 함께 파악합니다.