common.title

インターン講座1:GBDT / PyTorch NN

Yuichiro Minato a month ago

3

3

こんにちは、blueqat社では時々インターンを募集して、スキルの習得や就職支援、起業支援などをしています。また、弊社の業務を理解してもらう上で重要なスキルの習得を進めてもらいます。blueqat社では量子を利用したアルゴリズムを開発して社会問題を解いていますが、古典コンピュータでの計算との比較も度々でます。最近は量子の割合がかなり増えていますが、まだまだ量子と古典を比較したり、量子古典ハイブリッドを使いこなすためには過渡期ですので、両方のスキルが必要です。今回は初回です。

第一回:GBDT / PyTorch NN
第二回:離散最適化(GA) / 連続最適化(scipy optimize / torch optim) / ベイズ最適化(optuna)
第三回:量子アニーリングとQUBO / QAOA
第四回:量子ニューラルネットワーク回路

「GBDT」
よく利用される軽量で精度の高い機械学習モデルです。GBDTはGradient Boosting Decision Treeの略で、勾配降下法+ブースティング+決定木で構成されたアルゴリズムです。古典モデルは多くの参考資料がネットなどにありますので深くは説明しませんが使い方を確認します。

下記は東急田園都市線のたまプラーザ駅周辺の物件の、徒歩時間、階数、面積、築年数、賃料をまとめたデータです。
今回はxgboostというモデルを利用して賃料をその他のパラメータから予測してみます。
numpyはよく使われる数値ライブラリ、pandasはよく使われるデータ解析用のライブラリです。

最初に今回利用するライブラリをインストールしておきます。

!pip install numpy pandas sklearn xgboost
Requirement already satisfied: numpy in /opt/conda/lib/python3.10/site-packages (1.21.0)

Requirement already satisfied: pandas in /opt/conda/lib/python3.10/site-packages (1.4.3)

Requirement already satisfied: sklearn in /opt/conda/lib/python3.10/site-packages (0.0)

Requirement already satisfied: xgboost in /opt/conda/lib/python3.10/site-packages (1.6.2)

Requirement already satisfied: python-dateutil>=2.8.1 in /opt/conda/lib/python3.10/site-packages (from pandas) (2.8.2)

Requirement already satisfied: pytz>=2020.1 in /opt/conda/lib/python3.10/site-packages (from pandas) (2022.1)

Requirement already satisfied: scikit-learn in /opt/conda/lib/python3.10/site-packages (from sklearn) (1.1.2)

Requirement already satisfied: scipy in /opt/conda/lib/python3.10/site-packages (from xgboost) (1.8.1)

Requirement already satisfied: six>=1.5 in /opt/conda/lib/python3.10/site-packages (from python-dateutil>=2.8.1->pandas) (1.16.0)

Requirement already satisfied: threadpoolctl>=2.0.0 in /opt/conda/lib/python3.10/site-packages (from scikit-learn->sklearn) (3.1.0)
import numpy as np import pandas as pd #データを準備しました。 data = np.array([[8,3,83.74,18,22],[5,2,75.72,19,19],[7,2,31.47,46,7.8],[18,2,46.62,36,8],[8,3,41.02,49,8],[8,1,70.43,25,15.8],[8,1,70.43,25,15.8],[12,1,48.02,3,12.5],[10,4,58.57,36,11.8]]) df = pd.DataFrame(data,columns=['toho','kaisu','hirosa','chiku','chinryo']) df
   toho  kaisu  hirosa  chiku  chinryo

0   8.0    3.0   83.74   18.0     22.0

1   5.0    2.0   75.72   19.0     19.0

2   7.0    2.0   31.47   46.0      7.8

3  18.0    2.0   46.62   36.0      8.0

4   8.0    3.0   41.02   49.0      8.0

5   8.0    1.0   70.43   25.0     15.8

6   8.0    1.0   70.43   25.0     15.8

7  12.0    1.0   48.02    3.0     12.5

8  10.0    4.0   58.57   36.0     11.8

今回はこちらのデータを学習させ、賃料を予測するモデルを作ってみます。まずはデータから賃料だけのデータを抜き出し、賃料以外のデータを作ります。

#賃料だけのデータ y = df["chinryo"] #賃料以外のデータ X = df.drop(columns=["chinryo"], axis=1)

次にこれらのデータをさらに訓練用のデータとテスト用のデータに分けます。訓練用のデータをテストして精度を測定しても高くなるのは当然なので、訓練用のデータと精度評価用のデータは通常分けます。ここでは、機械学習用のライブラリのscikit-learnをつかってデータをさらに2つに分離してみます。

test_size=0.2となっているのは、評価用のデータを全体の20%確保するというものです。

from sklearn.model_selection import train_test_split X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=1) X_train
   toho  kaisu  hirosa  chiku

6   8.0    1.0   70.43   25.0

7  12.0    1.0   48.02    3.0

1   5.0    2.0   75.72   19.0

0   8.0    3.0   83.74   18.0

4   8.0    3.0   41.02   49.0

3  18.0    2.0   46.62   36.0

5   8.0    1.0   70.43   25.0

このように、上記のデータから訓練用のデータだけが抜き出されました。残りはy_trainに入っています。

これでデータが用意できましたのでさっそくxgboostを使ってみます。ツールを読み込み、モデルと呼ばれる学習用の器を用意します。そして、fitを使い、X_trainの値とy_trainの値を学習させます。

# xgboost import xgboost as xgb model = xgb.XGBRegressor() model.fit(X_train, y_train)
XGBRegressor(base_score=0.5, booster='gbtree', callbacks=None,

             colsample_bylevel=1, colsample_bynode=1, colsample_bytree=1,

             early_stopping_rounds=None, enable_categorical=False,

             eval_metric=None, gamma=0, gpu_id=-1, grow_policy='depthwise',

             importance_type=None, interaction_constraints='',

             learning_rate=0.300000012, max_bin=256, max_cat_to_onehot=4,

             max_delta_step=0, max_depth=6, max_leaves=0, min_child_weight=1,

             missing=nan, monotone_constraints='()', n_estimators=100, n_jobs=0,

             num_parallel_tree=1, predictor='auto', random_state=0, reg_alpha=0,

             reg_lambda=1, ...)

これでできました。モデルの中のパラメータ類が学習された状態となりました。さっそく何かしらデータを入れて予測してみます。
今回は駅徒歩9分、5階、広さ58.3平米、築年数34年の物件の賃料を予測してみます。

X_testに値を格納し、predictを使ってこの値を代入してみます。

X_test = np.array([[9,5,58.3,34]]) predictions = model.predict(X_test) predictions[0]
12.527947

計算結果として12.5万円と出ました。実際の賃料は11.5万円でした。そこまで外れていないことが分かります。わずかなデータでも学習ができました。

次にどのパラメータが予測に効いたのかを見てみます。

xgb.plot_importance(model)
<AxesSubplot:title={'center':'Feature importance'}, xlabel='F score', ylabel='Features'>
<Figure size 432x288 with 1 Axes>output

これを見る感じですと、広さや徒歩分数、階数などが重視されているのが分かります。パラメータ類を調整するともっと精度が上がります。

「PyTorch NN」
PyTorchは有名な機械学習ライブラリで、主にニューラルネットワークと呼ばれる手法で利用され、最近では量子計算ライブラリでもたびたび登場します。今回は同じデータを使って回帰計算をしてみたいと思います。まずはpytorchをインストールします。

!pip install torch
Requirement already satisfied: torch in /opt/conda/lib/python3.10/site-packages (1.12.1)

Requirement already satisfied: typing-extensions in /opt/conda/lib/python3.10/site-packages (from torch) (4.3.0)

そして次にモデルを作ります。ニューラルネットワークモデルでは、入力値が4つ、出力値が予測する1つで、中間層は今回12ノードにしてみます。4x12x1のネットワーク構造ができます。

このモデルを最適化するアルゴリズムをAdamに設定し、損失関数と呼ばれる入力データからの予測値と実際の正解データの誤差の関数を指定します。データは先ほどのDataFrameのデータからPyTorchで読めるテンソルの形式に変換します。正解データはそのままだと1次元の配列になってしまいますので、多少変換しました。

100回学習を行います。

import torch model2 = torch.nn.Sequential() model2.add_module('fc1', torch.nn.Linear(4, 12)) model2.add_module('relu', torch.nn.ReLU()) model2.add_module('fc2', torch.nn.Linear(12, 1)) #最適化選ぶ optimizer = torch.optim.Adam(model2.parameters(), lr=0.1) #損失関数選ぶ lossf = torch.nn.MSELoss() #入力値とターゲット input = torch.Tensor(X_train.values) target = torch.Tensor([[i] for i in y_train.values]) #トレーニング for _ in range(100): loss = lossf(model2(input), target) optimizer.zero_grad() loss.backward() optimizer.step()

モデルの学習が終わりましたので、推定をしてみたいと思います。こちらも先ほどのデータを使います。

pred = model2(torch.Tensor(X_test)) pred
tensor([[11.0694]], grad_fn=<AddmmBackward0>)

11.0694という値がでました。実際の賃料は11.5万円ですので比較的近いデータを推定することができました。

今回はxgboostとpytorchのニューラルネットワークを使って家賃の推定をしてみました。様々な使い方がありますので、様々な問題に応用してみましょう。以上です。

Yuichiro Minato

@yuichiro_minato2

blueqat CEO/CTO

About us | Terms of Service | © 2022, Copyright © 2022, blueqat Inc. All rights reserved