SVM Classifier - 하이퍼파라미터 튜닝
이전포스트에서는 일일주가데이터 자체를 SVC를 이용해 분석후 예측에 사용했다. 훈련세트에 과적합되어서 제대로된 예측을 하지못했다.
이번에는 교차검증과 그리드탐색을 이용해서 좀더 예측력이 강한 모델을 만들어보겠다.
Date | Open | High | Low | Close | Volume | Change | UD_Trend |
---|---|---|---|---|---|---|---|
2000-01-04 | 6000 | 6110 | 5660 | 6110 | 1483967 | 0.148496 | -1.0 |
2000-01-05 | 5800 | 6060 | 5520 | 5580 | 1493604 | -0.086743 | 1.0 |
2000-01-06 | 5750 | 5780 | 5580 | 5620 | 1087810 | 0.007168 | -1.0 |
2000-01-07 | 5560 | 5670 | 5360 | 5540 | 806195 | -0.014235 | 1.0 |
2000-01-11 | 5820 | 6100 | 5770 | 5770 | 1194974 | 0.000000 | -1.0 |
… | … | … | … | … | … | … | … |
2021-12-03 | 75600 | 76000 | 74100 | 75600 | 18330240 | -0.002639 | 1.0 |
2021-12-06 | 75100 | 76700 | 74900 | 76300 | 16391250 | 0.009259 | 1.0 |
2021-12-08 | 78300 | 78600 | 77100 | 77400 | 21558340 | 0.000000 | 1.0 |
2021-12-09 | 77400 | 78200 | 77000 | 78200 | 21604528 | 0.010336 | -1.0 |
2021-12-10 | 77400 | 77600 | 76800 | 76900 | 9155219 | -0.016624 | -1.0 |
이전 포스팅과 마찬가지로 일일 주가 변동 Column을 labeling 한다.
my_cv = TimeSeriesSplit(n_splits=5).split(X_train) # 교차검증 세트 생성
TimeSeriesSplit을 통해 시계열 교차검증 세트를 만들어준다. TimeSeriesSplit은 다른 교차검증 세트 생성기와 다르게 시계열이라는 특징을 반영하여 사전관찰편향(look ahrad bias)가 일어나지 않도록 투자자가 특정 일자에 접할 수 없는 데이터를 사용하는 교차검증세트를 생성하지 않는다.
params = {
'svc__C' : [0.01, 0.1, 1.0],
'svc__gamma' : [1, 10, 100],
}
현재 사용하는 CPU 성능을 고려하여 SVC의 규제에 영향을 많이주는 C와 gamma 파라미터를 조정한다. 파이프라인을 이용해 StandSclaer를 적용시키위해 딕셔너리 키를 svc__(파라미터이름)으로 만들어준다.
svm_cla = Pipeline([
("scaler", StandardScaler()),
("svc", SVC()),
])
GridSearchCV에 각 객체를 파라미터로 넘겨주어서 객체를 생성한다.
clf = GridSearchCV(svm_cla, param_grid=params, cv=my_cv, n_jobs=-1)
훈련을 진행하고 최적의 파라미터와 예측 최고점수를 출력한다.
clf.fit(X_train, y_train)
print('best parameter:\n', clf.best_params_)
print('best prediction:{0:.4f}'.format(clf.best_score_))
best parameter:
{'svc__C': 1.0, 'svc__gamma': 10}
best prediction:0.5039
C는 1, gamma는 10을 얻어냈다. 이제 이 파라미터들을 가진 모델을 처음 훈련세트로 훈련시키고 검증 세트로 검증을 실시해보자
svm_cla2 = Pipeline([
("scaler", StandardScaler()),
("svc", SVC(C=1, gamma=10)),
])
svm_cla2.fit(X_train, y_train) # 훈련 세트로 훈련진행
print("train_set score: ", svm_cla2.score(X_train, y_train)) # 훈련세트 점수
print("test_set score : ", svm_cla2.score(X_test, y_test)) # 검증세트 점수
결과는 다음과 같이 나왔다.
train_set score: 0.73
test_set score : 0.49806576402321084
훈련세트에서의 정확도는 상당이 높게 나왔지만 검증세트에서는 50퍼센트 이하가 나왔다. 이는 역시 이전 포스팅때와 마찬가지로 훈련세트에 과적합되어있다는 사실을 알 수 있었다.
unique, counts = np.unique(svm_cla2.predict(X_all), return_counts=True)
print(unique)
print(counts)
예측결과를 보면
[-1. 1.]
[3166 1868]
{-1.0: 3166, 1.0: 1868}
역시 -1 로 편향된 결과가 나온것을 볼 수 있다. 여전히 훈련세트에 과적합되어있다.