SW/주가 예측

주가, 비트코인 예측 : 하이퍼파라미터 최적화 : 개념, 특징, 방법

얇은생각 2019. 7. 8. 07:30
반응형

주가, 비트코인 예측 : 하이퍼파라미터 최적화 : 개념, 특징, 방법



하이퍼파라미터 최적화


머신러닝 모델 파라미터의 최적화를 보통 하이퍼 파라미터 최적화라고 합니다. 


모델 파라미터 최적화와 하이퍼 파라미터 최적화로 크게 2가지 종류가 있습니다.


하이퍼 파라미터에서 설정한 값에 따라 모델 파라미터를 최적화합니다. 따라서 하이퍼파라미터 최적화는 머신러닝 모델의 성능에 큰 영향을 미치게 됩니다. 


모델 파라미터 최적화는 하이퍼 파라미터로 설정된 범위 내에서만 최적화를 시도하기 때문에 올바르게 설정되지 않은 하이퍼 파라미터에서는 좋은 성능을 보여주기 힘듭니다. 


따라서, 모델 파라미터 최적화보다 중요한 것은 하이퍼파라미터 최적화라고 할 수 있습니다.


하이퍼 파라미터 최적화에는 크게 2가지 종류가 있습니다. 바로 격자 탐색과 랜덤 탐색의 개념입니다.




격자 탐색

주어진 범위 내의 모든 값을 입력해 하이퍼 파라미터를 최적화하는 방법입니다. 모든 경우의 수를 따지면서 최적의 방법이 무엇인지 찾는 방법입니다. 


아래 예제 코드를 참조해보겠습니다. 최적의 하이퍼 파라미터 값을 찾기 위해 격자 탐색을 시행합니다. sklearn에서 grid_search.fit이라는 단순 함수를 활용해서 격자 탐색을 할 수 있습니다.



    def optimizeHyperparameter(self,name, code, start_date,end_date,lags_count=5):
        a_predictor = self.predictor.get(code,name)

        df_dataset = self.predictor.makeLaggedDataset(code,
            start_date,
            end_date,
            self.config.get('input_column'),
            self.config.get('output_column'),
            lags_count )

        X_train,X_test,Y_train,Y_test = self.predictor.splitDataset(
            df_dataset,'price_date',
            [self.config.get('input_column')],
            self.config.get('output_column'),
            split_ratio=0.8)

        param_grid = {"max_depth": [3, None],
                    "min_samples_split": [1, 3, 10],
                    "min_samples_leaf": [1, 3, 10],
                    "bootstrap": [True, False],
                    "criterion": ["gini", "entropy"]}

        a_predictor.doGridSearch(X_train.values,Y_train.values,param_grid)

def doGridSearch(self,x_train,y_train,param_grid):
grid_search = GridSearchCV(self.classifier, param_grid=param_grid)
grid_search.fit(x_train,y_train)

for params, mean_score, scores in grid_search.grid_scores_:
print("%0.3f (+/-%0.03f) for %r" % (mean_score, scores.std() * 2, params))




랜덤 탐색

주어진 값에서 표본을 추출하고 이들 값에 대해서만 하이퍼파라미터를 찾는 방법입니다. 랜덤 탐색은 가능한 모든 조합의 하이퍼 파라미터를 계산하지 않고 표본으로 추출된 일부 값을 가지고 하이퍼 파라미터를 계산합니다. 그러므로 격자 탐색보다 훨씬 적은 계산과 짧은 시간에 최선의 하이퍼파라미터를 찾을 수 있는 장점이 있습니다.


랜덤 탐색은 전체 집합인 모든 경우의 수에서 일부만을 표본으로 추출해 하이퍼 파라미터 값을 찾습니다. 따라서 반드시 최적의 하이퍼 파라미터 값을 찾는다고 장담할 수 없습니다. 


즉, 하이퍼 파라미터를 찾기 위해 추출된 표본에 최적의 하이퍼 파라미터를 찾을 수 있는 값이 포함되어 있다면, 최적의 하이퍼 파라미터를 찾을 수 있습니다. 그렇지 않다면 최적의 하이퍼 파라미터를 찾을 수는 없습니다. 


해당 예제 코드를 참조해 보겠습니다. 위 격자 탐색 코드와 거의 유사합니다. 



    def optimizeHyperparameter(self,name, code, start_date,end_date,lags_count=5):
        a_predictor = self.predictor.get(code,name)

        df_dataset = self.predictor.makeLaggedDataset(code,
            start_date,
            end_date,
            self.config.get('input_column'),
            self.config.get('output_column'),
            lags_count )

        X_train,X_test,Y_train,Y_test = self.predictor.splitDataset(
            df_dataset,'price_date',
            [self.config.get('input_column')],
            self.config.get('output_column'),
            split_ratio=0.8)

        param_grid = {"max_depth": [3, None],
                    "min_samples_split": [1, 3, 10],
                    "min_samples_leaf": [1, 3, 10],
                    "bootstrap": [True, False],
                    "criterion": ["gini", "entropy"]}

        a_predictor.doGridSearch(X_train.values,Y_train.values,param_grid)


def doRandomSearch(self,x_train,y_train,param_dist,iter_count):
random_search = RandomizedSearchCV(self.classifier, param_distributions=param_dist, n_iter=iter_count)
random_search.fit(x_train,y_train)

for params, mean_score, scores in random_search.grid_scores_:
print("%0.3f (+/-%0.03f) for %r" % (mean_score, scores.std() * 2, params))



반응형