빅데이터 QAQC_3기/빅데이터 QAQC_3기 TIL

TIL_251105

usungusung 2025. 11. 5. 22:03

Today I learned

 

 

1. [라이브세션] 머신러닝 특강 - 머신러닝 주요 기법 3일차

1) 랜덤 포레스트

집단 지성의 원리를 학습한 앙상블 알고리즘

 

- 랜덤포레스트 분석의 원리

1단계: 부트스트랩 샘플링

부트스트랩 샘플링은 원본 데이터에서 복원 추출로 새로운 데이터셋을 만드는 방법입니다.

  1. 원본 데이터 N개(1000)에서 N개(1000)를 복원 추출
  2. 각 트리마다 서로 다른 부트스트랩 샘플 사용

효과:

  • 각 트리가 약간씩 다른 패턴을 학습
  • 과적합 방지 및 일반화 성능 향상

 

2단계: 특성 무작위성

특성 무작위성은 각 노드 분할 시 전체 특성 중 일부만 랜덤하게 선택하여 고려하는 방법입니다.

방법:

  • 전체 특성 수를 p(8개)라고 할 때, 보통 √p 루트8 개의 특성만 고려
  • 각 분할마다 다른 특성 조합 사용
  • 트리 간 상관관계 감소로 앙상블 효과 극대화

예를들어

  • 전체 특성: 9개
  • 각 분할에서 고려할 특성: √9 ≈ 3개
  • 가능한 조합: C(9,3) = 84가지

3단계: 투표 방식

앙상블의 최종 예측은 개별 트리드르이 예측을 종합하여 결정

scikit-learn을 활용한 랜덤포레스트 분석 예시(머신러닝 특강 2일차 데이터에서 이어짐)
1단계: 랜덤포레스트 모델 생성
# RandomForestClassifier import
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

# 랜덤 포레스트 모델 생성
rf_model = RandomForestClassifier(
    n_estimators=100,        # 트리 개수
    max_depth=10,           # 최대 깊이
    min_samples_split=20,   # 분할 최소 샘플
    min_samples_leaf=10,    # 리프 최소 샘플
    max_features='sqrt',    # 특성 무작위성 루트, decision tree에서 추가된거, 개인이 임의로 세팅할 수 있음
    #max_feature = 1 이면 전체를 사용하겠다, 0.5 면 절반 사용하겠다 이런 애기임
    bootstrap=True,         # 부트스트랩 사용, decision tree에서 추가된거
    random_state=42,
)

print("=== 랜덤 포레스트 모델 설정 ===")
print(f"트리 개수: {rf_model.n_estimators}")
print(f"최대 깊이: {rf_model.max_depth}")
print(f"특성 선택: {rf_model.max_features}")
print(f"부트스트랩: {rf_model.bootstrap}")
=== 랜덤 포레스트 모델 설정 === 트리 개수: 100 최대 깊이: 10 특성 선택: sqrt 부트스트랩: True
2단계: 모델 학습 과정  
# 모델 학습 시작
print("=== 랜덤 포레스트 학습 시작 ===")
print("100개의 트리를 병렬로 학습 중...")

# 학습 시간 측정
import time
start_time = time.time()

rf_model.fit(X_train, y_train)

end_time = time.time()
training_time = end_time - start_time

print(f"학습 완료! 소요 시간: {training_time:.2f}초")
print(f"학습된 트리 개수: {len(rf_model.estimators_)}")
=== 랜덤 포레스트 학습 시작 === 100개의 트리를 병렬로 학습 중... 학습 완료! 소요 시간: 0.15초 학습된 트리 개수: 100
3단계: 기본 성능 평가  
rf_train_pred = rf_model.predict(X_train)
rf_test_pred = rf_model.predict(X_test)

# 정확도 계산
rf_train_acc = accuracy_score(y_train, rf_train_pred)
rf_test_acc = accuracy_score(y_test, rf_test_pred)
rf_overfit = rf_train_acc - rf_test_acc

print(f"훈련 데이터 정확도: {rf_train_acc:.3f}")
print(f"테스트 데이터 정확도: {rf_test_acc:.3f}")
훈련 데이터 정확도: 0.850 테스트 데이터 정확도: 0.782
- 특성 중요도 확인  
# 특성 중요도 추출
feature_importance = pd.DataFrame({
    'feature': X.columns,
    'importance': rf_model.feature_importances_
}).sort_values('importance', ascending=False)

print("랜덤 포레스트 특성 중요도 순위:")
print("-" * 30)
for idx, row in feature_importance.iterrows():
    print(f"{row['feature']:15}: {row['importance']:.3f}")

# 상위 5개 특성 강조
print(f"\n🏆 TOP 5 중요 특성:")
top5_features = feature_importance.head(5)
for i, (_, row) in enumerate(top5_features.iterrows(), 1):
    print(f"{i}위. {row['feature']} ({row['importance']:.3f})")
- 트리 시각화  
first_tree = rf_model.estimators_[0] # 첫 번째 트리를 가져옴

for i in range(0, 100):
    first_tree = rf_model.estimators_[i]
   
# 첫 번째 트리 시각화
plt.figure(figsize=(20, 12))
plot_tree(first_tree,
          feature_names=X.columns,
          class_names=['사망', '생존'],
          filled=True,
          rounded=True,
          fontsize=10)
plt.title('랜덤 포레스트 내 첫 번째 디시전 트리', fontsize=16)
plt.show()

# 첫 번째 트리 구조를 텍스트로 출력
print("\n=== 랜덤 포레스트 내 첫 번째 디시전 트리 구조 (텍스트) ===")
tree_rules = export_text(first_tree, feature_names=list(X.columns))
print(tree_rules[:1000]) # 처음 1000자만 출력

 

 

 

2) XGBoost

XGBoost (eXtreme Gradient Boosting)**는 그래디언트 부스팅을 극한으로 최적화한 알고리즘입니다. 캐글 대회 우승작의 80% 이상에서 사용될 정도로 실무에서 가장 인기 있는 머신러닝 알고리즘입니다.

XGBoost의 핵심 특징:

  • 순차적 학습: 이전 모델의 오류를 다음 모델이 보완
  • 정규화: L1, L2 정규화로 과적합 방지
  • 병렬 처리: GPU 지원으로 빠른 학습
  • 결측치 처리: 자동으로 최적의 결측치 처리 방향 학습 </aside>

랜덤포레스트 vs xgboost

랜포: 독립적인 트리들의 병렬 학습

엑지: 오류를 보완하는 트리들의 순차 학습

 

  • 1단계: 첫 번째 기본 트리 만들기(약한 분류기)첫 번째 모델의 시도
    • 매우 간단한 트리 1개로 시작 (깊이 1-2 정도)
    • 예: "성별이 여성이면 생존, 남성이면 사망"
    결과 분석
    • 정확히 예측된 승객: 700명 ✅
    • 틀리게 예측된 승객: 191명 ❌
      • 실제로는 생존했는데 사망으로 예측: 80명
      • 실제로는 사망했는데 생존으로 예측: 111명
    핵심: 첫 번째 모델은 대략적인 패턴만 잡고, 많은 실수를 남김
  • 상황: 타이타닉 승객 891명의 생존 여부를 예측해야 합니다.
  • 2단계: 첫 번째 모델의 오차 분석하기
    • 남성인데 생존한 사람들: 어린 남자아이들, 1등급 남성들
    • 여성인데 사망한 사람들: 3등급의 나이 많은 여성들
    가중치 부여 메커니즘
    • 틀리게 예측된 191명에게 **"더 중요하다"**는 표시
    • 올바르게 예측된 700명은 **"덜 중요하다"**는 표시
  • 3단계: 두 번째 약한 분류기 만들기 (실수 보완에 집중)
    • 첫 번째 모델이 틀린 191명에 집중적으로 학습
    • 새로운 규칙 발견: "남성이면서 나이가 10세 이하면 생존"
    결과
    • 이전에 틀렸던 191명 중 120명을 올바르게 수정 ✅
    • 하지만 새롭게 71명을 틀리게 예측 ❌
    중요한 점
    • 두 번째 모델은 혼자서는 성능이 나쁠 수 있음
    • 하지만 첫 번째 모델의 특정 약점을 보완하는 데 특화됨
  • 두 번째 모델의 학습
  • 4단계: 세 번째 약한 분류기 만들기 (남은 실수 더 보완)
    • 첫 번째 + 두 번째 모델이 여전히 틀리는 승객들에 집중
    • 이 과정을 통해 점진적 성능 향상
      • 전체 891명 중: 1단계 후: 191명 틀림 (정확도 78.5%) 2단계 후: 71명 틀림 (정확도 92.0%) 3단계 후: 25명 틀림 (정확도 97.2%)
  • 5단계: 최종 예측 - 모든 모델의 지혜 결합
  • 가중 투표 방식! → 각 모델의 성능에 따라 다른 영향력 부여:

    새로운 승객의 생존 예측:
    - 1번 모델: "사망" (영향력 40%)
    - 2번 모델: "생존" (영향력 35%)
    - 3번 모델: "생존" (영향력 25%)

    최종 계산:
    사망: 40%
    생존: 35% + 25% = 60%
    → 결론: 생존 예측! 🎯


    최종 예측 = 기본값 + α₁×모델₁ + α₂×모델₂ + α₃×모델₃ + ...

    여기서:
    - 기본값: 전체 데이터의 평균 (타이타닉의 경우 생존률 38%)
    - α₁, α₂, α₃: 각 모델의 학습률 (보통 0.1~0.3)
    - 모델₁, 모델₂, 모델₃: 각 단계에서 학습된 약한 분류기

 

XGBoost로 이걸 구현하기

 

3) 클러스터링

지금까지 우리가 배운건 지도학습

 

비지도학습 (Unsupervised Learning)

  • 정답에 해당하는 값이 주어지지 않은 상태에서
  • 입력 데이터(X)의 특성을 분석하는 모델을 학습하는 과정
  • 특징: 분석가의 주관이 많이 개입, 사람마다 해석이 다를 수 있음
  • 목적: 데이터 사이의 연관 규칙이나 군집을 구하는 과정
  • 예시: 고객 세분화, 패턴 발견, 이상 탐지

  • 클러스터링이란 분석 대상이 되는 데이터의 그룹을 만드는 방법론.
  • 그룹을 만들 때는 마구잡이로 만드는 것이 아니라 특정 기준을 가지고 제작.
    • intra-cluster(군집 내 거리): 군집 사이의 데이터들의 거리는 가까울수록 좋음
    • inter-cluster(군집 간 거리): 각각의 군집 사이의 거리는 멀수록 좋음
    •  
  • 클러스터링 활용 예시
    • 목적: 수많은 양의 데이터를 몇 개의 그룹으로 묶어서 전체 특성 파악
    • 장점: 모든 데이터를 확인하지 않아도 전체 데이터 특성을 이해 가능
    • 예시:
      • 1년간의 뉴스 데이터를 클러스터링하여 그 해의 주요 뉴스 토픽 찾기
    • 1. 요약 및 시각화 (Summarization)

 

 

2. 개인과제 해설

- 라이브러리 실행 및 데이터 불러오기

# 라이브러리 실행
import pandas as pd
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.linear_model import LinearRegression, LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report
# 데이터 불러오기
df = pd.read_csv("data.csv")
df.info()

 

 

- 필수1. 기초통계

필수1 문제 필수 1 답안
- Breast Cancer 데이터셋의 종양 특성들을 카테고리별로 **진단 결과(diagnosis)**에 따라 분석해보세요.
   
    각 카테고리에 속한 특성들의 **평균과 중앙값**을 구하고 해석해주세요.
   
    1. **크기/형태 관련 특성의 기초통계**
        - radius_mean, perimeter_mean, area_mean에 대한 진단별 평균과 중앙값을 구하세요.
    2. **표면 특성의 기초통계**
        - texture_mean, smoothness_mean에 대한 진단별 평균과 중앙값을 구하세요.
    3. **형태 복잡도 특성의 기초통계**
        - compactness_mean, concavity_mean, concave points_mean에 대한 진단별 평균과 중앙값을 구하세요.
    4. **구조적 특성의 기초통계**
        - symmetry_mean, fractal_dimension_mean에 대한 진단별 평균과 중앙값을 구하세요.
- **유의 사항**
    - 결과는 **소수점 둘째자리**까지 표현해주세요.
    - 각 카테고리별로 **간단한 해석**을 덧붙여주세요.
  1. 크기/형태 관련 특성 통계량 :
    • 양성(B) 종양 :
      • radius_mean: 평균 12.15, 중앙값 12.20
      • perimeter_mean: 평균 78.08, 중앙값 78.18
      • area_mean: 평균 462.79, 중앙값 458.40
    • 악성(M) 종양 :
      • radius_mean: 평균 17.46, 중앙값 17.33
      • perimeter_mean: 평균 115.37, 중앙값 114.20
      • area_mean: 평균 978.38, 중앙값 932.00
    • 해석 :
      • 크기/형태 관련 모든 특성에서 악성 종양이 양성 종양보다 확연히 큰 값을 보입니다. 특히 area_mean의 경우 악성 종양(978.38)이 양성 종양(462.79)보다 2배 이상 큽니다. 각 특성에서 평균과 중앙값이 비슷한 값을 보이는 것으로 보아 데이터가 대체로 정규분포를 따르는 것으로 판단됩니다.
  2. 표면 관련 특성 통계량 :
    • 양성(B) 종양 :
      • texture_mean: 평균 17.91, 중앙값 17.39
      • smoothness_mean: 평균 0.09, 중앙값 0.09
    • 악성(M) 종양 :
      • texture_mean: 평균 21.60, 중앙값 21.46
      • smoothness_mean: 평균 0.10, 중앙값 0.10
    • 해석 :
      • 표면 특성에서도 악성 종양이 더 큰 값을 보이지만, 그 차이는 크기/형태 특성에 비해 상대적으로 작습니다. texture_mean의 경우 약 3.69 정도의 차이를 보이며, smoothness_mean은 매우 작은 차이(0.01)를 보입니다.
  3. 형태 복잡도 관련 특성 통계량 :
    • 양성(B) 종양 :
      • compactness_mean: 평균 0.08, 중앙값 0.08
      • concavity_mean: 평균 0.05, 중앙값 0.04
      • concave points_mean: 평균 0.03, 중앙값 0.02
    • 악성(M) 종양 :
      • compactness_mean: 평균 0.15, 중앙값 0.13
      • concavity_mean: 평균 0.16, 중앙값 0.15
      • concave points_mean: 평균 0.09, 중앙값 0.09
    • 해석 :
      • 형태 복잡도 특성들에서는 모두 악성 종양이 양성 종양보다 2-3배 정도 큰 값을 보입니다. 특히 concavity_mean에서 가장 큰 차이(0.11)를 보이며, 이는 악성 종양이 더 복잡한 형태를 가지고 있음을 시사합니다.
  4. 구조적 관련 특성 통계량 :
    • 양성(B) 종양 :
      • symmetry_mean: 평균 0.17, 중앙값 0.17
      • fractal_dimension_mean: 평균 0.06, 중앙값 0.06
    • 악성(M) 종양 :
      • symmetry_mean: 평균 0.19, 중앙값 0.19
      • fractal_dimension_mean: 평균 0.06, 중앙값 0.06
    • 해석 :
      • 구조적 특성에서는 다른 카테고리들에 비해 매우 작은 차이를 보입니다. symmetry_mean은 약 0.02의 작은 차이를 보이며, fractal_dimension_mean은 거의 차이가 없습니다. 이는 종양의 구조적 특성이 악성 여부 판단에 상대적으로 덜 중요할 수 있음을 시사합니다.
 
# 필수 1. 기초 통계

def get_category_stats(df, features):
    results = []
    for feature in features:
        # 진단별 평균 계산
        means = df.groupby('diagnosis')[feature].mean().round(2)
        # 진단별 중앙값 계산
        medians = df.groupby('diagnosis')[feature].median().round(2)

        results.append({
            'feature': feature,
            'B_mean': means['B'],
            'B_median': medians['B'],
            'M_mean': means['M'],
            'M_median': medians['M'],
            'diff_mean': (means['M'] - means['B']).round(2)
        })

    return pd.DataFrame(results)

# 카테고리별 특성 정의
size_shape = ['radius_mean', 'perimeter_mean', 'area_mean']
surface = ['texture_mean', 'smoothness_mean']
morphological = ['compactness_mean', 'concavity_mean', 'concave points_mean']
structural = ['symmetry_mean', 'fractal_dimension_mean']

# 각 카테고리별 분석 수행 및 결과 출력
print("1. 크기/형태 관련 특성 통계량")
print("-" * 50)
size_results = get_category_stats(df, size_shape)
print("\n양성(B) 종양:")
for _, row in size_results.iterrows():
    print(f"* {row['feature']}:")
    print(f"  평균: {row['B_mean']}, 중앙값: {row['B_median']}")

print("\n악성(M) 종양:")
for _, row in size_results.iterrows():
    print(f"* {row['feature']}:")
    print(f"  평균: {row['M_mean']}, 중앙값: {row['M_median']}")

print("\n2. 표면 특성 통계량")
print("-" * 50)
surface_results = get_category_stats(df, surface)
print("\n양성(B) 종양:")
for _, row in surface_results.iterrows():
    print(f"* {row['feature']}:")
    print(f"  평균: {row['B_mean']}, 중앙값: {row['B_median']}")

print("\n악성(M) 종양:")
for _, row in surface_results.iterrows():
    print(f"* {row['feature']}:")
    print(f"  평균: {row['M_mean']}, 중앙값: {row['M_median']}")

print("\n3. 형태 복잡도 특성 통계량")
print("-" * 50)
morphological_results = get_category_stats(df, morphological)
print("\n양성(B) 종양:")
for _, row in morphological_results.iterrows():
    print(f"* {row['feature']}:")
    print(f"  평균: {row['B_mean']}, 중앙값: {row['B_median']}")

print("\n악성(M) 종양:")
for _, row in morphological_results.iterrows():
    print(f"* {row['feature']}:")
    print(f"  평균: {row['M_mean']}, 중앙값: {row['M_median']}")

print("\n4. 구조적 특성 통계량")
print("-" * 50)
structural_results = get_category_stats(df, structural)
print("\n양성(B) 종양:")
for _, row in structural_results.iterrows():
    print(f"* {row['feature']}:")
    print(f"  평균: {row['B_mean']}, 중앙값: {row['B_median']}")

print("\n악성(M) 종양:")
for _, row in structural_results.iterrows():
    print(f"* {row['feature']}:")
    print(f"  평균: {row['M_mean']}, 중앙값: {row['M_median']}")
1. 크기/형태 관련 특성 통계량
--------------------------------------------------

양성(B) 종양:
* radius_mean:
  평균: 12.15, 중앙값: 12.2
* perimeter_mean:
  평균: 78.08, 중앙값: 78.18
* area_mean:
  평균: 462.79, 중앙값: 458.4

악성(M) 종양:
* radius_mean:
  평균: 17.46, 중앙값: 17.33
* perimeter_mean:
  평균: 115.37, 중앙값: 114.2
* area_mean:
  평균: 978.38, 중앙값: 932.0

2. 표면 특성 통계량
--------------------------------------------------

양성(B) 종양:
* texture_mean:
  평균: 17.91, 중앙값: 17.39
* smoothness_mean:
  평균: 0.09, 중앙값: 0.09

악성(M) 종양:
* texture_mean:
  평균: 21.6, 중앙값: 21.46
* smoothness_mean:
  평균: 0.1, 중앙값: 0.1

3. 형태 복잡도 특성 통계량
--------------------------------------------------

양성(B) 종양:
* compactness_mean:
  평균: 0.08, 중앙값: 0.08
* concavity_mean:
  평균: 0.05, 중앙값: 0.04
* concave points_mean:
  평균: 0.03, 중앙값: 0.02

악성(M) 종양:
* compactness_mean:
  평균: 0.15, 중앙값: 0.13
* concavity_mean:
  평균: 0.16, 중앙값: 0.15
* concave points_mean:
  평균: 0.09, 중앙값: 0.09

4. 구조적 특성 통계량
--------------------------------------------------

양성(B) 종양:
* symmetry_mean:
  평균: 0.17, 중앙값: 0.17
* fractal_dimension_mean:
  평균: 0.06, 중앙값: 0.06

악성(M) 종양:
* symmetry_mean:
  평균: 0.19, 중앙값: 0.19
* fractal_dimension_mean:
  평균: 0.06, 중앙값: 0.06


- 필수 2. 통계적 가설검정 1(t-test)

 

필수2 문제 필수2 답안
  • Breast Cancer 데이터셋의 종양 특성들을 카테고리별로 분석하려 합니다. 각 카테고리에 속한 특성들에 대해 diagnosis(양성/악성)에 따른 독립표본 T-TEST를 진행해주세요.
    • 크기/형태 관련 특성의 분석
    • radius_mean, perimeter_mean, area_mean에 대한 t-test를 수행하세요.
    • 표면 특성의 분석
    • texture_mean, smoothness_mean에 대한 t-test를 수행하세요.
    • 형태 복잡도 특성의 분석
    • compactness_mean, concavity_mean, concave points_mean에 대한 t-test를 수행하세요.
    • 구조적 특성의 분석
    • symmetry_mean, fractal_dimension_mean에 대한 t-test를 수행하세요.
  • 가설검정 방법은 각 카테고리별로:
    • 귀무가설과 대립가설을 작성하세요.
    • t-score와 p-value를 구하세요.
    • 귀무가설의 채택/기각 여부를 판단하세요.
    • 해당 카테고리 내에서 어떤 특성이 악성 종양 판별에 가장 큰 영향을 미치는지 분석하세요.
  1. 크기/형태 관련 특성 분석 :
    • 가설 :
      • H0: 양성과 악성 종양의 크기/형태 관련 특성 평균은 동일하다
      • H1: 양성과 악성 종양의 크기/형태 관련 특성 평균은 다르다
    • 검정 결과 :
      • radius_mean: t-score -25.44, p-value 0.000
      • perimeter_mean: t-score -26.41, p-value 0.000
      • area_mean: t-score -23.94, p-value 0.000
    • 해석 :
      • 모든 크기/형태 특성에서 p-value가 0.05보다 매우 작아 귀무가설을 기각합니다.
      • perimeter_mean이 가장 높은 t-score 절댓값(-26.41)을 보여, 가장 강력한 차이를 나타냅니다.
      • 평균 차이를 보면 area_mean이 515.59로 가장 큰 절대적 차이를 보입니다.
  2. 표면 관련 특성 분석 :
    • 가설 :
      • H0: 양성과 악성 종양의 표면 관련 특성 평균은 동일하다
      • H1: 양성과 악성 종양의 표면 관련 특성 평균은 다르다
    • 검정 결과 :
      • texture_mean: t-score -10.87, p-value 0.000
      • smoothness_mean: t-score -9.15, p-value 0.000
    • 해석 :
      • 두 표면 특성 모두 p-value가 0.05보다 작아 귀무가설을 기각합니다.
      • texture_mean이 더 높은 t-score 절댓값(-10.87)을 보여, 더 유의미한 차이를 나타냅니다.
      • 평균 차이는 texture_mean이 3.69, smoothness_mean이 0.01로 나타났습니다.
  3. 형태 복잡도 관련 특성 분석 :
    • 가설 :
      • H0: 양성과 악성 종양의 형태 복잡도 관련 특성 평균은 동일하다
      • H1: 양성과 악성 종양의 형태 복잡도 관련 특성 평균은 다르다
    • 검정 결과 :
      • compactness_mean: t-score -17.70, p-value 0.000
      • concavity_mean: t-score -23.10, p-value 0.000
      • concave points_mean: t-score -29.35, p-value 0.000
    • 해석 :
      • 모든 형태 복잡도 특성에서 p-value가 0.05보다 작아 귀무가설을 기각합니다.
      • concave points_mean이 가장 높은 t-score 절댓값(-29.35)을 보여, 가장 강력한 차이를 나타냅니다.
      • concavity_mean이 평균 차이 0.11로 가장 큰 차이를 보입니다.
  4. 구조적 관련 관련 특성 분석 :
    • 가설 :
      • H0: 양성과 악성 종양의 구조적 관련 특성 평균은 동일하다
      • H1: 양성과 악성 종양의 구조적 관련 특성 평균은 다르다
    • 검정 결과 :
      • symmetry_mean: t-score -8.34, p-value 0.000
      • fractal_dimension_mean: t-score 0.31, p-value 0.760
    • 해석 :
      • symmetry_mean은 p-value가 0.05보다 작아 귀무가설을 기각합니다.
      • 반면 fractal_dimension_mean은 p-value가 0.76으로 귀무가설을 기각할 수 없습니다.
      • 구조적 특성은 다른 카테고리에 비해 상대적으로 낮은 t-score를 보입니다.
  • 종합 결론:
    • 분석된 모든 카테고리 중 형태 복잡도 특성의 concave points_mean이 가장 큰 t-score(-29.35)를 보여, 종양의 악성 여부를 판단하는데 가장 중요한 지표로 판단됨
    • 크기/형태 관련 특성들도 전반적으로 높은 t-score를 보여 중요한 판단 기준이 될 수 있음
    • 구조적 특성은 상대적으로 낮은 t-score를 보이며, fractal_dimension_mean의 경우 통계적으로 유의미한 차이를 보이지 않아 악성 여부 판단에 적합하지 않은 것으로 판단됨
    • 대부분의 특성에서 악성 종양이 양성 종양보다 큰 값을 보이는 경향이 있음

 

# 필수 2. 통계적 가설검정 1

def perform_ttest_by_category(df, features):
   results = []
   for feature in features:
       # 양성과 악성 그룹 나누기
       benign = df[df['diagnosis'] == 'B'][feature]
       malignant = df[df['diagnosis'] == 'M'][feature]

       # T-test 수행
       t_stat, p_value = stats.ttest_ind(benign, malignant)

       # 평균값 계산
       mean_diff = malignant.mean() - benign.mean()

       results.append({
           'feature': feature,
           't_score': t_stat,
           'p_value': p_value,
           'mean_benign': benign.mean(),
           'mean_malignant': malignant.mean(),
           'mean_difference': mean_diff
       })

   return pd.DataFrame(results)

# 카테고리별 특성 정의
size_shape = ['radius_mean', 'perimeter_mean', 'area_mean']
surface = ['texture_mean', 'smoothness_mean']
morphological = ['compactness_mean', 'concavity_mean', 'concave points_mean']
structural = ['symmetry_mean', 'fractal_dimension_mean']

# 각 카테고리별 분석 수행 및 결과 출력
print("1. 크기/형태 관련 특성 분석")
print("-" * 50)
size_results = perform_ttest_by_category(df, size_shape)
print("\n크기/형태 특성 T-test 결과:")
print(size_results.round(4))

print("\n2. 표면 특성 분석")
print("-" * 50)
surface_results = perform_ttest_by_category(df, surface)
print("\n표면 특성 T-test 결과:")
print(surface_results.round(4))

print("\n3. 형태 복잡도 특성 분석")
print("-" * 50)
morphological_results = perform_ttest_by_category(df, morphological)
print("\n형태 복잡도 특성 T-test 결과:")
print(morphological_results.round(4))

print("\n4. 구조적 특성 분석")
print("-" * 50)
structural_results = perform_ttest_by_category(df, structural)
print("\n구조적 특성 T-test 결과:")
print(structural_results.round(4))

# 종합 분석: 각 카테고리에서 가장 영향력 있는 특성 찾기
def get_most_significant_feature(results):
   return results.loc[results['t_score'].abs().idxmax()]

print("\n\n종합 분석")
print("=" * 50)
print("\n각 카테고리별 가장 영향력 있는 특성:")
categories = {
   '크기/형태': size_results,
   '표면': surface_results,
   '형태 복잡도': morphological_results,
   '구조적': structural_results
}

for category_name, results in categories.items():
   most_sig = get_most_significant_feature(results)
   print(f"\n{category_name} 카테고리:")
   print(f"- 가장 영향력 있는 특성: {most_sig['feature']}")
   print(f"- t-score: {most_sig['t_score']:.4f}")
   print(f"- p-value: {most_sig['p_value']:.4f}")
   print(f"- 평균 차이: {most_sig['mean_difference']:.4f}")
1. 크기/형태 관련 특성 분석
--------------------------------------------------

크기/형태 특성 T-test 결과:
          feature  t_score  p_value  mean_benign  mean_malignant  \
0     radius_mean -25.4358      0.0      12.1465         17.4628   
1  perimeter_mean -26.4052      0.0      78.0754        115.3654   
2       area_mean -23.9387      0.0     462.7902        978.3764   

   mean_difference  
0           5.3163  
1          37.2900  
2         515.5862  

2. 표면 특성 분석
--------------------------------------------------

표면 특성 T-test 결과:
           feature  t_score  p_value  mean_benign  mean_malignant  \
0     texture_mean -10.8672      0.0      17.9148         21.6049   
1  smoothness_mean  -9.1461      0.0       0.0925          0.1029   

   mean_difference  
0           3.6901  
1           0.0104  

3. 형태 복잡도 특성 분석
--------------------------------------------------

형태 복잡도 특성 T-test 결과:
               feature  t_score  p_value  mean_benign  mean_malignant  \
0     compactness_mean -17.6984      0.0       0.0801          0.1452   
1       concavity_mean -23.1040      0.0       0.0461          0.1608   
2  concave points_mean -29.3543      0.0       0.0257          0.0880   

   mean_difference  
0           0.0651  
1           0.1147  
2           0.0623  

4. 구조적 특성 분석
--------------------------------------------------

구조적 특성 T-test 결과:
                  feature  t_score  p_value  mean_benign  mean_malignant  \
0           symmetry_mean  -8.3383   0.0000       0.1742          0.1929   
1  fractal_dimension_mean   0.3057   0.7599       0.0629          0.0627   

   mean_difference  
0           0.0187  
1          -0.0002  


종합 분석
==================================================

각 카테고리별 가장 영향력 있는 특성:

크기/형태 카테고리:
- 가장 영향력 있는 특성: perimeter_mean
- t-score: -26.4052
- p-value: 0.0000
- 평균 차이: 37.2900

표면 카테고리:
- 가장 영향력 있는 특성: texture_mean
- t-score: -10.8672
- p-value: 0.0000
- 평균 차이: 3.6901

형태 복잡도 카테고리:
- 가장 영향력 있는 특성: concave points_mean
- t-score: -29.3543
- p-value: 0.0000
- 평균 차이: 0.0623

구조적 카테고리:
- 가장 영향력 있는 특성: symmetry_mean
- t-score: -8.3383
- p-value: 0.0000
- 평균 차이: 0.0187

 

 

- 필수3. 통계적 가설검정2(ANOVA)

필수 3. 통계적 가설검정 2
  • Breast Cancer 데이터셋의 종양 특성들을 카테고리별로 분석하려 합니다. 각 카테고리에 속한 개별 특성들의 diagnosis(양성/악성)에 따른 측정치(mean, se, worst) 간 차이를 ANOVA로 분석해주세요.
    • 크기/형태 관련 특성의 분석
    • 진단(diagnosis)그룹(악성(M), 양성(B)))에 따라 radius (mean, se, worst), perimeter (mean, se, worst), area (mean, se, worst)에 대해 각각의 평균값에 통계적으로 유의미한 차이가 있는지 ANOVA로 분석하세요.
    • 표면 특성의 분석
    • 진단(diagnosis)그룹(악성(M), 양성(B)))에 따라 texture (mean, se, worst), smoothness (mean, se, worst)에 대해 각각의 평균값에 통계적으로 유의미한 차이가 있는지 ANOVA로 분석하세요.
    • 형태 복잡도 특성의 분석
    • 진단(diagnosis)그룹(악성(M), 양성(B)))에 따라compactness (mean, se, worst), concavity (mean, se, worst), - concave points (mean, se, worst)에 대해 각각의 평균값에 통계적으로 유의미한 차이가 있는지 ANOVA로 분석하세요.
    • 구조적 특성의 분석
    • 진단(diagnosis)그룹(악성(M), 양성(B)))에 따라 symmetry (mean, se, worst), fractal dimension (mean, se, worst)에 대해 각각의 평균값에 통계적으로 유의미한 차이가 있는지 ANOVA로 분석하세요.
  • 가설검정 방법은 각 카테고리별로:
    • 귀무가설과 대립가설을 작성하세요.
    • t-score와 p-value를 구하세요.
    • 귀무가설의 채택/기각 여부를 판단하세요.
    • 해당 카테고리 내에서 어떤 특성이 악성 종양 판별에 가장 큰 영향을 미치는지 분석하세요.
필수 3 답안
  1. 크기/형태 관련 특성 분석 :
    • 가설 :
      • H0: mean, se, worst 값 간의 평균 차이가 없다
      • H1: mean, se, worst 값 간의 평균 차이가 있다
    • 검정 결과 :
      • radius: F-statistic 3527.30, p-value 0.0000
      • perimeter: F-statistic 3147.87, p-value 0.0000
      • area: F-statistic 717.21, p-value 0.0000
    • 해석 :
      • 모든 특성에서 p-value가 0.05보다 작아 귀무가설을 기각합니다.
      • radius가 가장 높은 F-statistic(3527.30)을 보여 가장 유의미한 차이를 나타냅니다.
      • area는 상대적으로 낮은 F-statistic을 보이지만, 절대적 차이(max_diff)는 840.25로 가장 큽니다.
  2. 표면 관련 특성 분석 :
    • 가설 :
      • H0: mean, se, worst 값 간의 평균 차이가 없다
      • H1: mean, se, worst 값 간의 평균 차이가 있다
    • 검정 결과 :
      • texture: F-statistic 4856.02, p-value 0.0000
      • smoothness: F-statistic 9760.90, p-value 0.0000
    • 해석 :
      • 두 특성 모두 p-value가 0.05보다 작아 귀무가설을 기각합니다.
      • smoothness가 매우 높은 F-statistic(9760.90)을 보여 가장 강력한 차이를 나타냅니다.
      • texture의 max_diff가 24.46으로 smoothness(0.13)보다 절대적 차이가 큽니다.
  3. 형태 복잡도 관련 특성 분석 :
    • 가설 :
      • H0: mean, se, worst 값 간의 평균 차이가 없다
      • H1: mean, se, worst 값 간의 평균 차이가 있다
    • 검정 결과 :
      • compactness: F-statistic 827.42, p-value 0.0000
      • concavity: F-statistic 529.96, p-value 0.0000
      • concave points: F-statistic 788.95, p-value 0.0000
    • 해석 :
      • 모든 특성에서 p-value가 0.05보다 작아 귀무가설을 기각합니다.
      • compactness가 가장 높은 F-statistic(827.42)을 보입니다.
      • concavity가 max_diff 0.24로 가장 큰 절대적 차이를 보입니다.
  4. 구조적 관련 특성 분석 :
    • 가설 :
      • H0: mean, se, worst 값 간의 평균 차이가 없다
      • H1: mean, se, worst 값 간의 평균 차이가 있다
    • 검정 결과 :
      • symmetry: F-statistic 6752.70, p-value 0.0000
      • fractal_dimension: F-statistic 7689.02, p-value 0.0000
    • 해석 :
      • 두 특성 모두 p-value가 0.05보다 작아 귀무가설을 기각합니다.
      • fractal_dimension이 더 높은 F-statistic(7689.02)을 보입니다.
      • symmetry가 max_diff 0.27로 더 큰 절대적 차이를 보입니다.
  • 종합 결론:
    • 모든 특성에서 세 측정치 간 통계적으로 유의미한 차이가 있음이 확인됨
    • 표면 특성 카테고리의 smoothness가 가장 큰 F-statistic을 보여, 측정치 간 가장 뚜렷한 차이를 보임
    • 대부분의 특성에서 worst > mean > se 순서로 값이 크게 나타남
    • 크기/형태 관련 특성들은 절대적 차이(max_diff)가 크지만, F-statistic 관점에서는 중간 정도의 차이를 보임
    • 이러한 결과는 각 특성의 측정치들이 서로 다른 정보를 제공하고 있으며, 특히 worst 값이 mean, se 값과 상당한 차이를 보여 종양 특성을 파악하는데 중요한 정보를 제공할 수 있음을 시사함
from scipy import stats
import pandas as pd

def perform_anova_by_category(df, base_features):
    results = []
    for feature in base_features:
        # 세 측정치 추출
        mean_vals = df[f'{feature}_mean']
        se_vals = df[f'{feature}_se']
        worst_vals = df[f'{feature}_worst']

        # ANOVA 수행
        f_stat, p_value = stats.f_oneway(mean_vals, se_vals, worst_vals)

        # 평균값 계산
        results.append({
            'feature': feature,
            'f_statistic': f_stat,
            'p_value': p_value,
            'mean_mean': mean_vals.mean(),
            'mean_se': se_vals.mean(),
            'mean_worst': worst_vals.mean(),
            'max_diff': max(abs(mean_vals.mean() - se_vals.mean()),
                            abs(mean_vals.mean() - worst_vals.mean()),
                            abs(se_vals.mean() - worst_vals.mean()))
        })

    return pd.DataFrame(results)


#  데이터프레임에서 양성 / 음성 분리 (열 이름 맞게 수정)
benign_df = df[df['diagnosis'] == 'B']      # 0: Benign
malignant_df = df[df['diagnosis'] == 'M']   # 1: Malignant

#  카테고리 정의 (기존 동일)
size_shape = ['radius', 'perimeter', 'area']
surface = ['texture', 'smoothness']
morphological = ['compactness', 'concavity', 'concave points']
structural = ['symmetry', 'fractal_dimension']

#  양성 / 음성 각각에 대해 수행
groups = {
    "Benign(음성)": benign_df,
    "Malignant(양성)": malignant_df
}

for group_name, group_df in groups.items():
    print(f"\n\n===== {group_name} 그룹 ANOVA 분석 =====")

    print("\n1. 크기/형태 관련 특성 분석")
    size_results = perform_anova_by_category(group_df, size_shape)
    print(size_results.round(4))

    print("\n2. 표면 특성 분석")
    surface_results = perform_anova_by_category(group_df, surface)
    print(surface_results.round(4))

    print("\n3. 형태 복잡도 특성 분석")
    morphological_results = perform_anova_by_category(group_df, morphological)
    print(morphological_results.round(4))

    print("\n4. 구조적 특성 분석")
    structural_results = perform_anova_by_category(group_df, structural)
    print(structural_results.round(4))

    #  해당 그룹에서 카테고리별 가장 큰 차이를 보이는 feature 출력
    def get_most_different_feature(results):
        return results.loc[results['f_statistic'].abs().idxmax()]

    print("\n▶ 카테고리별 가장 큰 측정치 차이를 보이는 특성")
    categories = {
        '크기/형태': size_results,
        '표면': surface_results,
        '형태 복잡도': morphological_results,
        '구조적': structural_results
    }

    for category_name, results in categories.items():
        most_diff = get_most_different_feature(results)
        print(f"\n[{category_name}]")
        print(f"- 특성: {most_diff['feature']}")
        print(f"- F-statistic: {most_diff['f_statistic']:.4f}")
        print(f"- p-value: {most_diff['p_value']:.4f}")
        print(f"- mean 값: {most_diff['mean_mean']:.4f}")
        print(f"- se 값: {most_diff['mean_se']:.4f}")
        print(f"- worst 값: {most_diff['mean_worst']:.4f}")


===== Benign(음성) 그룹 ANOVA 분석 =====

1. 크기/형태 관련 특성 분석
     feature  f_statistic  p_value  mean_mean  mean_se  mean_worst  max_diff
0     radius    7877.9312      0.0    12.1465   0.2841     13.3798   13.0957
1  perimeter    7235.8446      0.0    78.0754   2.0003     87.0059   85.0056
2       area    1962.8767      0.0   462.7902  21.1351    558.8994  537.7643

2. 표면 특성 분석
      feature  f_statistic  p_value  mean_mean  mean_se  mean_worst  max_diff
0     texture    3098.8495      0.0    17.9148   1.2204     23.5151   22.2947
1  smoothness    6707.3312      0.0     0.0925   0.0072      0.1250    0.1178

3. 형태 복잡도 특성 분석
          feature  f_statistic  p_value  mean_mean  mean_se  mean_worst  \
0     compactness     720.2337      0.0     0.0801   0.0214      0.1827   
1       concavity     271.7046      0.0     0.0461   0.0260      0.1662   
2  concave points     774.2281      0.0     0.0257   0.0099      0.0744   

   max_diff  
0    0.1612  
1    0.1402  
2    0.0646  

4. 구조적 특성 분석
             feature  f_statistic  p_value  mean_mean  mean_se  mean_worst  \
0           symmetry    7056.4308      0.0     0.1742   0.0206      0.2702   
1  fractal_dimension    6951.1999      0.0     0.0629   0.0036      0.0794   

   max_diff  
0    0.2497  
1    0.0758  

▶ 카테고리별 가장 큰 측정치 차이를 보이는 특성

[크기/형태]
- 특성: radius
- F-statistic: 7877.9312
- p-value: 0.0000
- mean 값: 12.1465
- se 값: 0.2841
- worst 값: 13.3798

[표면]
- 특성: smoothness
- F-statistic: 6707.3312
- p-value: 0.0000
- mean 값: 0.0925
- se 값: 0.0072
- worst 값: 0.1250

[형태 복잡도]
- 특성: concave points
- F-statistic: 774.2281
- p-value: 0.0000
- mean 값: 0.0257
- se 값: 0.0099
- worst 값: 0.0744

[구조적]
- 특성: symmetry
- F-statistic: 7056.4308
- p-value: 0.0000
- mean 값: 0.1742
- se 값: 0.0206
- worst 값: 0.2702


===== Malignant(양성) 그룹 ANOVA 분석 =====

1. 크기/형태 관련 특성 분석
     feature  f_statistic  p_value  mean_mean  mean_se  mean_worst   max_diff
0     radius    2651.8503      0.0    17.4628   0.6091     21.1348    20.5257
1  perimeter    2492.3763      0.0   115.3654   4.3239    141.3703   137.0464
2       area     605.8169      0.0   978.3764  72.6724   1422.2863  1349.6139

2. 표면 특성 분석
      feature  f_statistic  p_value  mean_mean  mean_se  mean_worst  max_diff
0     texture    3044.7330      0.0    21.6049   1.2109     29.3182   28.1073
1  smoothness    4935.4538      0.0     0.1029   0.0068      0.1448    0.1381

3. 형태 복잡도 특성 분석
          feature  f_statistic  p_value  mean_mean  mean_se  mean_worst  \
0     compactness     600.3386      0.0     0.1452   0.0323      0.3748   
1       concavity     720.2198      0.0     0.1608   0.0418      0.4506   
2  concave points    1331.1311      0.0     0.0880   0.0151      0.1822   

   max_diff  
0    0.3425  
1    0.4088  
2    0.1672  

4. 구조적 특성 분석
             feature  f_statistic  p_value  mean_mean  mean_se  mean_worst  \
0           symmetry    2280.0136      0.0     0.1929   0.0205      0.3235   
1  fractal_dimension    2401.6841      0.0     0.0627   0.0041      0.0915   

   max_diff  
0    0.3030  
1    0.0875  

▶ 카테고리별 가장 큰 측정치 차이를 보이는 특성

[크기/형태]
- 특성: radius
- F-statistic: 2651.8503
- p-value: 0.0000
- mean 값: 17.4628
- se 값: 0.6091
- worst 값: 21.1348

[표면]
- 특성: smoothness
- F-statistic: 4935.4538
- p-value: 0.0000
- mean 값: 0.1029
- se 값: 0.0068
- worst 값: 0.1448

[형태 복잡도]
- 특성: concave points
- F-statistic: 1331.1311
- p-value: 0.0000
- mean 값: 0.0880
- se 값: 0.0151
- worst 값: 0.1822

[구조적]
- 특성: fractal_dimension
- F-statistic: 2401.6841
- p-value: 0.0000
- mean 값: 0.0627
- se 값: 0.0041
- worst 값: 0.0915

 

- 필수4. 머신러닝

필수 4. 머신러닝 1
  • 아래와 같은 데이터를 바탕으로 선형 회귀 모델을 훈련시키고, 회귀식을 작성해주세요.
    • 독립 변수(X): radius_mean (평균 반지름)
    • 종속 변수(Y): area_mean (평균 면적)
  • 이 두 변수는 직관적으로 서로 관계가 있을 것으로 예상됩니다
    (반지름이 커지면 면적도 커질 것).회귀 모델을 학습한 후:
    • 결정계수(R²)를 계산해주세요.
    • 회귀식을 작성해주세요.
    • radius_mean이 25일 때의 area_mean을 예측해주세요.
  • 유의 사항
    • 데이터 전처리나 분할은 필요하지 않습니다. 전체 데이터를 사용하여 학습을 진행해주세요.
    • sklearn.linear_model의 LinearRegression을 사용해주세요.
 

 

# 필수 4. 머신러닝 1

# 독립변수(X)와 종속변수(Y) 준비
X = df['radius_mean'].values.reshape(-1, 1)  # 2D array 형태로 변환
Y = df['area_mean'].values

# 선형 회귀 모델 학습
model = LinearRegression()
model.fit(X, Y)

# 결정계수(R²) 계산
r_squared = model.score(X, Y)

# 회귀식 계수
slope = model.coef_[0] #기울기 가중치
intercept = model.intercept_

# radius_mean이 25일 때의 예측
new_radius = np.array([[25]]) #판다스로 만들어도 무관하다.
predicted_area = model.predict(new_radius)[0]

# 시각화
plt.figure(figsize=(10, 6))
plt.scatter(X, Y, color='blue', alpha=0.5, label='실제 데이터')
plt.plot(X, model.predict(X), color='red', label='회귀선')
plt.scatter(new_radius, predicted_area, color='green', s=100, label='예측값')
plt.xlabel('radius_mean')
plt.ylabel('area_mean')
plt.title('Radius와 Area의 선형 회귀 관계')
plt.legend()
plt.grid(True)
plt.show()

# 결과 출력
print("1. 결정계수(R²):", round(r_squared, 4))
print("\n2. 회귀식:")
print(f"area_mean = {round(slope, 2)} × radius_mean + {round(intercept, 2)}")
print("\n3. 예측 결과:")
print(f"radius_mean이 25일 때의 예측 area_mean: {round(predicted_area, 2)}")
1. 결정계수(R²): 0.9749
2. 회귀식: area_mean = 98.6 × radius_mean + -738.04
3. 예측 결과: radius_mean이 25일 때의 예측 area_mean: 1726.92

 

도전1. 머신러닝 2

  • 과제
    크기/형태 관련 특성(radius_mean, perimeter_mean, area_mean)을 사용하여 종양의 악성 여부(diagnosis)를 예측하는 RandomForest 모델을 학습시켜주세요.
    학습된 모델을 사용하여 다음 작업을 수행해주세요.
    1. 모델의 정확도를 계산해주세요.
    2. Feature Importance를 막대 그래프로 시각화해주세요.
    3. 각 특성의 중요도 수치를 출력하고 해석해주세요.
  • 학습 방법
    • y(종속변수)는 B/M으로 기재된 이진형 데이터이므로, 인코딩 작업이 필요합니다.
      구현을 위해 LabelEncoder를 사용해주세요.
    • 머신러닝 코드 작성 시, 전체 데이터셋을 Train set과 Test set으로 나눠주세요.
      • Test set 비중 : 30%
      • random_state : 42
    • RandomForestClassifier를 활용하여 모델 학습을 진행해주세요.
      • random_state : 42
도전 1 답안 3. Feature Importance 해석 - perimeter_mean가 0.3541로 가장 중요한 특성으로 나타났습니다. - 이는 종양의 크기/형태 특성 중에서 perimeter_mean가 악성 여부를 판단하는데 가장 큰 영향을 미친다는 것을 의미합니다.
#도전 1. 머신러닝 2

# 크기/형태 관련 특성 선택
X = df[['radius_mean', 'perimeter_mean', 'area_mean']]
y = df['diagnosis']

# 레이블 인코딩
le = LabelEncoder()
y = le.fit_transform(y)

# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# RandomForest 모델 학습
rf_model = RandomForestClassifier(random_state=42)
rf_model.fit(X_train, y_train)

# 모델 평가
y_pred = rf_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)

# Feature Importance 시각화
importances = rf_model.feature_importances_
feature_names = X.columns

plt.figure(figsize=(10, 6))
bars = plt.bar(feature_names, importances)
plt.title('Feature Importance in Random Forest Model')
plt.xlabel('Features')
plt.ylabel('Importance')
plt.xticks(rotation=45)

# 중요도 값 표시
for bar in bars:
   height = bar.get_height()
   plt.text(bar.get_x() + bar.get_width()/2., height,
            f'{height:.4f}',
            ha='center', va='bottom')

plt.tight_layout()
plt.show()

# 결과 출력
print("1. 모델 정확도:", round(accuracy * 100, 2), "%")

print("\n3. Feature Importance 수치:")
importance_df = pd.DataFrame({
   'Feature': feature_names,
   'Importance': importances
}).sort_values('Importance', ascending=False)

print(importance_df)
print("\nFeature Importance 해석:")
most_important = importance_df.iloc[0]
print(f"- {most_important['Feature']}{most_important['Importance']:.4f}로 가장 중요한 특성으로 나타났습니다.")
print(f"- 이는 종양의 크기/형태 특성 중에서 {most_important['Feature']}가")
print("  악성 여부를 판단하는데 가장 큰 영향을 미친다는 것을 의미합니다.")
1. 모델 정확도: 91.81 %

3. Feature Importance 수치: Feature Importance 1 perimeter_mean 0.354107 0 radius_mean 0.338884 2 area_mean 0.307009

Feature Importance 해석: - perimeter_mean가 0.3541로 가장 중요한 특성으로 나타났습니다. - 이는 종양의 크기/형태 특성 중에서 perimeter_mean가 악성 여부를 판단하는데 가장 큰 영향을 미친다는 것을 의미합니다.

 

도전 2. 머신러닝 3


  • 과제
    형태 복잡도 특성(compactness_mean, concavity_mean, concave points_mean)을 사용하여 종양의 악성 여부를 예측하는 로지스틱 회귀 모델을 학습시켜주세요.
    학습된 모델을 사용하여 다음 작업을 수행해주세요.
    1. 모델의 정확도를 계산해주세요.
    2. 각 특성의 계수를 막대 그래프로 시각화해주세요.
    3. 아래의 조건에 맞춰, 새로운 종양의 악성 확률을 계산해주세요.
      • compactness_mean : 0.1
      • concavity_mean : 0.1
      • concave points_mean : 0.05
  • 학습 및 추론 방법
    • y(종속변수)는 B/M으로 기재된 이진형 데이터이므로, 인코딩 작업이 필요합니다.
      구현을 위해 LabelEncoder를 사용해주세요.
    • 머신러닝 코드 작성 시, 전체 데이터셋을 Train set과 Test set으로 나눠주세요.
      • Test set 비중 : 30%
      • random_state : 42
    • 계수 시각화 코드 작성 시, 각 특성의 계수 크기를 비교할 수 있도록 막대 그래프를 생성하세요.
      • 양수/음수를 다른 색상으로 표시해주세요.
    • 새로운 종양 데이터를 new_tumor 변수에 지정하고, **model.predict_proba**를 사용하여 악성 확률을 구해주세요.
 

 

# 도전 2. 머신러닝 3

# 형태 복잡도 특성 선택
X = df[['compactness_mean', 'concavity_mean', 'concave points_mean']]
y = df['diagnosis']

# 레이블 인코딩
le = LabelEncoder()
y = le.fit_transform(y)

# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 로지스틱 회귀 모델 학습
log_model = LogisticRegression(random_state=42)
log_model.fit(X_train, y_train)

# 모델 평가
y_pred = log_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)

# 계수 시각화
coefficients = log_model.coef_[0]
feature_names = X.columns

plt.figure(figsize=(10, 6))
colors = ['red' if c < 0 else 'blue' for c in coefficients]
bars = plt.bar(feature_names, coefficients, color=colors)
plt.title('Logistic Regression Coefficients')
plt.xlabel('Features')
plt.ylabel('Coefficient Value')
plt.xticks(rotation=45)

# 계수 값 표시
for bar in bars:
    height = bar.get_height()
    plt.text(bar.get_x() + bar.get_width()/2., height,
             f'{height:.2f}',
             ha='center', va='bottom' if height > 0 else 'top')

plt.show()

# 새로운 종양 데이터에 대한 예측
new_tumor = np.array([[0.1, 0.1, 0.05]])
probabilities = log_model.predict_proba(new_tumor)

# 결과 출력
print("1. 모델 정확도:", round(accuracy * 100, 2), "%")
# [양성= 86.5, 악성 .13.5]
print("\n3. 새로운 종양의 예측 확률:")
print("양성(B) 확률:", round(probabilities[0][0] * 100, 2), "%")
print("악성(M) 확률:", round(probabilities[0][1] * 100, 2), "%")
1. 모델 정확도: 82.46 %
3. 새로운 종양의 예측 확률: 양성(B) 확률: 61.81 % 악성(M) 확률: 38.19 %

'빅데이터 QAQC_3기 > 빅데이터 QAQC_3기 TIL' 카테고리의 다른 글

TIL_251110  (1) 2025.11.10
TIL_251107  (0) 2025.11.07
TIL_251103  (0) 2025.11.03
TIL_251030  (0) 2025.10.30
TIL_251029  (1) 2025.10.29