dvcによるデータの管理をしてみた
はじめに
最近ではKaggleなどでkernelをsubmitしてコンペティションに参加するなどデータ分析においてもデータの管理や試行した履歴を残すといった再現性により一層注目が集まっていると感じております.
そんな中でデータのバージョン管理ツールとしてdvc(Data Version Control)というデータやモデルといった大きいデータを管理するツールがあります.
今回はdvcを試しに使ってデータ管理を行ってみましょう.
dvcのインストール
dvcはGitと連携して基本的に利用します.
また,dvcのコマンドはGitライクに作成されているためGitを扱える人にとっては比較的低い学習コストで導入することができます.
dvcの仕組みを簡単に説明すると,dvc add
でデータやモデルなどをdvcの管理対象として設定し, 生成された .dvc
ファイルをGitで管理することによってサイズの大きいデータをgitで管理することなくバージョン管理を実現します.
さて以降ではdvcを実際に使って試して行きましょう.
本記事の実行環境は以下になります.
- Python 3.6.9
- DVC 0.86.2
では,はじめにインストールを行います.
$ pip install dvc
Pip以外にもHomebrewやcondaなど複数のインストール方法が提供されていますのでご自身の環境に合わせて選択ください.
dvcの使い方
次に実際に dvc を利用してデータを管理してみましょう.
簡単のためファイルを保存する先はローカルの別ディレクトリとします.
git
とdvc
の初期化
$ mkdir sample $ cd sample $ git init $ dvc init $ git commit -m "Initialize commit"
- ローカルの保存先の指定
ローカルのディレクトリを設定します.
dvcで管理したデータは指定したディレクトリに保存されます.
$ dvc remote add -d mylocal /tmp/local_storage
- データファイルのダウンロード
ブランチ名 data_1
に対してdvcの公式が公開している data.xml
をダウンロードして data
ディレクトリ配下に配置します.
$ git checkout -b data_1 $ mkdir data $ wget https://data.dvc.org/get-started/data.xml -O data/data.xml
- dvcによるデータ管理
ダウンロードした data.xml
を dvc で管理対象にしてさらに git で.dvc
ファイルを管理します.
dvc add
で指定すると.dcvファイルが生成されるので,このファイルをgitで管理することでバージョン管理できるようになります.
$ dvc add data/data.xml $ dvc push $ git add data/.gitignore data/data.xml.dvc $ git commit -m "add data.xml"
- 別のブランチに切り替えて別のデータを管理する
新たに master
ブランチから data_2
ブランチを作成して,test.gif
をdata配下に保存します.保存後dvcで管理していきます.
$ git checkout master $ git checkout -b data_2 $ wget https://www.electrictoolbox.com/images/icons/linux-bsd.gif -O data/test.gif $ dvc add data/test.gif $ dvc push $ git add data/test.gif.dvc data/.gitignore $ git commit -m "add test.gif"
- 各ブランチで管理しているdataを削除する
先ほど管理した data_1
と data_2
のブランチで作成したdata.xml
と test.gif
を削除します.機械学習でデータを削除することは比較的少ないと思うので意外と新鮮な感じになります.
$ git checkout data_1 $ rm data/data.xml $ git checkout data_2 $ rm data/test.gif
- .dvcファイルで記載した内容のデータを取得する
data_1
ブランチで管理しているsample.csvをローカルの保存先から dvc pull
で取得します.
$ git checkout data_1 $ dvc pull $ ls data sample.csv sample.csv.dvc
data_2
ブランチも同様にデータを取得します.
$ git checkout data_2 $ dvc pull $ ls data train.gif train.tsv.gif
このように.dvcファイルと紐づいたデータ,.dvcファイルと紐づいたgitという形でバージョンとデータを紐づけることができます.
チームで分析する時や再現性を確保する時には非常に有効なツールとして活用できそうです.
ファイル保存先をリモートサーバに設定
そして,最後にデータの保存先をローカルではなくリモートのサーバ等に設定する場合の方法を記載しておきます.
企業などの環境によってはクラウドストレージなどが利用できない場合などがあるかと思うので,オンプレのリモート環境をハブにしてデータを授受する方法で対処することが想定されます.
以下にその方法を記載しておきます.
データを保存する際のコマンドは共通なので,設定のみを変更すればリモートサーバをストレージとして利用できます.デフォルトではsshに必要なライブラリが不足しているため以下のコマンドを用いてdvcを拡張します.
$ pip install dvc[ssh]
今回は以下の条件をストレージとして利用する場合の設定を記載します.
- ホスト: example.com
- ストレージパス: /home/user/tmp
- ユーザ名: user
- 認証: private key
$ dvc remote add remote_storage ssh://user@example.com:22/home/user/tmp
リモートの接続にはparamikoを介して行っており,公開鍵認証に利用する秘密鍵にパスフレーズを設定している場合は追加で設定が必要になります. 下記設定をしない場合はエラーが発生して正常に動作しないので注意してください.
$ dvc remote modify remote_storage ask_password true
これでリモートサーバをストレージとして利用することができます.
$ dvc push --remote remote_storage
まとめ
今回はdvcの使い方とリモートサーバをストレージとして利用した場合の設定方法をご紹介しました.非常に便利なので今後も継続的に利用していきたいと思います.
今度はS3などのクラウドストレージを利用する場合も試して見ようと思います.
回帰における評価指標
回帰の評価指標はこれ
回帰の評価指標として扱うべき指標は主にMAEとRMSEです.
ただし,どちらが良いということではなく観測されるデータに応じて使い分けるということが非常に重要です.
そのため,観測データの分布はしっかり可視化してどういった傾向があるのかを事前に把握しておきましょう.
さて,次からはそれぞれの指標の解説となぜMAEとRMSEで評価することが良いのかを話していこうと思います.
評価指標の種類
項目 | 指標 | 内容 |
---|---|---|
1 | 決定係数 | 推定されたモデルの当てはまりの良さを表す |
2 | 平均絶対誤差 | 予測結果と観測値の誤差の平均を表す |
3 | 平均二乗誤差 | 予測結果と観測値の誤差の二乗平均を表す |
4 | 二乗平均平方根誤差 | 予測結果と観測値の誤差の二乗平均にルートした値を表す |
5 | 平均絶対パーセント誤差 | 予測結果と観測値の誤差の割合を表す |
決定係数
決定係数は以下の式で表される.
この式の は観測値を はモデルの予測結果,は観測値の平均を示す.
決定係数の算出する式からわかるように,モデルの予測結果が観測値と近しい値を推論することができれば分子が小さくなり決定係数が1に近づくことになる.逆にモデルの予測結果が観測値と大きく異なる場合は分子が大きくなるため決定係数は0への近づく.また,観測データのばらつきが大きい場合には分母が大きくなるため決定係数が1に近づくことになるため一概に決定係数が1に近い値をとっているからと言って良いモデルとは限らないことに注意が必要である.正解データの分布などは事前に確認することで間違った解釈を防ぐことができるため積極的に可視化で分布は確認することが良いと考えられる.
import numpy as np y_small_scale = np.asarray([1, 1, 2, 2, 3, 3, 4, 4, 5, 5]) y_large_scale = np.asarray([1, 1, 5, 5, 10, 10, 100, 100,1000, 1000 ]) y_small_scale_mean = y_small_scale.mean() y_large_scale_mean = y_large_scale.mean() np.sum((y_small_scale - y_small_scale_mean)**2 ) # 20.0 np.sum((y_large_scale - y_large_scale_mean)**2 ) # 1522069.59999
一般論ではあるが以下に決定係数における判断基準をまとめておく.
- 0.6以下: あまり良いモデルではない
- 0.8以上: 高精度のモデルと考える
- 0.9以上: 過学習している可能性がある
決定係数は各データの予測が直感的に理解できる点で有効ではあるが決定係数のみで回帰の評価指標を判断するのは得策ではないため他の指標と組みわせて使うことが良さそうである.
平均絶対誤差(MAE)
平均絶対誤差は以下の式で表される.
観測値と予測値の誤差の絶対値の合計を平均したものである. 単純に差を算出するだけのため外れ値のようなデータの影響を受けにくいため,外れ値のようなスパイクがあるようなデータに対して評価する場合にはMSEやRMSEよりMAEを用いた方が良さそうです.
平均二乗誤差(MSE)
平均二乗誤差は以下の式で表される.
式を見ると観測値 と予測値 の差を二乗した値の平均を算出した値となる.
これを見ると先ほどのMAEと比べて差があった場合に二乗の部分よりMSEの値が大きくなることが言えます.
データセットが高いバイアスを含む公平な場合はMSEを利用することで適切な評価ができます.
平均二乗平方根誤差(RMSE)
平均二乗平方根誤差は以下の式で表される.
RMSEはMSEに対してルートをとった値になります.
RMSEはMSEと同様にデータセットが高いバイアスを含む公平なデータセットの時に利用することで適切な評価ができます.
ところでRMSEとMSEの使い分けについてはMSEはRMSEより計算が早く操作が簡単なため多くのアルゴリズムで採用されておりますが,MSEは誤差が二乗されたままなので元の大きさにスケーリングされていないことから元の観測値などと関連づけることができないといった注意点があります.
MSEを利用しなければいけないという条件がないのであればRMSEを使うことが良いでしょう.
平均絶対パーセント誤差(MAPE)
平均絶対パーセント誤差は以下の式で表される.
MAEを相対誤差で表現したものになります.
MAPEは観測値 と予測値 の誤差に対して観測値における割合を算出していることより,MAPEによって平均して予測がどのくらいの割合でずれているかを表現できます.しかし,観測値に0が含まれている場合は利用できないといった制約や観測値が非常に小さい値の場合には誤差が大きくなるため別途処理が必要になるといった対応が発生してくることを意識しておく必要があります.
なぜ「MAEとRMSE」なのか
サンプルのデータを使って各指標が状況に応じてどのような値になるのかを確認してみます.
整数値で均一な観測データを含む場合
import numpy as np from sklearn.metrics import r2_score from sklearn.metrics import mean_absolute_error from sklearn.metrics import mean_squared_error def culculate_error(y_test, y_pred): """ Returns: y_test: 観測値のnumpy array y_pred: 予測値のnumpy array """ print( "R^2: %s" % (r2_score(y_test, y_pred)) ) print( "MAE: %s" % (mean_absolute_error(y_test, y_pred)) ) print( "MSE: %s" % (mean_squared_error(y_test, y_pred)) ) print( "RMSE: %s" % (np.sqrt(mean_squared_error(y_test, y_pred))) ) print( "MAPE: %s" % (np.mean(np.abs((y_test - y_pred) / y_test)) * 100) ) y = np.asarray([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5]) y_hat = np.asarray([1, 1, 1, 1 ,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) print("整数値で均一な観測データの誤差") culculate_error(y, y_hat)
整数値で外れ値等を含まないある程度均一の観測データに対する誤差で注目する点はMSEとRMSEの値です.
平均絶対誤差であるMAEの値を基準にRMSEとMSEを見たときにMSEの値はより大きい値を指していることが分かります.これはMSEを算出する式からわかるように誤差を二乗している点が要因です.つまり観測値のスケールと合っていないことが分かります.そのため単純に誤差がいくつ離れているといった表現をすることができません.
整数値で均一な観測データの誤差 R^2: -2.0 MAE: 2.0 MSE: 6.0 RMSE: 2.449489742783178 MAPE: 54.333333333333336
外れ値の観測データを含む場合
import numpy as np from sklearn.metrics import r2_score from sklearn.metrics import mean_absolute_error from sklearn.metrics import mean_squared_error def culculate_error(y_test, y_pred): """ Returns: y_test: 観測値のnumpy array y_pred: 予測値のnumpy array """ print( "R^2: %s" % (r2_score(y_test, y_pred)) ) print( "MAE: %s" % (mean_absolute_error(y_test, y_pred)) ) print( "MSE: %s" % (mean_squared_error(y_test, y_pred)) ) print( "RMSE: %s" % (np.sqrt(mean_squared_error(y_test, y_pred))) ) print( "MAPE: %s" % (np.mean(np.abs((y_test - y_pred) / y_test)) * 100) ) y_1 = np.asarray([10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]) y_hat_1 = np.asarray([1, 1, 1, 1 ,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) y_2 = np.asarray([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 136]) y_hat_2 = np.asarray([1, 1, 1, 1 ,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) print("全て同じ観測値") culculate_error(y_1, y_hat_1) print("------------") print("外れ値を含む観測値") culculate_error(y_2, y_hat_2)
結果をみてわかるようにMAEの値は同じなのに対してRMSEとMSEの値には大きな誤差が生じています.
全体としての誤差が同じでも1つの外れ値の影響受けてRMSEとMSEの値は大きく変動してしまいます.
一方で,MAEとMAPEは外れ値の影響を受けにくいため全体の誤差を適切に表現することができていると言えます.
全て同じ観測値 R^2: 0.0 MAE: 9.0 MSE: 81.0 RMSE: 9.0 MAPE: 90.00000000000001 ------------ 外れ値を含む観測値 R^2: -0.0714285714285714 MAE: 9.0 MSE: 1215.0 RMSE: 34.85685011586675 MAPE: 6.61764705882353
予測値が小数点以下の小さい値を含む場合
import numpy as np from sklearn.metrics import r2_score from sklearn.metrics import mean_absolute_error from sklearn.metrics import mean_squared_error def culculate_error(y_test, y_pred): """ Returns: y_test: 観測値のnumpy array y_pred: 予測値のnumpy array """ print( "R^2: %s" % (r2_score(y_test, y_pred)) ) print( "MAE: %s" % (mean_absolute_error(y_test, y_pred)) ) print( "MSE: %s" % (mean_squared_error(y_test, y_pred)) ) print( "RMSE: %s" % (np.sqrt(mean_squared_error(y_test, y_pred))) ) print( "MAPE: %s" % (np.mean(np.abs((y_test - y_pred) / y_test)) * 100) ) y_1 = np.asarray([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5]) y_hat_1 = np.asarray([1.01, 1, 1, 2.02, 2, 2, 3.03, 3, 3, 4.04, 4, 4, 5.05, 5, 5]) y_2 = np.asarray([0.1, 1, 1, 0.2, 2, 2, 0.3, 3, 3, 0.4, 4, 4, 0.5, 5, 5]) y_hat_2 = np.asarray([0.11, 1, 1, 0.22, 2, 2, 0.33, 3, 3, 0.44, 4, 4, 0.55, 5, 5]) print("1より大きい値の観測値") culculate_error(y_1, y_hat_1) print("------------") print("1より小さい値を含む観測値") culculate_error(y_2, y_hat_2)
観測値としてy_1
では1より大きい値をだけの観測値とy_2
では1より小さい値を含む観測値の場合で各指標を算出した結果は以下のようになりました.これより絶対的な誤差が同じであってもMAPEはより大きな値となっていることが分かります.
1より小さい値を予測する場合はMAPEの値が大きく算出されてしまうため,誤差の割合でどうしても評価したい場合を除き安易にMAPEで評価するのは得策ではないです.その場合は観測値に対して1より大きい値になるように処理を加えて評価することが必要となります.
1より大きい値の観測値 R^2: 0.9998166666666667 MAE: 0.00999999999999998 MSE: 0.000366666666666665 RMSE: 0.019148542155126718 MAPE: 0.3333333333333328 ------------ 1より小さい値を含む観測値 R^2: 0.9998761261261261 MAE: 0.010000000000000002 MSE: 0.0003666666666666669 RMSE: 0.019148542155126767 MAPE: 3.3333333333333335
これより外れ値の影響が受けにくい指標であるMAE,誤差のスケールが観測値と一致しているRMSEを利用することが良いと言えるのです.
実業務における評価の難しさ
ここまで各指標となぜMAEとRMSEが良いのかについて述べてきましたが,実務では精度以外にも追求する様々な観点があり,その状況に応じて最適な指標を選択する必要があります.例えば,結果の解釈を分かりやすくするために予測値の誤差がどれくらいのパーセントなのかを示すMAPEを使うといった場面も容易に想像できるかと思います.
データサイエンティストには一般的にサイエンスの領域だけではなくビジネスサイドの情報を踏まえて見せ方を変えていかなければいけないため幅広い指標について理解しておくことは非常に重要です.そして,それらを適切に使い分けることがポイントになってくると思います.
今回の内容は基礎的なものでしたが,これからも様々な観点で知識を吸収して最適な選択ができるように努力していきたいと思います.
G検定に合格した時の勉強法
はじめに
XAIの流行りもあり最近ではGBDT系のアルゴリズムを活用する場合が多いのですが,特徴量エンジニアリングの過程の中で深層学習を用いた特徴量生成などに挑戦する機会があり,ディープラーニングについてより基礎的で体系的な知識を身に付けたいと思い立ち,G検定の受験を試みました.その際に私が行った勉強方法についてまとめます.
G検定とは
G検定とはジェネラリスト検定の略でJDLAが主催するディープラーニングに関する知識を証明する資格です. G検定の他にもE検定と呼ばれるディープラーニングを実装するエンジニア向けの資格もあるので実装力の証明をしたい方はそちらを受験すると良いと思います.
試験の中身についてはディープラーニングに関する知識から線形代数などの数学,機械学習全般の知識など幅広く出題されるため全く知識がない状態で試験に合格することは難しいと思います.
勉強前の状況
勉強前の状況ですが,ディープラーニングにおけるフレームワークなどは扱った経験があり,詳細なアルゴリズムまでは把握していませんでしたが,全く聞いたことがない単語はほとんどなく,手法と処理内容は概ね把握している状態でした.また,ディープラーニング以外の機械学習全般の知識にはそこそこの自信がある状態でした.
教材
今回実際に利用した教材は以下です.
- G検定公式問題集
- AI白書2019
- Study AIの模擬試験(225門)
https://www.ipa.go.jp/ikc/info/20181030.htmlwww.ipa.go.jp
学習方法
基本的な学習方法としてはひたすら問題集を解きながら知識が不足している箇所を調べて勉強するというスタンスでした. また,実際の試験では120分で100問(実際に回答するのは225問)といった非常に多くの問題に回答しなければいけないため,StudyAIが提供している模擬試験などにも挑戦して早く回答するように意識した勉強を行いました.
AI白書2019は非常に幅の広い領域を詳細にまとめている分厚い書籍のため初めてAIを勉強するという方からすると,「これを全て理解するのか...」と怪訝そうな顔をすると思います.そのため,全てを読んで理解すると言うよりは,勉強して行く中で「この領域は深掘りしたいな」と言う箇所があった際に読みこむ補助ツール的な位置付けで利用することをお勧めします.現に私も全部読み込んで試験に備えた訳ではなく,特定分野の今後の発展などについて把握しておきたいと言う時に利用していました.
受験
私は11月9日開催の第3回目の試験を受験しました。
過去の受験者の記事を参考にDeepLearningの発展の歴史といった内容が試験問題の中心になるのかと想定していたのすが,実際は最新の動向が多く出題されていたように感じました.特に自然言語処理や強化学習といった領域は勉強しておいて良かったと試験中幾度となく思いました.試験中でも知らないことは調べられるのですが圧倒的に時間が足らないので調べながらというよりは不安な問題を確認する程度で受験するくらいのスタンスで受験する方が確実に受かると思いました.
合格結果
結果は無事に合格していました.合格発表は受験日から約1週間後であったため,ほぼ確実に受かっているとは感じつつも早く結果が出ないかと待ち遠しい1週間を過ごしました.Twitterなどでも「早く合否結果通知こい」といったつぶやきをしてる方が沢山いたのでみんな同じ気持ちなんだなと謎のシンパシーを感じてた気がします笑
まとめ
ディープラーニングを日常的に利用している人であれば難易度は決して高くなく,勉強しなくても合格できる資格だと思います. ただし,技術だけではなくAIの歴史や発展に関する知識までを問われるため確実に合格したい人はしっかり問題集などで事前に勉強することをオススメします. 今回私はディープラーニングに関する体系的な知識を獲得したいという思いで受験をしましたが,これを機により深い専門的なディープラーニングに関する知識を獲得して行こうと思います.
データ分析における基礎【モデル評価】
はじめに
データ分析におけるモデル評価についての内容をまとめてみます.
データ分析を初めて行うとモデル作成や手法に注目しがちですが,目的を達成するための最適なモデル選定においてはモデル評価は重要な要素になります.
また,私自身の備忘録としても本記事にモデル評価のまとめを記していこうと思います.
一般的なデータ分析の問題設定
問題設定の種類
一般的なデータ分析の問題設定は以下の2種類にカテゴライズされることがよくあります.
- 分類
- 回帰
厳密にはその他にもクラスタリングや強化学習と言った問題もあるのですが,現実の世界でよく問題設定として挙がってくるのが分類と回帰の2つのカテゴリです.分類は教師あり学習の1つで,予測対象はカテゴリなどの離散的なクラスを予測します.例えば,画像に写っている内容が猫かそれ以外かを判別する二値問題などがこれに該当します.回帰は教師あり学習で連続値を予測する際に利用します.通信事業を行なっている事業者が自社のネットワークトラフィックの帯域をどれくらい確保するべきかを過去のトラフィック量から推測して帯域を確保するなどと言った問題がそれに当たります.
次ではこの2つの問題のそれぞれに対して適切な評価方法について述べていきます.
適切な分類とその評価
データ分析には大きく分けて2種類の問題設定があるということを話しました.ここでは各々の問題設定における評価方法について述べていきます.
分類
分類問題では正しいクラスに分類されたかどうかを評価する必要があります. そこで利用されるものが混合行列になります.
予測結果 | |||
---|---|---|---|
Positive | Negative | ||
実際の結果 | Positive | True Positive | False Nagative |
Negative | False Positive | True Nagative |
この行列をもとに適合率と再現率,F値を算出して各種モデルを比較することができます. 適合率や再現率,F値の解説はまたの機会とします.以下に各式を記載します.
正解率などを算出することもありますが,正解率が高いからと言って良いモデルとは限りません.というのも,システムの異常を予測検知するという問題設定を想定すると,異常状態はそこまで頻繁には発生しません.そのため,仮に5%の確率で異常が発生するとして,学習したモデルがすべての出力を正常と出力する場合であったとしても95%の精度を算出することが可能になります.このように正解率で比較してしまうと誤った評価・解釈をしてしまう可能性があるため,混合行列を算出して正確に吟味することを心がけましょう.
回帰
回帰での連続する数値を予測する問題であると説明しました.
回帰における評価は主に平均二乗誤差を利用します.
回帰分析で全データの平均値を出力する予測モデルを考えたとき,その平均二乗誤差は標準偏差となります.そのため,最低ラインとして標準偏差と比較,モデル間での平均二乗誤差を比較することでモデルの良し悪しを判別することができます.
また,平均二乗誤差とは別に回帰式の当てはまりの良さを表現する決定係数という評価指標を用いる場合もあります.決定係数は常に平均を出力するモデルに比べて相対的にどのくらい性能が良いのかを表します.決定係数が1に近ければ良い性能であることを表し,逆に0に近いほど良くない性能であることを示します.
まとめ
今回は一般的なデータ分析の問題とその評価方法についての話をしました.初めの投稿ということもあって基本的な内容についてまとめてみました.データ分析ではモデルのアルゴリズムや手法に焦点が当てられることが多いため,評価について述べられる機会というのはそれほど多くはないと思います.ですが,実際のデータ分析ではどんな問題であったとしても必ず行う重要なプロセスになるので必ず抑えておきたいですね.
これからもデータ分析における知見を蓄積する目的で様々なブログを記載していこうと思います.まずは隔週での投稿を目指していこうと思います.