학교에서 수업 시간에 공모전에 참여하여 개개인마다의 인사이트를 얻고 발표를 하라는 교수님의 지시에 공모전을 찾아보다가 한 팀원이 '여기에 참여해보자!' 하여 24년 홍천군 공모전에 참여하게 되었습니다.
참가하게 된 계기나 목표가 있었나요?
기왕 참가하게 된 거 상은 무조건 타고 간다는 마인드였습니다. '세상은 2등은 기억해주지 않기 때문에 1등 해보자라는 마음가짐'이였습니다.
2. 준비 과정
어떤 방식으로 준비했나요? (팀원 구성, 역할 분배, 공부 방법 등)
팀원들 중 2명은 서류 작성에 많은 도움을 주셨고, 저랑 다른 팀원 한 명은 전반적인 데이터를 분석하는 역할을 맡았습니다. 여타 다른 공모전들도 마찬가지로 공모전은 얼마나 진심으로 문제에 대해 고민했고 그것의 해결방안을 어떻게 잘 ppt에 녹여내는지가 관건이기에 문제를 잘 설정하는 것에 진심이였던 것 같습니다.
어려웠던 점과 이를 어떻게 해결했나요?
저희는 최적의 위치 선정과 관련된 프로젝트를 진행했는데 여기서 유클리디안 거리를 사용했을 때는 지형물, 건물과 같은 장애물을 제외하고 오로지 직선 거리만을 계산하기에 최적의 위치를 적절하게 선정하는데에 있어서 어려움이 있었습니다. 고민을 하던 와중 같이 데이터 분석 역할을 맡은 팀원 한 명이 '네이버 길찾기의 최소 경로를 사용하면 어떨까'라는 말을 해줬고, 이것이 저희가 가지고 있는 한계를 돌파해 줄 수 있는 key라는 느낌이 와 바로 진행하니 좋은 결과를 얻을 수 있었습니다.
3. 공모전 진행 중 경험
공모전에서 겪은 인상 깊은 경험이 있나요?
사실 팀원들과 이렇게 호흡이 잘 맞고 좋은 사람들이랑 했던 기억이 많이 없어서.. 좋은 사람들과 힘든 시간을 극복해가면서 같이 성장하는 느낌을 받았던 게 참 좋았던 것 같습니다.
예상과 달랐던 점이 있었나요?
23년도에 했던 데이터 분석은 팀원들이 데이터 분석에 대해 관심없기도 했고 잘 몰라서 대충해서 그냥 혼자 다 했었는데 이번에도 그런 팀원이 있었기는 했지만 자신의 힘이 되는 한에서 끝까지 도와줄려고 하는 모습에서 감동?을 받았었고, 같이 데이터 분석을 하는 친구는 밤을 새가며 자신의 책임을 다 하는거에서 이 친구들이랑 더 많은 공모전이나 프로젝트 할 수 있었으면 좋겠다라고 생각했습니다.
4. 결과 및 배운 점
공모전 결과(수상 여부와 관계없이) 어떤 점에서 성장했나요?
음... 일단 최우수상! 1등했고, 힘든 시간 동안 같이 버텨준 팀원들이 가장 자랑스럽고, 팀장인 제가 역량이 부족했다고 생각했는데, 잘 따라주기도 했고 많은 도움을 받았습니다. 지금 팀장으로서 어떤 부분이 제가 부족한 지를 알게 된 거 같아 좋았습니다.
어떤 기술이나 역량이 향상되었나요?
공부의 본질을 알게 되었다고 해야하나..ㅋㅋㅋ 모르는게 있으면 가만히 있는게 아니라 고민하고 찾고 또 찾으면 결국 자신만의 답이 나온다? 그게 정답은 아니더라도 자신만의 답을 그렇게 많이 도출하다 보면 결국에는 근접할 수 있습니다. 결론은 탐구하고 인내하는 능력이 늘어난 것 같습니다.
5. 소감 및 앞으로의 계획
이번 경험이 앞으로 어떤 영향을 줄 것 같나요?
도전 = 두려움이 아니라 도전 = 성장 이라고 생각을 하면서 앞으로 살아가도록 도움을 준 것 같네요
다음에는 어떤 공모전에 도전하고 싶은가요?
공모전보다 학회나 학술대회를 많이 참여하려고요. 이번 공모전하면서 제 수학적 식견이 낮아 논문의 수식을 이해못했던 적이 있어서 부끄럽더라고요. 네. 그래서 학회나 학술대회에 많이 참여할 것 같습니다.
seed 값에 의해 동일한 코드를 사용해도 결과가 다를 수 있기에, 동일한 결과를 위해 seed값을 고정시킵니다.
import numpy as np
import random
import os
defseed_everything(seed):
random.seed(seed)
os.environ['PYTHONHASHSEED'] = str(seed)
np.random.seed(seed)
seed_everything(42) # Seed 고정
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)
데이터 전처리 2: 범주형 변수 수치화
LabelEncoder를 통해 범주형 변수 수치화를 진행합니다.
from sklearn.preprocessing import LabelEncoder
categorical_features = ['대출기간', '주택소유상태', '대출목적']
for i in categorical_features:
le = LabelEncoder()
le=le.fit(train_x[i])
le=le.fit(X[i])
train_x[i]=le.transform(train_x[i])
X[i]=le.transform(X[i])
for case in np.unique(test_x[i]):
if case notin le.classes_:
le.classes_ = np.append(le.classes_, case)
test_x[i]=le.transform(test_x[i])
display(train_x.head(3))
display(test_x.head(3))
모델 선정 및 학습
RandomForestClassifier
from sklearn.ensemble import RandomForestClassifier
RFC = RandomForestClassifier()
RFC.fit(X_train, y_train)
max_depth_list = range(20,25)
accuracy = []
for m in max_depth_list:
RFC = RandomForestClassifier(random_state = 42, max_depth = m)
RFC.fit(X_train, y_train)
pred = RFC.predict(X_test)
score = accuracy_score(pred, y_test)
accuracy.append(score)
plt.plot(max_depth_list, accuracy)
plt.xlabel('max_depth')
plt.ylabel('accuracy')
plt.show()
최적의 깊이를 찾기위한 코드
from sklearn.metrics import accuracy_score
pred = RFC.predict(X_test)
score = accuracy_score(pred, y_test)
print(f"정확도: {score}")
가장 잘 나온 max_depth의 값을 선택하여 예측한 결과 정확도는 0.8231이 나왔습니다.
IBM에서 제공했으며 고객 데이터를 분석하여 고객 유지 프로그램을 개발하는 데 도움이 됨.
고객 인구 통계 정보(Demographic info): 고객의 성별, 연령대, 배우자 및 부양 가족의 유무(Gender, SeniorCitizen, Partner, Dependents)
고객 이탈(Churn) 정보: 서비스를 중단 여부에 대한 정보
서비스 가입 정보(Services subscribed): 고객들이 가입한 서비스들, 예를 들어 전화, 다중 라인, 인터넷, 온라인 보안, 온라인 백업, 장치 보호, 기술 지원, 스트리밍 TV 및 영화( honeService, MultipleLine, InternetService, OnlineSecurity, OnlineBackup, DeviceProtection, TechSupport, StreamingTV, StreamingMovies) 등에 대한 정보
고객 계정 정보(Customer account info): 고객이 얼마나 오래 서비스를 이용했는지, 계약 유형, 결제 방법, 무페이퍼 청구 여부, 월별 요금, 총 요금 (CustomerID, Contract, PaperlessBilling, PaymentMethod, MonthlyCharges, TotalCharges, Tenure)등의 정보
2. 필요한 라이브러리로드
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
# 학습, 예측에 사용할 컬럼에 이름을 지정# 범주형 데이터 (object, category)는 전처리가 따로 필요# 따라서 수치데이터만을 사용
feature_names = df.select_dtypes(include = "number").columns
feature_names
# train 과 test 로 나누기 위해 데이터를 기준을 정함.
split_count = int(df.shape[0] * 0.8)
split_count
6. 정답값이자 예측해야할 값
label_name = "Churn"
label_name #정답값
7. 학습, 예측 데이터셋 만들기
# 데이터의 80%을 나눌 기준 인덱스(split_count)로 문제 데이터(X)를 train, test로 나눔.# 데이터의 80%을 나눌 기준 인덱스(split_count)로 정답 데이터(y)를 train, test로 나눔.
train = df[:split_count].copy()
test = df[split_count:].copy()
X_train = train[feature_names]
y_train = train[label_name]
X_test = test[feature_names]
y_test = test[label_name]
X_train.shape, X_test.shape, y_train.shape, y_test.shape
8. 머신러닝 알고리즘 가져오기
DecisionTreeClassifier(
*,
criterion='gini', # 분할방법 {"gini", "entropy"}, default="gini"
splitter='best',
max_depth=None, # The maximum depth of the tree
min_samples_split=2, # The minimum number of samples required to split an internal node
min_samples_leaf=1, # The minimum number of samples required to be at a leaf node.
min_weight_fraction_leaf=0.0, # The minimum weighted fraction of the sum total of weights
max_features=None, # The number of features to consider when looking for the best split
random_state=None,
max_leaf_nodes=None,
min_impurity_decrease=0.0,
class_weight=None,
ccp_alpha=0.0,
)
주요 파라미터
criterion: 가지의 분할의 품질을 측정하는 기능
max_depth: 트리의 최대 깊이
min_samples_split:내부 노드를 분할하는 데 필요한 최소 샘플 수
min_samples_leaf: 리프 노드에 있어야 하는 최소 샘플 수
max_leaf_nodes: 리프 노드 숫자의 제한치
random_state: 추정기의 무작위성을 제어. 실행했을 때 같은 결과가 나오도록 함.
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier()
9. 학습(훈련)
model.fit(X_train, y_train)
10. 예측
# 데이터를 머신러닝 모델로 예측(predict)
y_predict = model.predict(X_test)
y_predict[:5]