원자력 발전소 상태 판단 알고리즘 공모전 도전 1, 2일차!

솜씨좋은장씨

·

2020. 1. 26. 06:34

 

[산업] 원자력발전소 상태 판단 대회

출처 : DACON - Data Science Competition

dacon.io

다음의 과정은 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)

제출 결과

 

 

 

앞으로 아래의 링크들을 통해 공부를 하고 더 이해를 한 후에 도전을 하면 좋을 것 같습니다.

 

5. Decision Tree(의사결정나무)

1. 배경​다음 데이터를 보자​우리는 Outlook, Temperature, Humidity, Wind를 통하여 종속변수 Play...

blog.naver.com

 

 

[ML with Python] 2장. 지도 학습 - 분류 예측의 불확실성 추정

2.4 분류 예측의 불확실성 추정

subinium.github.io

 

 

[핸즈온 머신러닝] 7강 앙상블 학습과 랜덤 포레스트(ensemble, RandomForest)

앙상블 학습과 랜덤 포레스트 앙상블 학습이란 하나로 이어진 여러개의 (SVM, 결정트리, 로지스틱 회귀, 경사하강법)예측기를 사용하여 분류, 회귀등을 하는 것을 앙상블학습이라고 부릅니다. 예를 들어 각기 다른..

hoony-gunputer.tistory.com

 

오늘은 여기까지!

 

대회는 계속 연습해볼 수 있도록 오픈되어있습니다. 관심있는 분들은 도전해보시면 좋을 것 같습니다.

 

나도 한번 도전해보기

 

[산업] 원자력발전소 상태 판단 대회

출처 : DACON - Data Science Competition

dacon.io