주제

3차 프로젝트 1일차

 

  • 3차 프로젝트는 머신 러닝 모델을 구현하여 성능 평가까지 해보는 것이 목표
  • 화요일에 멘토님에게 선정한 주제를 보여드리기 위해 첫날은 각자 주제를 탐색하고 저녁에 모여 최종 주제를 선정하기로 함
  • 내가 준비한 주제는 두가지 :
 

Breast Cancer Wisconsin (Diagnostic) Data Set

Predict whether the cancer is benign or malignant

www.kaggle.com

 

Credit Card customers

Predict Churning customers

www.kaggle.com

 

  • 첫번째 유방암 데이터는 세포의 다양한 데이터를 이용하여 해당 환자가 최종적으로 유방암(즉 암세포가 양성인지 음성인지)을 진단 받았는지를 통해 예측을 하고, 어떤 요소들이 가장 중요한지 알아볼 수 있어서 준비해봤다. 특히 의료쪽 데이터는 아직 한번도 해보질 않아서 꼭 해보고 싶었고, 머신러닝보다는 딥러닝이 더 좋겠지만 기초부터 하면 좋을 것 같다.
  • 두번째 카드사 데이터는 카드사의 고객들의 정보와 고객 이탈 여부를 예측할 수 있는 데이터셋이다. 고객 이탈율 측정이나 예측은 서비스 측면에서 매우 중요하다고 생각하여서 한번쯤은 해보아도 좋을 것 같아서 선택했다. 무엇보다 데이터량이 많아서 성능에 도움이 되지 않을까 생각한다. 다만 이탈한 사람과 아닌 사람의 차이가 크게 차이나는데, 이거는 오버샘플링을 통해서 해결할 수 있지 않을까 생각한다.

 


프로젝트 외

  • 오늘 주제 선정 회의가 저녁 늦은 시간에 잡혀있어서 프로젝트에 도움이 될만한 것 위주로 해보기로 했다
  • 여태 배운 머신러닝 개념을 사용해보고 싶어서 케글의 타이타닉 생존 예측을 해보기로 했다.
  • 먼저 수치형 / 범주형 데이터 EDA를 진행 :
import matplotlib.pyplot as plt
import seaborn as sns

# Numerical columns
columns = ['Survived', 'Pclass', 'Age', 'SibSp', 'Parch', 'Fare']
fig, axes = plt.subplots(nrows=3, ncols=2, figsize=(14, 12))

for i, column in enumerate(columns):
    sns.histplot(train_data[column], bins=20, kde=True, color='skyblue', edgecolor='black', ax=axes[i//2, i%2])
    axes[i//2, i%2].set_title(f'Distribution of {column}')
    axes[i//2, i%2].set_xlabel(column)
    axes[i//2, i%2].set_ylabel('Frequency')
    axes[i//2, i%2].grid(True)

plt.tight_layout()
plt.show()

수치형 데이터 시각화

# Categorical columns
sns.countplot(data=train_data, x=train_data['Sex'])
plt.title('Sex')
plt.xlabel('Sex')
plt.ylabel('Count')
plt.show()

sns.countplot(data=train_data, x=train_data['Embarked'])
plt.title('Embarked')
plt.xlabel('Embarked')
plt.ylabel('Count')
plt.show()

 

  • 결측치는 나이와 승선장소에 존재했는데(Cabin은 사용하지 않을 예정이니 전처리 하지 않음) 나이는 평균으로, 승선 장소는 가장 흔한 장소로 대체
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy='most_frequent')
train_data[['Embarked']] = imputer.fit_transform(train_data[['Embarked']])

imputer = SimpleImputer(strategy='mean')
train_data[['Age']] = imputer.fit_transform(train_data[['Age']])
  • 성별은 여자가 1, 남자는 0으로 대체하고 불필요한 다른 컬럼들 삭제
train_data['Gender'] = np.where(train_data['Sex'] == 'female', 1, 0)
train_data.drop(['Sex'], axis=1, inplace=True)
  • Embarked 컬럼은 문자열이기 때문에 인코딩 진행
from sklearn.preprocessing import OneHotEncoder

embarked_col = train_data[['Embarked']]
encoder = OneHotEncoder(sparse_output=False)
embarked_encoded = encoder.fit_transform(embarked_col)

embarked_df = pd.DataFrame(embarked_encoded)

train_encoded = pd.concat([train_data, embarked_df], axis=1)

train_encoded.rename(columns={0: 'C', 1: 'Q', 2: 'S'}, inplace=True)

최종적으로 사용할 데이터의 모습

  • 모델 학습을 위해 훈련 세트와 테스트 세트 분리
from sklearn.model_selection import train_test_split
X = train_data[['Pclass', 'Gender', 'Age', 'SibSp', 'Parch', 'Fare', 'C', 'Q', 'S']]
y = train_data['Survived']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
  • 스케일링은 MinMaxScaler를 사용
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaler.fit(X_train)
X_scaled = scaler.transform(X_train)

scaler.fit(X_test)
X_test_scaled = scaler.transform(X_test)
  • 알고리즘은 랜덤포레스트를 사용하기로 했다
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_estimators=200, random_state=42)
rf.fit(X_scaled, y_train)
  • 점수 확인
# Overfitting
print(rf.score(X_scaled, y_train))
print(rf.score(X_test_scaled, y_test))

훈련 세트와 테스트 세트의 점수 비교

  • classification report 확인
Y_pred = rf.predict(X_test_scaled)

from sklearn.metrics import classification_report
print(classification_report(y_test, Y_pred))

classification report

  • 최종적으로 정확도는 약 81%가 나왔는데 훈련 세트는 98%가 나왔다. 아주 과대적합한 모델이 나왔는데, 이건 아마 그리드 서치를 안해서 그런 것 같기도 하다.. 다음에는 그리드서치로 최적의 파라미터를 찾고 다시 시도해봐야겠다.

+ Recent posts