본문 바로가기
AI/AI 부트캠프

[AI 부트캠프] DAY 61 - 머신러닝 프로젝트 5

by HOHHOH 2023. 10. 18.

[오늘의 일지]

머신러닝 프로젝트 - 딥러닝, Stacking과 Voting, 대회 초기화

[상세 내용]

머신러닝 프로젝트

- 아래의 주제들을 설명하기에 앞서서 저희 조는 더 이상 발전이 없었던 평가지표 때문에 강사님께 조언을 구했습니다. 강사님도 이 정도 해서 진전이 없는 상태라면 완전히 다른 알고리즘 모델로 방향을 틀어봐야 한다고 말해주셨습니다. 그중 하나의 예시가 딥러닝이었는데 아직 딥러닝을 배우지 않은 상태여서 강사님은 머신러닝 알고리즘 모델 3가지를 앙상블을 하는 방법인 stacking이나 voting을 대회 같은 특수한 상황에서는 자주 사용한다고 말씀하셨습니다. 그래서 간단하게 알아보도록 하겠습니다.

 

딥러닝

- 딥러닝은 아직 배우지 않았기 때문에 간단하게 있는 코드만 가져와서 실행을 해보았습니다. 모델은 tensorflow이고 데이터에 맞게 다중 선형 회귀 모델을 사용해 보았습니다. 그리고 optimizers는 Adam을 사용했는데 이 것은 경사하강법을 사용하여 학습하면서 적절한 모델을 찾는 것이었습니다. 경사하강법이므로 당연히 모멘텀 기능도 내재되어 있었습니다. 그런데 간단한 모델이다 보니 학습률은 그리 좋지 못했습니다. 한번 사용해 보면서 미리 예습했다고 생각하고 넘어갔습니다.

# 데이터 분할: 학습 데이터와 테스트 데이터
train_X, test_X, train_y, test_y = train_test_split(X_train_reduced, y_train, test_size=0.2, random_state=42)

# 다중 선형 회귀 모델 생성
model = tf.keras.Sequential([
    tf.keras.layers.Input(shape=(14,)),  # 입력 특성의 개수는 17
    tf.keras.layers.Dense(units=800, activation='relu'),
    tf.keras.layers.Dense(units=800, activation='relu'),
    tf.keras.layers.Dense(1, activation='linear')  # 선형 회귀 모델
])

# 학습률 조정
learning_rate = 0.001  # 원하는 학습률 값으로 조정
optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)

# 모델 컴파일
model.compile(optimizer=optimizer, loss='mean_absolute_error', metrics=['mae'])

# 모델 훈련
early_stopping = EarlyStopping(monitor='val_loss', patience=6)

batch_size = 6000
epochs = 100

# 모델 학습
model.fit(train_X, train_y, batch_size=batch_size, epochs=epochs,
          validation_data=(test_X, test_y), callbacks=[early_stopping])


# 모델 평가
loss, mae = model.evaluate(test_X, test_y)
mae_result = model.evaluate(test_X, test_y, verbose=0)[1]
print(f"평가 MAE (Mean Absolute Error) on Test Data: {mae_result}")

 

Stacking과 Voting

- 이전 일지에서 소개한 적이 있는 스태킹과 보팅입니다. 이 둘은 앙상블 모델들 중 하나로서 간단하게 설명하자면 스태킹은 데이터를 분리해서 여러 가지 알고리즘 모델들을 사용해서 각자 모델을 돌려서 다시 결합하여 예측 성능을 올리는 기능을 가지고 있습니다. 보팅도 기능은 유사한데 여러 가지 알고리즘 모델을 결합하거나 선택한다는 점에서 차이점이 있다고 할 수 있습니다. 둘 다 여러 가지 알고리즘 모델들을 사용해서 예측성능을 향상시킨 다는 목적은 같습니다. 실제로 저희 조는 보팅을 사용해서 3가지 모델을 통해 성능지표를 향상시키는 것을 성공했습니다. (하지만 결과를 제출한 뒤에 갑자기 대회 규정이 다시 생겨서 모두 초기화되었습니다...)

 

- Stacking 예시

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.svm import SVC
from sklearn.neural_network import MLPClassifier
from sklearn.ensemble import StackingClassifier
from sklearn.metrics import accuracy_score

# 데이터 로드 및 분할
X, y = load_data()  # 데이터 로드
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 1단계 모델 정의
estimators = [
    ('rf', RandomForestClassifier(n_estimators=100, random_state=42)),
    ('gb', GradientBoostingClassifier(n_estimators=100, random_state=42)),
    ('svm', SVC(probability=True, random_state=42)),
    ('mlp', MLPClassifier(hidden_layer_sizes=(100, 50), max_iter=500, random_state=42))
]

# 2단계 스태킹 모델 정의
stacking_model = StackingClassifier(estimators=estimators, final_estimator=LogisticRegression())

# 1단계 모델 학습
for name, estimator in estimators:
    estimator.fit(X_train, y_train)

# 2단계 스태킹 모델 학습
stacking_model.fit(X_train, y_train)

# 1단계 모델의 예측
predictions = [estimator.predict(X_test) for _, estimator in estimators]

# 2단계 모델 예측
stacking_predictions = stacking_model.predict(X_test)

# 1단계 모델들의 정확도 출력
for name, prediction in zip([name for name, _ in estimators], predictions):
    acc = accuracy_score(y_test, prediction)
    print(f'{name} Accuracy: {acc}')

# 2단계 모델의 정확도 출력
stacking_acc = accuracy_score(y_test, stacking_predictions)
print(f'Stacking Model Accuracy: {stacking_acc}')

 - Voting 예시

from sklearn.ensemble import VotingClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC

# 데이터 로드 및 분할
X, y = load_data()  # 데이터 로드
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 분류기 정의
clf1 = DecisionTreeClassifier(random_state=42)
clf2 = LogisticRegression(max_iter=1000, random_state=42)
clf3 = SVC(probability=True, random_state=42)

# 하드 보팅
voting_hard = VotingClassifier(estimators=[('dt', clf1), ('lr', clf2), ('svm', clf3], voting='hard')
voting_hard.fit(X_train, y_train)
y_pred_hard = voting_hard.predict(X_test)
accuracy_hard = accuracy_score(y_test, y_pred_hard)
print(f'Hard Voting Accuracy: {accuracy_hard}')

# 소프트 보팅
voting_soft = VotingClassifier(estimators=[('dt', clf1), ('lr', clf2), ('svm', clf3], voting='soft')
voting_soft.fit(X_train, y_train)
y_pred_soft = voting_soft.predict(X_test)
accuracy_soft = accuracy_score(y_test, y_pred_soft)
print(f'Soft Voting Accuracy: {accuracy_soft}')

 

대회 초기화

- 갑자기 대회가 초기화되었습니다. 그 이유는 특정 피처가 타깃피처와 거의 똑같은 유사도를 가지고 있어서 그 피처만 사용해서 학습시키면 결과가 비현실적으로 좋게 나오는 상황이었습니다. 결국 다시 처음부터 시작하게 되었습니다. 프로젝트 기간이 이제 얼마 남지 않았기 때문에 기존에 하던 작업들을 위주로 다시 하면서 마무리해야 할 거 같습니다.

 

[마무리]

 오늘은 마지막으로 새로운 방법들을 찾아가면서 좋은 알고리즘 모델을 찾으려고 했는데 결과적으로는 약간의 도약이 있었지만 대회가 초기화되면서 다시 시작하게 되었습니다. 애초에 대회 자체를 프로젝트를 위해서 시작했고 프로젝트도 지금까지 배운 내용을 잘 복습하면서 활용해 보기 위해서 하는 과정이기 때문에 대회가 초기화된 것에 대해서는 크게 여의치 않고 이번주까지 프로젝트를 잘 마무리할 수 있도록 지금까지의 과정을 잘 정리해 보도록 해야겠습니다.

반응형

댓글