주제
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))

- 최종적으로 정확도는 약 81%가 나왔는데 훈련 세트는 98%가 나왔다. 아주 과대적합한 모델이 나왔는데, 이건 아마 그리드 서치를 안해서 그런 것 같기도 하다.. 다음에는 그리드서치로 최적의 파라미터를 찾고 다시 시도해봐야겠다.
'Data Science > TIL (Today I Learned)' 카테고리의 다른 글
| 프로그래머스 데이터분석 데브코스 1기 - 58일차 (1) | 2024.02.14 |
|---|---|
| 프로그래머스 데이터분석 데브코스 1기 - 57일차 (1) | 2024.02.13 |
| 프로그래머스 데이터분석 데브코스 1기 - 55일차 (0) | 2024.02.09 |
| 프로그래머스 데이터분석 데브코스 1기 - 54일차 (0) | 2024.02.08 |
| 프로그래머스 데이터분석 데브코스 1기 - 53일차 (0) | 2024.02.07 |