自動化機械学習(AutoML)を利用して中国株の騰落予想を行う

前回までの記事で、世界中のデータサイエンティストが集う「kaggle」のコンペをベースに機械学習について学んできました。

▼翌月の商品売上予測「Predict Future Sales」過去記事

ai-china.hatenablog.com

評価が高い投稿者のプログラムを理解することはまだ可能ですが、自分でゼロから機械学習のモデル選びやハイパーパラメータのチューニング、特徴量エンジニアリングをするのは難易度が高いです。そこで今回はこれらを自動的に行う「AutoML」を使ってみました。AutoMLで中国株の騰落予想を行います。

AutoMLとは

AutoML(Automated Machine Learning)とは機械学習モデルの設計や構築を自動化する事です。

一般的に機械学習を行う場合は下記の工程があります

  • データ収集
  • データ加工
  • 特徴量エンジニアリング
  • 機械学習モデル構築
  • ハイパーパラメータチューニング

AutoMLでは収集したデータを渡すと自動でモデル構築やパラメータ最適化を行いデータ分析できます。

中国株情報取得

今回はAutoMLを利用して中国株の騰落予想を行います。

データ取得はTushare Proを使いました。

waditu.com

ユーザ登録して、接続用TOKENキーを取得します。ユーザ登録には中国の携帯番号が必要でした。(メールアドレスでの登録はNG)

無料で使えるAPIの種類や、接続回数、取得件数には制限があります。詳しくは公式サイトに記載されています。

AutoML(auto-sklearn)のインストール

AutoMLはGoogleやMicrosoft等様々な企業・団体がツールを出しています。今回利用したのは「auto-sklearn」です。

まず、Dockerで構築したWindows10のローカル環境にインストールします。

pip install auto-sklearn

▼環境構築の過去記事

ai-china.hatenablog.com

AutoMLを使った中国株の騰落予想

今回予想するのは、私が保有している銘柄「600031三一重工」の翌日の株価が上がるか(「終値-始値」がプラスか)どうか。

以前も同じような予測を行いました。その際には機械学習モデル7種類に対してGridSearchCVでパイパーパラメータ最適化を行っています。

ai-china.hatenablog.com

今回はAutoMLを使うのでこれらは全て自動化されます。

プログラム

from autosklearn.classification import AutoSklearnClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score
import tushare as ts

#Tushareユーザ登録時に取得したTOKEN
ts.set_token('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')

pro = ts.pro_api()

#三一重工の2010/01/01から2021/09/01までの株価情報(始値、終値、高値、安値、出来高)を取得
df = pro.daily(ts_code='600031.SH', start_date='20100101', end_date='20210901')

#ラベル(翌日の株価が上ったか)を設定
df["Diff"] = df["close"]-df["open"]
df = df.sort_values('trade_date')
df["y"] = df["Diff"].apply(lambda x: 1 if x > 0 else 0).shift(-1)

df = df.drop(
 ["ts_code", "trade_date"],
 axis=1,
).dropna()

X = StandardScaler().fit_transform(df.drop(["y"], axis=1))
y = df["y"].values

X_train, X_test, y_train, y_test = train_test_split(
 X,
 y,
 test_size=0.2,
 shuffle=False,
)
cls = AutoSklearnClassifier()
cls.fit(
 X_train,
 y_train,
)
y_pred = cls.predict(X_test)
print(accuracy_score(y_test, y_pred))

実行結果は以下となりました。

[WARNING] [2021-09-02 03:42:34,242:Client-EnsembleBuilder] No models better than random - using Dummy loss!Number of models besides current dummy model: 1. Number of dummy models: 1
[WARNING] [2021-09-02 03:42:36,222:Client-EnsembleBuilder] No models better than random - using Dummy loss!Number of models besides current dummy model: 2. Number of dummy models: 1
0.5309734513274337

「ランダムより優れたモデルが無い」と警告メッセージが出ています。要するに、これらのデータから機械学習を行っても明確な関連性が見つけられなかったという事になります。最終的に無理やり作成したモデルでの評価結果は「0.5309734513274337」

自動生成されたモデルを見てみます。

print(cls.show_models())
(0.260000, SimpleClassificationPipeline({'balancing:strategy': 'weighting', 'classifier:__choice__': 'sgd', 'data_preprocessing:categorical_transformer:categorical_encoding:__choice__': 'one_hot_encoding', 'data_preprocessing:categorical_transformer:category_coalescence:__choice__': 'no_coalescense', 'data_preprocessing:numerical_transformer:imputation:strategy': 'mean', 'data_preprocessing:numerical_transformer:rescaling:__choice__': 'power_transformer', 'feature_preprocessor:__choice__': 'select_percentile_classification', 'classifier:sgd:alpha': 0.0013631054367675124, 'classifier:sgd:average': 'False', 'classifier:sgd:fit_intercept': 'True', 'classifier:sgd:learning_rate': 'optimal', 'classifier:sgd:loss': 'perceptron', 'classifier:sgd:penalty': 'l2', 'classifier:sgd:tol': 0.0005999701177112265, 'feature_preprocessor:select_percentile_classification:percentile': 69.60059418172739, 'feature_preprocessor:select_percentile_classification:score_func': 'f_classif'},
dataset_properties={
  'task': 1,
  'sparse': False,
  'multilabel': False,
  'multiclass': False,
  'target_type': 'classification',
  'signed': False})),
(0.160000, SimpleClassificationPipeline({'balancing:strategy': 'weighting', 'classifier:__choice__': 'gradient_boosting', 'data_preprocessing:categorical_transformer:categorical_encoding:__choice__': 'no_encoding', 'data_preprocessing:categorical_transformer:category_coalescence:__choice__': 'no_coalescense', 'data_preprocessing:numerical_transformer:imputation:strategy': 'mean', 'data_preprocessing:numerical_transformer:rescaling:__choice__': 'robust_scaler', 'feature_preprocessor:__choice__': 'liblinear_svc_preprocessor', 'classifier:gradient_boosting:early_stop': 'valid', 'classifier:gradient_boosting:l2_regularization': 1.947481959717886e-07, 'classifier:gradient_boosting:learning_rate': 0.14962678227484008, 'classifier:gradient_boosting:loss': 'auto', 'classifier:gradient_boosting:max_bins': 255, 'classifier:gradient_boosting:max_depth': 'None', 'classifier:gradient_boosting:max_leaf_nodes': 1243, 'classifier:gradient_boosting:min_samples_leaf': 109, 'classifier:gradient_boosting:scoring': 'loss', 'classifier:gradient_boosting:tol': 1e-07, 'data_preprocessing:numerical_transformer:rescaling:robust_scaler:q_max': 0.9863752688366136, 'data_preprocessing:numerical_transformer:rescaling:robust_scaler:q_min': 0.26438489069409477, 'feature_preprocessor:liblinear_svc_preprocessor:C': 1.0, 'feature_preprocessor:liblinear_svc_preprocessor:dual': 'False', 'feature_preprocessor:liblinear_svc_preprocessor:fit_intercept': 'True', 'feature_preprocessor:liblinear_svc_preprocessor:intercept_scaling': 1, 'feature_preprocessor:liblinear_svc_preprocessor:loss': 'squared_hinge', 'feature_preprocessor:liblinear_svc_preprocessor:multi_class': 'ovr', 'feature_preprocessor:liblinear_svc_preprocessor:penalty': 'l1', 'feature_preprocessor:liblinear_svc_preprocessor:tol': 6.093031593256922e-05, 'classifier:gradient_boosting:n_iter_no_change': 11, 'classifier:gradient_boosting:validation_fraction': 0.18041079271731097},
dataset_properties={
  'task': 1,
  'sparse': False,
  'multilabel': False,
  'multiclass': False,
  'target_type': 'classification',
  'signed': False})),
 ・・・・

SimpleClassificationPipelineが28個連結された形となっています。

まとめ

AutoMLを使用して中国株の騰落予想を行ってみました。結果的には取得したデータと騰落の関係性は見つけられず自動化機械学習に失敗しました。

今回は、検証した内容が悪くAutoMLの有用性は分からなかったので、今後は別のデータ分析で使用してみようと思います。