党䜓の流れを意識しお機械孊習に取り組む

前回は、教垫あり孊習/分類に関しお、「決定朚」「ロゞスティック回垰」手法の違いを玐解いおいきたした。手法による違いがどういったものなのかが盎感的にむメヌゞできたしたでしょうか。

これたでは、機械孊習を盎感的に理解しおもらうために、簡易的なデヌタを準備し、機械孊習の郚分だけを取り扱っおきたした。しかし、本来は、1)機械孊習を䜿うための目的や解決すべき課題の蚭蚈、2)デヌタ蚭蚈、3)デヌタの収集・加工、4)デヌタの把握を行い、ようやく5)機械孊習を実行できたす。今回は、これたでよりも耇雑なデヌタを甚意したので、党䜓の流れ(1〜5の工皋)を意識しながら機械孊習に取り組んでいきたしょう。

デヌタの準備・抂芁把握

今回は、消費者物䟡指数から、消費者支出が増加するかを予枬(分類)しおみたす。デヌタは、これたでず同様に政府統蚈の総合窓口e-statのデヌタを䜿甚したす。

目的倉数ずしお、月次の消費者支出を家蚈調査から取埗し、先月よりも支出が増加した堎合はフラグ1を、枛少した堎合はフラグ0を付䞎したした。説明倉数ずしおは、月次の消費者物䟡指数を2015幎基準消費者物䟡指数から取埗し、加工しおありたす。今回は冒頭にあたり现かくデヌタの説明を行いたせん。どんなデヌタなのかを把握しおいく䜜業も䞀緒にやっおいきたしょう。

たずは、こちらからデヌタをダりンロヌドし、Jupyter Notebookの䜜業フォルダにコピヌしおください。Jupyter Notebookを立ち䞊げ、右䞊のNewから、Notebookを開き、タむトル名を倉曎しおおきたしょう。今回は、ConsumerExpendituresずいう名前にしたした。

たずは、デヌタを読み蟌んでみたす。

import pandas as pd
data = pd.read_csv('ConsumerExpenditures.csv')
data.head()
  • デヌタ読み蟌み

たずは、先頭5行のみを衚瀺したす。これたでず違い、党デヌタが画面に衚瀺されおおらず、「 」で省略されおいたす。列数は、䞋の63columnsから63列存圚するこずがわかりたす。これたでは10列皋床でしたが、倧幅に列数、すなわち説明倉数の数が増えおいたす。このたたでは、デヌタ数や、どんな列があるかを完党に把握できないので、たずは党䜓把握に努めたしょう。䞋蚘、コヌドを実行しおみおください。

data.count()
  • デヌタ数の把握

countを指定するこずで、列名ずその列に入っおいるデヌタ数が衚瀺されたす。どのデヌタも387ずあるように、今回のデヌタは387行存圚するこずがわかりたす。これで、行数に関しおも、これたでの50行皋床から倧きく増えおいるこずが理解できたかず思いたす。たた、今回のデヌタでは存圚しないのですが、デヌタが入力されおおらずデヌタ欠損(null)が生じおいるこずが倚々ありたす。countを実行するず、デヌタの欠損倀は数に含たれないので、欠損があるかどうかの把握を簡易的に行えたす。

さお、列名もcountによっお倧分芋えおきたしたが、せっかくなので列名だけ取り出しおみたしょう。

data.columns
  • デヌタの列名䞀芧

これによっお、列名がすべお取埗できたした。この列名を芋おいくず、今回の目的倉数である消費支出増加フラグず、それ以降の説明倉数に倧きく分かれるこずがわかりたす。説明倉数を芋おいくず、第3回で扱った消費者物䟡指数の項目ず同じです。ただし、圓月(Date)に察しお1カ月前から6カ月前たで遡っお消費者物䟡指数が甚意されおいたす。このようなデヌタを甚意した理由は、冒頭に述べた1)機械孊習の目的ず関連しおいたす。

䜕床か述べおいたすが、機械孊習の本来の目的は、未知な事䟋を予枬するこずにありたす。今回の䟋でいうず、来月の消費者支出を予枬するこずです。来月の予枬を行う際に、来月のデヌタを䜿うこずはできるのでしょうか。もうおわかりのように、来月のデヌタはただ存圚しないため、今月のデヌタのみで、来月の予枬を行う必芁がありたす。そのため、過去に遡っお消費者物䟡指数を甚意しおいるのです。物䟡が䞋がれば、お金を出しやすくなるずいうのはむメヌゞしやすいかず思いたす。今回は取り扱いたせんが、正確には、過去の消費者物䟡指数が支出に寄䞎しおいるのをグラフ化したりしお確認するずなお良いず思いたす。䜕カ月前の物䟡が支出に寄䞎しおいるかわからないため、1〜6カ月前たでのデヌタをそれぞれ抜出し機械孊習できる圢にデヌタを蚭蚈し(2.デヌタ蚭蚈工皋)、加工を行なっおいたす(3.デヌタの収集・加工工皋)。

デヌタの準備

それでは、機械孊習のために、デヌタ準備をしおいきたしょう。先ほど調べおわかったかず思いたすが、目的倉数は消費支出増加フラグ、説明倉数は食料から諞雑費、1カ月前から6カ月前たでのデヌタずなりたす。

data_tmp = data.copy()
del data_tmp['Date']
del data_tmp['消費支出']
data_tmp_X = data_tmp.copy()
del data_tmp_X['消費支出増加フラグ']
data_tmp_Y = data_tmp['消費支出増加フラグ']
data_tmp_X.columns
  • 機械孊習向けデヌタの準備

たずは、読み蟌んだデヌタを残すために、datatmpを䜜成したす。そこから、䞍芁なデヌタを削陀した埌、説明倉数datatmpX、目的倉数datatmpYを䜜成したす。最埌に、datatmp_X.columnsで、列がしっかり甚意できおいるか確認しおいたす。次に、デヌタを蚓緎デヌタず、テストデヌタに分割したす。

from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(data_tmp_X, data_tmp_Y,random_state=0, test_size=0.3)
print(len(X_train))
print(len(Y_train))
print(len(X_test))
print(len(Y_test))
  • 蚓緎デヌタ、テストデヌタの分割

分割には、traintestsplitを䜿甚しおいたす。サむズは、蚓緎70%、テスト30%に分割したした。しっかり分割できおいるか確かめるために、lenを甚いおデヌタ数を単玔に合算し、printで出力しおいたす。Xtrain、Ytrainは270件、Xtest、Ytestは110件ずなっおおり、387件を指定通り分割出来おいるこずがわかりたした。これで、機械孊習のための準備は敎いたした。

決定朚

たずは、決定朚による予枬モデル䜜成をやっおいきたしょう。

from sklearn.tree import DecisionTreeClassifier
treeModel = DecisionTreeClassifier(max_depth=3, random_state=0)
treeModel.fit(X_train, Y_train)
from sklearn import metrics
print(metrics.accuracy_score(Y_train, treeModel.predict(X_train)))
print(metrics.accuracy_score(Y_test, treeModel.predict(X_test)))
  • 決定朚

1行目で、決定朚のむンポヌト、2行目で予枬モデルの定矩を行なっおいたす。今回の朚の深さは、ずりあえず3でやっおみたした。その埌、Fitで、予枬モデルを䜜成し、さらに、粟床を把握するために、accuracy_scoreで最も簡易的なモデル評䟡(粟床)を行ないたした。蚓緎デヌタで78%、テストデヌタで60%ずなりたした。蚓緎デヌタでの粟床が高いため、蚓緎デヌタに過剰適合(過孊習)傟向にありたすが、蚓緎、テストデヌタどちらを甚いおも60%以䞊の粟床は出おいたす。

過孊習傟向なため、モデルの耇雑さを枛らしおみたしょう。モデルをシンプルにする方法ずしお、max_depthを小さくする方法がありたす。

treeModel = DecisionTreeClassifier(max_depth=2, random_state=0)
treeModel.fit(X_train, Y_train)
print(metrics.accuracy_score(Y_train, treeModel.predict(X_train)))
print(metrics.accuracy_score(Y_test, treeModel.predict(X_test)))
  • 決定朚 (シンプルモデル)

max_depthを2にするず、蚓緎デヌタの粟床は枛少し、テストデヌタの粟床は向䞊したした。これによっお、粟床は䞋がりたしたが、モデルは汎化され、より良いモデルになったず考えられたす。最埌に、モデルに寄䞎しおいる倉数を抜出しおみたしょう。

Importance = pd.DataFrame({'倉数名':data_tmp_X.columns, '重芁床':treeModel.feature_importances_})
Importance[Importance['重芁床'] != 0]
  • 決定朚モデルによる重芁倉数

これだけ芋るず、すべお衣類関係の物䟡が寄䞎しおいるずいう結果になりたした。解釈は難しいずころですが、衣類関連だけですべおの消費支出を決めおいるずは考えにくいです。ただモデル粟床が䜎いこずも考慮する必芁があるず思いたす。しかし、このデヌタセットを䜿甚する限り、これ以䞊決定朚のモデル粟床が向䞊させるのは困難なため、ロゞスティック回垰に挑戊し、モデル粟床を比范しおみたしょう。

ロゞスティック回垰

䜿甚するデヌタは、決定朚ず党く同じで良いので、蚓緎デヌタ、テストデヌタに分割されおいるものを䜿甚したす。

from sklearn.linear_model import LogisticRegression
logModel = LogisticRegression()
logModel.fit(X_train, Y_train)
print(metrics.accuracy_score(Y_test, logModel.predict(X_test)))
print(metrics.accuracy_score(Y_train, logModel.predict(X_train)))
  • ロゞスティック回垰

決定朚のずきず同様に、1行目でロゞスティック回垰のむンポヌト、2行目で予枬モデルの定矩を行なっおいたす。決定朚ず異なり、特にパラメヌタ指定はせず、デフォルトのものを䜿甚しおいたす。その埌、Fitで予枬モデルを䜜成し、さらに、簡易的な粟床評䟡を行いたした。こちらは驚くこずに、蚓緎デヌタで83%、テストデヌタでも79%を瀺したした。決定朚よりも党䜓的な粟床が高いだけでなく、蚓緎デヌタずテストデヌタの粟床に開きがないため、汎化されおいる良いモデルずなっおいたす。

前回述べたように、手法によっお分類の方法が異なるため、今回のケヌスのように倧きくモデル粟床が異なるこずがありたす。いく぀かの手法を甚いお適切に評䟡を行い、最適なモデルを䜜成しおいくこずの重芁性を理解できたのではないでしょうか。

せっかくなので、ロゞスティック回垰のモデルに぀いお、もう少し觊れおいきたしょう。前回、ロゞスティック回垰は、決定朚のように条件分岐によっお線を匕いおいくのではなく、あくたでも倚倉数の匏を元に分割線を匕くものであるずお䌝えしたした。ロゞスティック回垰は、線圢回垰の関数Y=aX1+bX2+zを0から1の範囲に抌し蟌めおしたう関数を䜿甚しおいたす。そのため、線圢回垰ず同様に、モデルを䜜成するこずは、線を匕くこずであり、線を匕くこずは係数(a、b、z)を決めるこずず同矩です。

ロゞスティック回垰には、決定朚のようにfeature_importancesが存圚したせんが、係数によっおある皋床倉数の寄䞎がわかるようになっおいたす。早速、出力しおみたしょう。

Coef = pd.DataFrame({'倉数名':data_tmp_X.columns, '係数':logModel.coef_[0]})
Coef.sort_values('係数')
  • ロゞスティック回垰による係数

1行目で、今回䜜成したモデルから、係数を抜出しおいたす。これらの係数は、Y=aX1+bX2+zのaやbに盞圓したす。぀たり、それぞれの倉数に掛かっおおり、絶察倀が倧きければ倧きいほど寄䞎は倧きく、正であれば支出増加に、負であれば支出枛少に寄䞎しおいるこずになりたす。絶察倀が倧きい郚分には、1カ月前の物䟡指数は存圚しおおらず、1カ月前の物䟡指数の寄䞎は小さいこずが考えられたす。぀たり、支出増枛には少なくずも2カ月以䞊前の物䟡が倧きく圱響しおいるず予想できたす。ただし、䜏宅の物䟡指数が、正にも負にも入っおおり、景気の波等が関係しおいる可胜性がありたす。さらにより良いモデルにしおいく堎合、デヌタの粒床や説明倉数の芋盎しも必芁になるず思いたす。

さお、今回は、ここたで孊んできたこずを掻かし、より実践に近い圢で、デヌタを扱い、機械孊習によるモデル䜜成たで行いたした。前回たでの埩習に加えお、デヌタの扱い方のむメヌゞや、機械孊習のモデル構築プロセスの理解は進みたしたか。ここからは、自分で悩みながら、解決したい課題を考えお、いろんなデヌタに挑戊しおいくこずが最も重芁だず思いたす。いろんな課題に取り組むこずで、機械孊習の粟床だけにずらわれず、真に䞖の䞭に必芁な機械孊習モデルを䜜れるようになるず思いたす。たた、自分で課題を考えお、解決手段を考えるこずで、自然ず機械孊習手法のバリ゚ヌションも増えおいくず思いたす。

次回は、これたでずは違ったデヌタを扱いながら、機械孊習の未来にも觊れおいきたいず思いたす。

著者プロフィヌル

䞋山茝昌
倧手電機メヌカヌにお、ハヌドりェアの研究開発に埓事した埌、独立。独立埌は゜フトりェア、デヌタ分析等においお実務経隓を積むずずもに、数瀟を共同創業。その䞭でも合同䌚瀟アむキュベヌタでは、人工知胜・IoTなどの可胜性や方向性を研究しおいる。最近では、オヌプンデヌタに着目し、オヌプンデヌタ掻甚のためのwebサヌビスの立ち䞊げ、オヌプンデヌタ×IoTによる䟡倀創出を1぀のテヌマに取り組んでいる。