원자력발전소 상태 판단 경진대회

원자력 발전소 상태 판단 대회 도전 1, 2일차! by 솜장

2020.03.03 23:14 4,560 Views

다음의 과정은 Google Drive에 데이터를 저장하고 Colab - TPU 환경에서 진행하였습니다.

 

이 공모전은 원자력 발전소의 5,121개의 변수를 가지고

 

각각의 label (상태 0~197)에 해당하는 예측확률을 0~1사이의 값으로 제출하는 공모전입니다.

 

 

첫번째 시도는 대회를 이해해보기 위해서 DACON에서 제공하는 baseline 코드를 실행해보았습니다.

 

앞서 데이터 불러오기에서 볼 수 있었던 코드에서 ver2 코드를 활용하여

 

다운 받은 csv 데이터를 코드에서 load하고

 

학습데이터 라벨링과 테스트 데이터를 만들어 활용하였습니다.

import os
import pandas as pd 
import numpy as np
import multiprocessing # 여러 개의 일꾼 (cpu)들에게 작업을 분산시키는 역할
from multiprocessing import Pool 
from functools import partial # 함수가 받는 인자들 중 몇개를 고정 시켜서 새롭게 파생된 함수를 형성하는 역할
from data_loader_v2 import data_loader_v2 # 자체적으로 만든 data loader version 2.0 ([데이콘 15회 대회] 데이터 설명 및 데이터 불러오기 영상 참조)

from sklearn.ensemble import RandomForestClassifier
import joblib # 모델을 저장하고 불러오는 역할

train_folder = 'data/train/'
test_folder = 'data/test/'
train_label_path = 'data/train_label.csv'

train_list = os.listdir(train_folder)
test_list = os.listdir(test_folder)
train_label = pd.read_csv(train_label_path, index_col=0)

def data_loader_all_v2(func, files, folder='', train_label=None, event_time=10, nrows=60):   
    func_fixed = partial(func, folder=folder, train_label=train_label, event_time=event_time, nrows=nrows)     
    if __name__ == '__main__':
        pool = Pool(processes=multiprocessing.cpu_count()) 
        df_list = list(pool.imap(func_fixed, files)) 
        pool.close()
        pool.join()        
    combined_df = pd.concat(df_list)    
    return combined_df
    
#     event_time: [int] 상태_B 발생 시간 
#    nrows: [int] csv 파일에서 불러올 상위 n개의 row 
train = data_loader_all_v2(data_loader_v2, train_list, folder=train_folder, train_label=train_label, event_time=10, nrows=60)

 

여기서 data_loader_all 메소드에 들어가는 변수 중에서 event_time을 10으로 설정한 이유는

데이터를 설명해주는 부분에서

실제의 원전의 상태는 10초를 기점으로 상태 A에서 상태 B로 변한다고 하였기 때문에 10으로 설정하였습니다.

 

또한 학습데이터로 0초 ~ 59초 사이의 데이터만 사용하기위하여 nrows를 60으로 설정하여줍니다.

 

 

X_train = train.drop(['label'], axis=1)
y_train = train['label']
model = RandomForestClassifier(random_state=0, verbose=1, n_jobs=-1)
model.fit(X_train, y_train)
# joblib.dump(model, 'model.pkl')

X_train으로는 라벨을 제외한 V000 ~ V5120 (5,121개) 를 추출해내고

y_train으로는 라벨값을 추출해줍니다.

 

그 다음에 RandomForestClassifier를 활용하여 학습 시킵니다.

 

여기서 n_jobs=-1 이라고 설정한 부분은 시스템에 있는 CPU 코어수를 모두 사용하여 학습을 하게 됩니다.

 

실행 결과

 

 

학습이 완료되었다면

test = data_loader_all_v2(data_loader_v2, test_list, folder=test_folder, train_label=None, event_time=10, nrows=60)

test 데이터를 load 하여 줍니다.

 

predict_proba 메소드를 활용하여 각각의 라벨의 확률을 예측합니다.

pred = model.predict_proba(test)
submission = pd.DataFrame(data=pred)
submission.index = test.index
submission.index.name = 'id'
submission = submission.sort_index()
submission = submission.groupby('id').mean()
submission.to_csv('submission_baseline_test.csv', index=True) #제출 파일 만들기

위의 코드를 활용하여 제출할 파일을 csv로 만들어 제출합니다.

 

제출결과

 

 

다음으로는 데이터 load 방식은 그대로 활용하고

 

학습에는 핸즈온 머신러닝 책 247쪽에 나오는 BaggingClassifier 코드를 활용하여 제출해 보았습니다.

from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier

bag_clf = BaggingClassifier(
    DecisionTreeClassifier(), n_estimators=500,
    max_samples = 100, bootstrap=True)
bag_clf.fit(X_train, y_train)

여기서 n_estimators = 500 은 결정트리 분류기 500개의 앙상블을 훈련시키는 것을 뜻하고

 

max_samples = 100 은 훈련세트에서 중복을 허용하여 무작위로 선택된 100개의 샘플로 훈련을 뜻합니다.

 

배깅을 사용하기 위해서 bootstrap은 True로 설정하였습니다.

 

제출 결과

다음으로는 baseline 코드에서 n_jobs = -1 에서 1로 바꾸고 학습을 시킨 뒤에 제출해보았습니다.

model3 = RandomForestClassifier(random_state=0, verbose=1, n_jobs=1)

제출결과

슬프게도 해당 하이퍼파라미터는 결과에 영향을 미치지 않는 변수였습니다.

 

 

다음으로는 첫번째 시도했던 모델에서 n_estimators = 200 / warm_start = True 로 설정해주고 학습해보았습니다.

model4 = RandomForestClassifier(random_state=0, verbose=1, n_jobs=-1, n_estimators=200, warm_start=True)
model4.fit(X_train, y_train)

warm_start을 True로 설정해주면 sklearn fit() 메서드가 호출될 때 기존 트리를 유지하고 훈련을 추가할 수 있게 해준다고 합니다.

 

제출결과

그동안 중에 가장 좋은 결과가 나왔습니다.

 

 

다음으로는 방금 전에 해봤던 모델에서 max_leaf_nodes를 16으로 설정해주고 학습해보았습니다.

model5 = RandomForestClassifier(random_state=0, verbose=1, n_jobs=-1, n_estimators=200, warm_start=True, max_leaf_nodes=16)
model5.fit(X_train, y_train)

max_leaf_nodes를 16으로 설정해주면 이 분류기는 최대 16개의 리프 노드를 갖게 된다고 합니다.

 

제출 결과

 

다음으로는 핸즈온 머신러닝 257쪽에 있는

 

AdaBoostClassifier 코드를 활용하여 학습해보았습니다.

from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier

ada_clf = AdaBoostClassifier(
    DecisionTreeClassifier(max_depth=1), n_estimators=200,
    algorithm="SAMME.R", learning_rate=0.5)

ada_clf.fit(X_train, y_train)

제출 결과


출처 - 솜장 https://ideans.tistory.com/34


로그인이 필요합니다
0 / 1000
당쇠
2020.03.03 23:19

공유해주신 솜장님께 감사드립니다.