View
1. 데이터 로드
import pandas as pd
df = pd.read_csv('./titanic.csv')
print('Train 데이터 정보')
print(df.info())
df.head(3)
- pd.read_csv('./titanic.csv')
- titanic.csv 파일을 읽어 DataFrame으로 불러옵니다.
- 파일 경로와 이름이 정확해야 오류가 발생하지 않습니다.
- df.info()
- 데이터의 구조(열 이름, 데이터 타입, 결측값 여부 등)를 출력합니다.
- 데이터를 탐색하기 위한 기본적인 정보를 제공합니다.
- df.head(3)
- DataFrame의 상위 3개 행을 출력합니다.
- 데이터 샘플을 확인할 수 있습니다.df.head(3):
2. 데이터 전처리
1) 결측치 처리
- Age : 평균 값으로 채우기
- Cabin : N으로 채우기
- Embarked : N으로 채우기
def fillna(df):
df['Age'] = df['Age'].fillna(df['Age'].mean())
df['Cabin'] = df['Cabin'].fillna('N')
df['Embarked'] = df['Embarked'].fillna('N')
return df
- df['Age'] 결측값 처리:
- Age 열의 결측값을 해당 열의 평균값으로 채웁니다.
- 숫자형 데이터에서 결측값을 처리할 때 평균값을 사용하는 것이 일반적입니다.
- df['Cabin'] 결측값 처리:
- Cabin 열의 결측값을 **'N'**으로 채웁니다.
- 문자열 데이터에서 결측값을 특정 문자로 채우는 방식입니다.
- df['Embarked'] 결측값 처리:
- Embarked 열의 결측값을 **'N'**으로 채웁니다.
- 이 열도 문자열이므로 같은 방식으로 처리합니다.
- return df : 결측값이 처리된 DataFrame을 반환합니다.
2) 필요없는 컬럼 제거
def drop_columns(df):
return df.drop(['PassengerId', 'Name', 'Ticket'], axis=1)
- df.drop:
- ['PassengerId', 'Name', 'Ticket']: 제거할 열 목록을 지정합니다.
- axis=1: 열 단위로 작업을 수행하도록 지정합니다.
- 반환값은 지정한 열이 제거된 새로운 데이터프레임입니다.
- 반환값 : 입력 데이터프레임(df)에서 PassengerId, Name, Ticket 열이 제거된 데이터프레임을 반환합니다.
3) 범주형 데이터 처리
- Sex : 숫자형 변환
- Embarked : 숫자형 변환
- Cabin : 첫 번째 문자만 추출 후 숫자형 변환
from sklearn.preprocessing import LabelEncoder
def format_features(df):
df['Cabin'] = df['Cabin'].astype(str).str[:1]
features = ['Cabin', 'Sex', 'Embarked']
for feature in features:
le = LabelEncoder()
df[feature] = le.fit_transform(df[feature])
return df
- df['Cabin'].astype(str).str[:1]
- Cabin 열의 값을 문자열로 변환한 후, 각 값의 첫 번째 문자만 추출합니다.
- 예: 'C123' → 'C', NaN → 'n' (문자열 'NaN'이 됩니다).
- features 리스트
- 숫자형으로 변환할 열 목록을 정의합니다: ['Cabin', 'Sex', 'Embarked'].
- LabelEncoder 사용
- LabelEncoder는 범주형 데이터를 숫자형으로 변환하는 도구입니다.
- 각 열의 고유 값을 정수로 매핑합니다.
- 예: Sex 열의 값이 ['male', 'female']일 경우, 'male' → 1, 'female' → 0.
- 반환
- 변환된 DataFrame을 반환합니다.
4) 데이터 전처리 함수
def transform_features(df):
df = fillna(df)
df = drop_columns(df)
df = format_features(df)
return df
- fillna(df)
- 결측값 처리 함수입니다.
- 데이터에 포함된 결측값을 적절히 채워줍니다.
- drop_columns(df)
- 불필요한 열을 제거하는 함수입니다.
- 예: 이름(Name), 티켓 번호(Ticket) 등 모델 학습에 필요하지 않은 열을 제거합니다.
- format_features(df)
- 범주형 데이터 변환 함수입니다.
- 문자열 데이터(Sex, Embarked, Cabin 등)를 숫자로 변환하여 모델 학습에 적합하게 만듭니다.
- 반환 : 결측값 처리, 불필요한 열 제거, 범주형 데이터 변환이 완료된 DataFrame을 반환합니다.
3. 데이터 분리(X, y)
y_titanic_df = df['Survived']
X_titanic_df = df.drop('Survived', axis=1, inplace=False)
X_titanic_df = transform_features(X_titanic_df)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X_titanic_df, y_titanic_df, test_size=0.2, random_state=11)
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
X_titanic_df
X_titanic_df.isnull().sum()
- df['Survived'] : 생존 여부(Survived)를 타겟 변수로 설정합니다.
- df.drop('Survived', axis=1, inplace=False) : Survived 열을 제외한 나머지 데이터를 피처 데이터로 분리합니다.
- transform_features(X_titanic_df) : 전처리 함수를 호출하여 결측값 처리 및 범주형 데이터 변환을 수행합니다.
- train_test_split: 데이터를 학습용(X_train, y_train)과 테스트용(X_test, y_test)으로 분리합니다.
- test_size=0.2: 데이터의 20%를 테스트 세트로 사용합니다.
- random_state=11: 재현 가능한 결과를 위해 시드를 고정합니다.
- 데이터의 각 열에 대해 결측값 개수를 확인합니다.
- 출력값이 0이어야 결측값 처리가 완료되었다는 것을 확인할 수 있습니다.
4. 모델 학습
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
models = {
'DecisionTree' : DecisionTreeClassifier(random_state=44),
'RandomForest' : RandomForestClassifier(random_state=44),
'LogisticRegression' : LogisticRegression(solver='liblinear')
}
1) models 딕셔너리
- 여러 모델을 딕셔너리 형태로 저장하여 관리합니다.
- 각 키는 모델의 이름, 값은 해당 모델의 인스턴스입니다.
models = {
'DecisionTree': DecisionTreeClassifier(random_state=44),
'RandomForest': RandomForestClassifier(random_state=44),
'LogisticRegression': LogisticRegression(solver='liblinear')
}
2) random_state와 solver
- random_state=44: 모델 학습 결과를 재현 가능하게 하기 위해 사용됩니다.
- solver='liblinear': 로지스틱 회귀에서 사용되는 최적화 알고리즘을 지정합니다.
3) accuracy_score, confusion_matrix, classification_report
모델 평가를 위한 Scikit-learn의 대표적인 평가 메트릭입니다.
- accuracy_score: 정확도 계산.
- confusion_matrix: 예측 결과를 요약한 혼동 행렬.
- classification_report: 정밀도(Precision), 재현율(Recall), F1-스코어 등을 포함한 상세 보고서.
5. 평가
def evaluate_models(models, X_train, X_test, y_train, y_test):
results = {}
for name, model in models.items():
model.fit(X_train, y_train)
pred = model.predict(X_test)
acc = accuracy_score(y_test, pred)
results[name] = acc
print(f'{name} 정확도: {acc:.4f}')
print("Confusion Matrix:\n", confusion_matrix(y_test, pred))
print("Classification Report:\n", classification_report(y_test, pred))
return results
# 모델 평가
results = evaluate_models(models, X_train, X_test, y_train, y_test)
- 모델 학습 및 평가 : 각 모델을 학습 (fit)하고 테스트 데이터에 대해 예측 (predict)을 수행합니다.
- 정확도 계산 : accuracy_score를 사용하여 각 모델의 정확도를 계산합니다.
- 혼동 행렬 및 분류 보고서
- confusion_matrix: 모델의 예측 성능을 상세히 확인할 수 있습니다.
- classification_report: 정밀도(precision), 재현율(recall), F1-score를 포함한 성능 지표를 제공합니다.
- 결과 저장 : 각 모델의 이름과 정확도를 딕셔너리 (results)에 저장하여 나중에 비교할 수 있도록 합니다.
6. 시각화
import matplotlib.pyplot as plt
plt.bar(results.keys(), results.values())
plt.title('Model Accuracy Comparison')
plt.ylabel('Accuracy')
plt.show()
- plt.bar :
- 막대 그래프를 생성합니다.
- results.keys(): x축 값(모델 이름).
- results.values(): y축 값(모델 정확도).
- plt.title : 그래프 상단에 제목을 추가합니다: "Model Accuracy Comparison".
- plt.ylabel : y축 레이블을 설정합니다: "Accuracy".
- plt.show : 그래프를 화면에 출력합니다.
7. K-Fold 교차 검증
# for 문
from sklearn.model_selection import KFold
import numpy as np
def exec_kfold(clf, folds=5):
kfold = KFold(n_splits=folds)
scores = []
for iter_count, (train_index, test_index) in enumerate(kfold.split(X_titanic_df)):
X_train, X_test = X_titanic_df.values[train_index], X_titanic_df.values[test_index]
y_train, y_test = y_titanic_df.values[train_index], y_titanic_df.values[test_index]
clf.fit(X_train, y_train)
predictions = clf.predict(X_test)
accuracy = accuracy_score(y_test, predictions)
scores.append(accuracy)
print(f'교차 검증 {iter_count} 정확도: {accuracy:.4f}')
mean_score = np.mean(scores)
print(f'평균 정확도: {mean_score:.4f}')
exec_kfold(DecisionTreeClassifier(random_state=11))
- K-Fold 객체 생성:
- KFold(n_splits=folds): 데이터를 folds 개수만큼 나누는 K-Fold 객체를 생성합니다.
- 교차 검증 반복:
- kfold.split(X_titanic_df):
- 학습 데이터와 테스트 데이터를 n_splits 개수만큼 나눕니다.
- train_index, test_index: 현재 fold에서 학습용 및 테스트용 데이터의 인덱스를 반환합니다.
- kfold.split(X_titanic_df):
- 데이터 분리:
- X_titanic_df.values[train_index]: 인덱스를 사용하여 학습 및 테스트 데이터를 나눕니다.
- 모델 학습 및 예측:
- clf.fit(X_train, y_train): 학습 데이터를 사용해 모델을 학습합니다.
- clf.predict(X_test): 테스트 데이터에 대한 예측을 수행합니다.
- 정확도 계산:
- accuracy_score(y_test, predictions): 테스트 데이터에 대한 정확도를 계산합니다.
- 평균 정확도 출력:
- np.mean(scores): 모든 fold의 정확도를 평균 내어 모델의 전반적인 성능을 평가합니다.
8. 교차 검증 함수 (cross_val_score)
from sklearn.model_selection import cross_val_score
scores = cross_val_score(DecisionTreeClassifier(random_state=44), X_titanic_df, y_titanic_df, cv=5)
for iter_count, accuracy in enumerate(scores):
print(f'교차 검증: {iter_count}, 정확도: {accuracy}')
print(f'평균 정확도 >>>> {np.mean(scores):.4f}')
- cross_val_score:
- Scikit-learn에서 제공하는 교차 검증 함수입니다.
- 모델 학습, 검증 데이터 분리, 성능 평가를 한 번에 수행합니다.
- 매개변수:
- DecisionTreeClassifier(random_state=44): 학습에 사용할 모델.
- X_titanic_df, y_titanic_df: 입력 데이터(X)와 타겟(y).
- cv=5: 5-Fold 교차 검증을 수행.
- 결과:
- 각 Fold에서 계산된 정확도 값이 리스트 형태로 반환됩니다 (scores).
요약
- cross_val_score는 교차 검증 과정을 단순화하며, 효율적이고 간결하게 모델을 평가할 수 있도록 도와줍니다.
- 정확도 외에도 다양한 메트릭을 추가하여 모델 성능을 다각도로 평가할 수 있습니다.
- 시각화 및 결과 저장을 통해 모델의 성능을 더 직관적으로 분석할 수 있습니다.
9. 하이퍼파라미터 튜닝
from sklearn.model_selection import GridSearchCV
parameters = {'max_depth': [2, 3, 5, 10],
'min_samples_split': [2, 3, 5],
'min_samples_leaf': [1, 5, 8]}
grid_dclf = GridSearchCV(DecisionTreeClassifier(random_state=44), param_grid=parameters, scoring='accuracy', cv=5)
grid_dclf.fit(X_train, y_train)
print(f'GridSearchCV 최적 하이퍼 파라미터 >>>> {grid_dclf.best_params_}')
print(f'GridSearchCV 최고 정확도: {grid_dclf.best_score_}')
1) 하이퍼파라미터 설정
parameters = {'max_depth': [2, 3, 5, 10],
'min_samples_split': [2, 3, 5],
'min_samples_leaf': [1, 5, 8]}
(1) max_depth:
- 트리의 최대 깊이.
- 값이 작으면 과소적합(underfitting), 크면 과적합(overfitting) 위험이 있습니다.
(2) min_samples_split:
- 노드를 분할하기 위해 필요한 최소 샘플 수.
- 값이 작으면 세분화, 크면 일반화된 모델을 생성합니다.
(3) min_samples_leaf:
- 리프 노드가 가져야 하는 최소 샘플 수.
- 값이 클수록 리프 노드가 안정적으로 유지됩니다.
2) GridSearchCV 설정
grid_dclf = GridSearchCV(DecisionTreeClassifier(random_state=44), param_grid=parameters, scoring='accuracy', cv=5)
(1) DecisionTreeClassifier(random_state=44) : 성능을 평가할 기본 모델.
(2) param_grid=parameters : 탐색할 하이퍼파라미터 값의 조합.
(3) scoring='accuracy' : 평가 지표로 정확도를 사용합니다.
(4) cv=5 : 5-Fold 교차 검증을 수행합니다.
3) 모델 학습
grid_dclf.fit(X_train, y_train)
모든 하이퍼파라미터 조합에 대해 교차 검증을 수행하고 최적의 하이퍼파라미터를 찾습니다.
4) 결과 출력
print(f'GridSearchCV 최적 하이퍼 파라미터 >>>> {grid_dclf.best_params_}')
print(f'GridSearchCV 최고 정확도: {grid_dclf.best_score_}')
(1) grid_dclf.best_params_ : 최적의 하이퍼파라미터 조합을 반환합니다.
(2) grid_dclf.best_score_ : 최적의 하이퍼파라미터에서 얻은 최고 교차 검증 정확도를 반환합니다.
장점
- 자동화된 하이퍼파라미터 튜닝
- 모든 가능한 하이퍼파라미터 조합을 탐색하므로 수작업 없이 최적의 값을 찾을 수 있습니다.
- 교차 검증 내장
- 데이터의 훈련/검증 분할을 자동으로 수행하여 일반화된 성능을 평가합니다.
- 확장성
- 다양한 모델과 평가 지표에 쉽게 적용할 수 있습니다.
최적의 모델 반환
# depth >>>> 너무 깊으면 과적합될 가능성이 높아
# split >>>> 작으면 작을수록 트리가 복잡해져
# leaf >>>> 리프 노드가 최소한의 데이터를 포함하도록 설정
parameters = {'max_depth': [2, 3, 5, 10],
'min_samples_split': [2, 3, 5],
'min_samples_leaf': [1, 5, 8]}
# 조합의 개수
# 조합 수 = 4 x 3 x 3 == 36
1. max_depth (트리의 최대 깊이) : 너무 깊으면 과적합될 가능성이 높다.
- 트리가 깊을수록 데이터에 지나치게 맞춰져 복잡한 모델이 생성될 수 있습니다.
- 과적합된 모델은 학습 데이터에서는 높은 성능을 보이지만, 테스트 데이터에서는 일반화 능력이 떨어집니다.
2. min_samples_split (노드를 분할하기 위한 최소 샘플 수) : 작을수록 트리가 복잡해진다.
- 작은 값일수록 분할이 빈번하게 발생하며, 트리가 더욱 깊어집니다.
- 값이 너무 작으면 작은 변동에도 민감한 모델이 될 수 있습니다.
- 일반적으로 min_samples_split 값을 늘리면 모델의 복잡도가 줄어들어 과적합을 방지합니다.
3. min_samples_leaf (리프 노드가 포함해야 하는 최소 샘플 수) : 리프 노드가 최소한의 데이터를 포함하도록 설정
- 값이 너무 작으면 리프 노드가 극단적으로 세분화되며 과적합 위험이 있습니다.
- 일반적으로 데이터가 충분히 많을수록 min_samples_leaf 값을 크게 설정하는 것이 유리합니다.
파라미터 조합 계산
조합 계산 공식
총 조합 수 = max_depth 옵션 수 × min_samples_split 옵션 수 × min_samples_leaf 옵션 수
주어진 값 대입
- max_depth: 4가지 [2, 3, 5, 10]
- min_samples_split: 3가지 [2, 3, 5]
- min_samples_leaf: 3가지 [1, 5, 8]
총 조합 수 = 4 × 3 × 3 = 36
즉, GridSearchCV는 총 36번의 모델 학습 및 평가를 수행합니다.
GridSearchCV 설정
grid_dclf = GridSearchCV(
estimator=DecisionTreeClassifier(random_state=44),
param_grid=parameters,
scoring='accuracy',
cv=5
)
grid_dclf.fit(X_titanic_df, y_titanic_df)
1) estimator
- 성능 최적화를 진행할 모델을 지정합니다.
- 여기서는 DecisionTreeClassifier를 사용하고, random_state=44를 설정하여 재현성을 보장합니다.
2) param_grid
- 하이퍼파라미터의 값 범위를 정의합니다.
3) scoring
- 모델 성능을 평가할 지표를 지정합니다.
- 여기서는 accuracy를 사용하여 정확도를 평가합니다.
4) cv
- 교차 검증 횟수를 설정합니다.
- cv=5는 데이터를 5개 Fold로 나누어 5-Fold 교차 검증을 수행합니다.
5) fit : 모든 하이퍼파라미터 조합에 대해 학습과 평가를 수행합니다.
이 과정에서 교차 검증(cv=5)을 통해 각 조합의 평균 성능을 계산합니다.
print(f'최적의 파라미터 >>>> {grid_dclf.best_params_}')
print(f'최고 교차 검증 정확도 >>>> {grid_dclf.best_score_}')
best_model = grid_dclf.best_estimator_
best_model
pred = best_model.predict(X_titanic_df)
print(f'GridSearchCV 최적의 값 >>>> {accuracy_score(y_titanic_df, pred)}')
1. 최적의 하이퍼파라미터 및 교차 검증 최고 정확도 확인
- grid_dclf.best_params_ : GridSearchCV에서 탐색한 하이퍼파라미터 중 최고 성능을 보인 조합을 반환합니다.
- grid_dclf.best_score_ : 최적의 하이퍼파라미터 조합에서 얻어진 교차 검증 평균 정확도를 반환합니다.
2. 최적의 모델 확인 및 예측
- grid_dclf.best_estimator_ : 최적의 하이퍼파라미터로 학습된 모델 객체를 반환합니다.
3. 전체 데이터 예측
- predict : 최적의 모델(best_model)로 전체 데이터를 예측합니다.
4. 최적 모델 평가
- accuracy_score(y_titanic_df, pred) : 전체 데이터에 대한 정확도를 계산합니다.
'TIL' 카테고리의 다른 글
내일배움캠프 본캠프 29일차 - 혼동행렬 (0) | 2025.01.06 |
---|---|
내일배움캠프 5주차 WIL (3) | 2025.01.03 |
내일배움캠프 본캠프 27일차 (0) | 2025.01.02 |
내일배움캠프 본캠프 26일차 - GPT에게서 온 편지 (2) | 2024.12.31 |
내일배움캠프 본캠프 25일차 - 파이썬은 헷갈려 / 쟝고 투두리스트만들기 (0) | 2024.12.30 |