機械学習手法による違い

前回は、最も直感的にわかりやすい決定木手法を用いて、教師あり学習の分類を取り扱いました。教師あり学習のモデル作成や、過学習などに触れ、教師あり学習における作業プロセスをイメージすることができたと思います。

今回は、さらに一歩踏み込んで、手法の違いを直感的に理解してみましょう。これまでは、教師なし学習「K-Means」、教師あり学習/回帰「線形回帰」、教師あり学習/分類「決定木」を取り扱ってきましたが、実際には、それぞれの学習に対して、多くの機械学習手法が存在します。実際に、同じ教師あり学習/分類を扱う際であっても、いくつかの手法を同時に試し、適切な手法を選択します。

そこで今回は、前回と同じく教師あり学習/分類に関して、「決定木」以外の手法として「ロジスティック回帰」を取り扱い、手法の違いに触れていこうと思います。

データの準備

今回のデータは前回と同じく「consumerPrices_tree.csv」を使用します。各都道府県の物価データを説明変数として、「大都市圏を持つ都道府県なのか、そうでないか」を目的変数として分類していきます。

これまでと同様に、データを準備し、Jupyter Notebookを立ち上げてください。前回、すでに「consumerPrices_tree.csv」をダウンロードしてある方は、データの準備は必要ありません。Jupyter Notebookが立ち上がったら、右上のNewから、Notebookを開き、タイトル名を変更しておきましょう。今回は、ClassificationModelsという名前にしました。 まずは、これまでと同様に、データを読み込んでみます。

import pandas as pd
data = pd.read_csv('consumerPrices_tree.csv')
data.head()

前回と同じデータなため、先頭5行のみを表示し、エラーが出ないことを確認しています。問題なければ、機械学習に向けて、説明変数と目的変数のデータを作成しましょう。

X = data.drop(['都道府県', '大都市圏分類'], axis=1)
Y = data['大都市圏分類']

データ読み込み

これで、機械学習に向けての準備が整いました。

決定木vsロジスティック回帰 - 分類結果の違い

それでは、手法の違いを見ていきましょう。まずは、前回使用した「決定木」と新たに「ロジスティック回帰」を用いて、分類結果にどのような違いが見られるかを見ていきましょう。決定木は、前回もお伝えしたように、最もきれいに分割できる説明変数およびその条件を探す作業を、木構造状に派生させていく手法です。一方、ロジスティック回帰は、多変数(説明変数)に対してきれいに分割できる線を引く手法です。回帰という名前がついていますが、実際には分類問題を解く手法なので混乱しないようにしてください。

今回は、訓練・テストデータの分割等は一切考慮せずに、予測結果にどんな違いがあるのかを見ていきましょう。

まずは、決定木による学習を行い、作成された機械学習モデルを用いて分類を行なった結果を表示してみます。

from sklearn.tree import DecisionTreeClassifier
treeModel = DecisionTreeClassifier(max_depth=3, random_state=0)
treeModel.fit(X, Y)
predicted = pd.DataFrame({'TreePredicted':treeModel.predict(X)})
data_predicted = pd.concat([data, predicted], axis =1)
data_predicted.head()

決定木

こちらの結果も先頭5行のみを表示しています。前回と同じ結果を確認できましたでしょうか。1行目で決定木の呼び出し、2行目でモデルの条件を指定しています。3行目で、教師データの学習を実行し、機械学習モデルを作成しています。

予測結果は、treeModel.predict(X)を実行することで、今回作成したtreeModelにおいて説明変数Xを予測した結果を取得できます。見やすくするために、元データに追加する形でデータを整えています。こちらでは先頭行のみを指定しましたが、データを確認されたい方は、headを外して、全データを見てみると良いでしょう。

続けて、ロジスティック回帰を用いた予測を行い、先ほどのdata_predictedに追加してみましょう。

from sklearn.linear_model import LogisticRegression
logisticModel = LogisticRegression()
logisticModel.fit(X, Y)
predicted = pd.DataFrame({'LogisPredicted':logisticModel.predict(X)})
data_predicted = pd.concat([data_predicted, predicted], axis =1)
data_predicted

ロジスティック回帰

手法は違いますが、使い方はこれまでの流れとまったく同じです。ここまでくると、だいぶ機械学習に慣れてきたと感じるのではないでしょうか。

1行目で機械学習ライブラリscikit-learn(sklearn)のなかから、LogisticRegression、つまりロジスティック回帰を呼び出しています。2行目でlogisticModelという名前でロジスティック回帰を使う宣言をしています。決定木の場合は、モデルの条件を指定しましたが、今回はすべてデフォルトのものを使用するので、指定せずに定義しています。3行目で、先ほど宣言したモデルに教師データを代入して、学習を実行し、機械学習モデルを作成しています。決定木のときと同様に、「モデル名.predict(予測に用いる説明変数)」で、予測値を抽出できるので、logisticModel.predict(X)を4行目で抽出し、LogisPredictedという列名で保存しています。5行目で先ほどのデータに、LogisPredicted列を追加しています。

データを上から順番に見ていくと、ロジスティック回帰では、一番上の北海道の予測が外れています。しかし、逆に宮城県においては、決定木では外れていますが、ロジスティック回帰の場合は当たっています。このように、ロジスティック回帰と決定木では、同じ教師データを用いているのにもかかわらず、予測結果に違いが出ていることがわかります。ではこの違いはどこにあるのでしょうか。まずは決定木手法について可視化を行いながら見ていきましょう。

決定木を紐解いていく

決定木は、最もきれいに1/0を分類する変数とその条件を見つけて、木構造状に分類を行なっていきます。今回の例では、たまたま教養娯楽、保険医療のみである程度分類が行えることが前回の結果からわかっています。では、教養娯楽、保険医療のデータを可視化してみましょう。

import matplotlib.pyplot as plt
%matplotlib inline
plt.scatter(data_predicted['保険医療'],data_predicted['教養娯楽'], c=data_predicted['大都市圏分類'])
plt.xlabel('Medical care')
plt.ylabel('Culture & recreation')

データの可視化

黄色が、大都市圏分類列における1、つまり大都市圏を含んだ都道府県になります。これを見ると、教養娯楽の値が高いものは、ほぼ大都市圏に分類できることがわかります。これは、前回の木構造で示した一番上の分岐そのものです。では、前回出力した木構造をベースに、決定木を見ていきましょう。

決定木による分類プロセス

決定木は、最もきれいに分割できる方法を探していきます。この場合、大都市圏であるClass1かどうかを最もきれいに分割する方法が、分岐1の教養娯楽が99.85以下かどうかです。99.85より大きい領域では、すべてClass1に分けられます。次に、保険医療が99.35以下かどうかでグラフの最も左側の領域をClass0として分けられます。さらに、保険医療が100.25より高い領域もClass0として分類しています。保険医療が100.25以下の領域は、Class0が4個、Class1が5個となり、精度が良い分類とは言えません。さらに階層を増やすことで、きれいに分割することはできますが、過学習に注意しなくてはなりません。

最後に、予測結果を可視化しておきましょう。

plt.scatter(data_predicted['保険医療'],data_predicted['教養娯楽'], c=data_predicted['TreePredicted'])
plt.xlabel('Medical care')
plt.ylabel('Culture & recreation')

決定木による分類結果

可視化は、先ほどとほぼ同じですが、色分けの指定にTreePredictedを与えています。これによって、決定木によって予測した分類結果を色分けして表示しています。この図を見ると、先ほどの分岐に基づいて分類されているのがわかります。

機械による分類プロセスを理解できましたでしょうか。比較的直感的で、場合分けによって細かく分岐していくのが決定木の分類プロセスです。そのため、保険医療が99.35以下、100.25より大きい部分はClass0というような飛び地のような条件を作り出してくれます。

ロジスティック回帰を紐解いていく

さて、続いてロジスティック回帰を紐解いていきましょう。こちらは、決定木ほど直感的ではないのですが、分割できる直線を引くというのは同じなので、頭の片隅に入れておいてください。まずは、決定木で使用した保険医療、教養娯楽の散布図をプロットし、ロジスティック回帰による分類をもとに色分けしてみましょう。

plt.scatter(data_predicted['保険医療'],data_predicted['教養娯楽'], c=data_predicted['LogisPredicted'])
plt.xlabel('Medical care')
plt.ylabel('Culture & recreation')

ロジスティック回帰による分類結果

色分けの変数にLogisPredictedを与えている以外は、先ほどとまったく同じです。これを見ると、決定木により分けられたものとは大きく違います。特に、決定木で表現できていた飛び地部分は見られず、大きくは上下に分割しているように見えます。ロジスティック回帰も決定木と同様に線を引く作業ではありますが、こちらは説明変数すべてを考慮した形で、分割に適した線を導き出します。これは、線形回帰をイメージすると良いでしょう。実は、ロジスティック回帰は、線形回帰の関数Y=aX1+bX2+zを0から1の範囲に押し込めてしまう関数を使用し、0/1の分類を行なっています。そのため、線形回帰のときと同様に、2変数ではきれいに表現できますが、今回のケースのように10変数ではイメージできません。そこで、2変数でロジスティック回帰を実行して、可視化してみましょう。

精度は一度考慮せず、このまま保険医療、教養娯楽を使っていきます。

X_logis = X[['保険医療','教養娯楽']]
logisticModel2 = LogisticRegression()
logisticModel2.fit(X_logis, Y)
predicted = pd.DataFrame({'LogisPredicted2':logisticModel2.predict(X_logis)})
logis_predicted = pd.concat([X_logis, predicted], axis =1)
logis_predicted.head()

2変数によるロジスティック回帰

1行目で、説明変数として保険医療、教養娯楽の2変数を取り出しています。2行目以降は、先ほどと同様に、ロジスティック回帰のモデル定義から学習を行なっています。最後に、今回の予測結果を可視化するために、データを整えています。

続いて可視化を行います。今回は、散布図に加えて、作成した機械学習モデルから算出できる分割線も表示してみます。

import numpy as np
plt.scatter(logis_predicted['保険医療'],logis_predicted['教養娯楽'], c=logis_predicted['LogisPredicted2'])
plt.xlabel('Medical care')
plt.ylabel('Culture & recreation')
a = logisticModel2.coef_[0,0]
b = logisticModel2.coef_[0,1]
z = logisticModel2.intercept_[0]
x = np.arange(97,104,1)
plt.plot(x,(-a*x-z)/b)

2変数ロジスティック回帰による分類結果

可視化を行うと、決定木と違い飛び地部分はなく、線によって上下に分割されています。1行目は、nupmyという数値計算用ライブラリをimportしています。2から4行目までは散布図の可視化で、色分けに関しては、2変数によって作成した機械学習モデルの予測結果を指定しています。残りが、今回のモデルから算出した分割線の可視化です。細かい数学的な説明は割愛しますが、線形回帰式のY = aX1+ bX2 + zをイメージし、Y=0として変形すると、8行目の式になります。a、b、zの値は、5から7行目で機械学習モデルから抽出しています。線形回帰のときと同様、このa、b、zが線を引くために必要な数値で、これらを教師データから算出することが線を引く(=学習)ことと同義です。

決定木のように条件分岐によって線を引いていくのではなく、あくまでも多変数の式を元に分割線を引くのがロジスティック回帰です。2変数であれば直線、3変数であれば分割する平面を書くことになります。これだけ聞くと決定木の方が、スマートに分割できるような錯覚に陥るのですが、ロジスティック回帰は、多変数を上手に扱えるため、とても有効な手法です。訓練・テストデータを分割して正確にモデル精度を検証しないと優劣はつけられませんが、今回作成した決定木とロジスティック回帰モデルにおける単純な正答率は、ほぼ同じ値を示しています。

さて、今回は、教師あり学習/分類に関して、前回よりもさらに一歩進んで、機械学習手法の違いを紐解いてきました。数学的な説明は割愛しましたが、手法の違いがどういったものなのかが直感的にイメージできましたでしょうか。今回取り上げた決定木やロジスティック回帰以外にも多くの手法が存在し、そこには必ず意味があります。それらの違いを理解し、データに合わせて適切に手法を選択していくのが重要です。少しずつさまざまな手法に挑戦し、その違いを紐解きながら理解を深めていくと良いと思います。

次回は、これまでの学びを活かしながら、複雑なデータを用いて機械学習に挑戦していきます。

著者プロフィール

下山輝昌
大手電機メーカーにて、ハードウェアの研究開発に従事した後、独立。独立後はソフトウェア、データ分析等において実務経験を積むとともに、数社を共同創業。その中でも合同会社アイキュベータでは、人工知能・IoTなどの可能性や方向性を研究している。最近では、オープンデータに着目し、オープンデータ活用のためのwebサービスの立ち上げ、オープンデータ×IoTによる価値創出を1つのテーマに取り組んでいる。