未来の数値を予測する!?AIの回帰分析を徹底解説!

回帰分析とは

回帰分析とはデータに基づいてある数値を予測するということをいいます。
データに基づかない予測はここでいう予測といいません。


データに関して

それではどういった、データが必要になってくるかというと例えば予測したい数値が、商品の売上であるなら、データはその商品の売上に「関係がありそうな」数値です。

商品がアイスクリームであれば、気温が高いのか低いのか、砂糖の量なのか、人の出入りの数なのかなど何か売上に関係してそうな情報値のことを指します。

専門用語

回帰分析において様々な専門用語を目にすることがあると思いますが、今必要なのは4つだけ、目的変数と説明変数。
連続的数値と離散的数値です。
一つずつ簡単に説明していきます。
目的変数とは、予測したい値(明日の売上など)
そして説明変数とは、予測に使うデータの値をいいます。
連続的数値とは、17000円、17001円、17002円のような字のごとく連続して並んでいる数値を言います。
気温などもそうで、21度の次が50度とはなりませんよね。
身長などもそうで、170mの次が180mとはなりません。

170.1mもあれば、170.0001mも存在します。
そして離散的数値というのは、サイコロの目や、電源のオンオフ、クリックをしたか、していないかなどです。
一般的に物事がはっきりと分けられていて、分類できる事象を数値化したものを指します。
YESかNOを数値化すると0か1、1か100にしてもいいです。
大事なのは数値と数値の間の境目がはっきりとしていて、それによって、どっちがどの分野なのかが明確になっていることです。
そして、回帰分析によって予測する数値は売上の予想のような連続する数値、離散的ではない数値を分析することをいいます。

簡単なアルゴリズム

回帰分析における基本的なアルゴリズムである、線形回帰について説明をします。
平易的ではありますが、ある程度内部の中身を知っておいたほうが、
応用が効くのではないかと思います。
線形回帰(LinearRegression)は線形、つまり直線で分類可能なデータの境界線を学習によって見つけていく計算方法です。

最初分類できる直線のあたりをつけてから、
損失関数や最小勾配法などと言った関数を使っていきながら
一番最適な分類方法をとる直線式つまりY=aX+bを求めていきます。

回帰分析を使ったAIのプログラミング方法が学べるAIエンジニア向けセミナーはこちら

手を動かす

ある程度、回帰分析を使って未来の数値を予測するということが
どういうことなのか見えてきたところで実際の具体的な例を混じえて、数値予想のモデルを作成していきましょう。
手を動かしながら実際の数値を見ていったほうが、ただ受動的に理論を学ぶより遥かに理解が深まります。


Scikit-Learn

今回は簡単にインストールできて、すぐに機械学習などに必要な
データセット、アルゴリズムなどが利用できる便利なライブラリ、Scikit-Learnを使います。
Python環境が整っているなら、pipを使ってコマンドライン上一発でインストールできます。

Scikit-learnとは?5分で分かるScikit-learnのメリットや機能まとめ


ボストンの住宅価格を予想

それでは実際に回帰分析をしていきます。
使用するデータセットは、Scikit-Learn標準装備のBoston house prices dataset(ボストンの住宅価格)です。

ライブラリをインポート

必要なライブラリをインポートしていきます。
尚今回使用するエディターはJupyter Notebookです。

import numpy as npimport matplotlib.pyplot as plt import pandas as pd  import seaborn as sns %matplotlib inline

データセットをインポート

続いて、データセットをインポートしていきます。

from sklearn.datasets import load_bostonboston_dataset = load_boston()

データセットの中身

まずどんなデータセットにどんな値が入っているのかを見ていきます。

print(boston_dataset.keys())

出力結果

dict_keys(['data', 'target', 'feature_names', 'DESCR'])
data様々な住宅の情報が入っている(説明変数)
target住宅価格(目的変数)
feature_names説明変数の列名
DESCRこのデータセットの説明

 

pandasを使って、テーブル表記にし、何が入っているかを見やすくしましょう。

boston = pd.DataFrame(boston_dataset.data, columns=boston_dataset.feature_names)boston.head()

出力結果

feature_namesに入っている列名の説明

CRIM人口1人あたりの犯罪発生率
ZN25,000平方フィート以上の住居区画の占める割合
INDUS小売業以外の商業が占める面積の割合
CHASチャールズ川によるダミー変数(1:川の周辺、0:それ以外)
NOXNOXの濃度 –> NOXとは、排ガスや工場設備などから発生し,大気汚染の原因となる。
窒素酸化物の総称。
RM住居の平均部屋数
AGE1940年より前に建てられた物件の割合
DIS5つのボストン市の雇用施設からの距離(重み付け済)
RAD環状高速道路へのアクセスしやすさ
TAX$10,000 ドルあたりの不動産税率の総計
PATRATIO町毎の児童と教師の比率
B町毎の黒人 (Bk) の比率を次の式で表したもの。
1000(Bk – 0.63)^2
LSTAT給与の低い職業に従事する人口の割合 (%)

回帰分析で重要なデータの設定

上のリストにて、2点、回帰分析において重要な元データの設定用語がでてきたので説明します。

ダミー変数

ダミー変数とはカテゴリー型のデータを0か1で表現し直す変数のことです。
上の例でいうと、CHAS列にはチャールズ川の周辺かそれ以外というカテゴリー分けがなされています。
そして、チャールズ川の周辺であれば1にして、それ以外は0という「数値」に直します。
例えば曜日をダミー変数にする場合。
月曜日から日曜日までを0から6にして、そこから列名として月曜日から日曜日に直し、月曜日であれば1、そうでないなら0にします。
同様に火曜日であれば1、と順次直していきます。

曜日番号

月曜日0
火曜日1
水曜日2
木曜日3
金曜日4
土曜日5
日曜日6

さらに変換する

インデックス番号月曜日火曜日水曜日木曜日金曜日土曜日日曜日

01000000
10100000
20010000
30001000
40000100
50000010
60000001

重み付け

続いては重み付けです。
「重み」を簡単に説明すると貢献度、信頼度、評価の度合いです。
このデータセットで「重み」がつけられているのは「距離」です。
距離には様々な測定法があり、地形、勾配などが考慮されます。
その考慮された中に「信頼性」の高い測定方法、測定基準が存在します。
その「信頼度」こそが「重み」あり、一つの距離測定に対して、「重み」が違う値同士を
その測定の重みを考慮した加重平均で計算し、最確値として導き出した値が、所謂「重み付けされた値」です。

目的変数を取り出す

続いては予測したい住宅価格をデータセットから取り出し、データフレームに加えます。

boston['MEDV'] = boston_dataset.target

回帰分析で重要なデータの前処理

続いて欠損値です。
欠損値とは何らかの理由で、データが取れなかった値などを指し、これが入っていると学習精度が下がります。
これらを取り除いていく作業も重要です。

boston.isnull().sum()

幸いに、今回のデータセットでは欠損値はないようです。
欠損値を探す他のやり方としては、info()メソッドを使うなどがあります。
実行すると下の画像の赤枠部分に情報がでます。

boston.info()

回帰分析を使ったAIのプログラミング方法が学べるAIエンジニア向けセミナーはこちら

回帰分析でもっとも重要な元データの分析

続いて、回帰分析において、もっとも重要であるデータの分析をおこなっていきます。
ここでは、目的変数と他の特徴とでどんな関係性があるのかをいくつかグラフにして、確認していきます。
まずは目的変数をグラフにしてみます。

# figuresizeは描写するグラフの画面サイズです。sns.set(rc={'figure.figsize':(12,9)})# ヒストグラムを表示させます。binsはX軸のメモリの細かさです。sns.distplot(boston['MEDV'], bins=60)plt.show()

ほんの少しバラけていますが、正常に分布しているようです。
続いて、PandasのCorrメソッドで相関行列を作り、
それをヒートマップにして、2つの値の相関関係を調べていきます。

# 相関行列を作ります。round(2)は小数点以下をどれぐらい残して表示するかです。correlation_matrix = boston.corr().round(2)# annotをTrueにすると数値をグラフ内に表示してくれます。sns.heatmap(data=correlation_matrix, annot=True)

この図にある一つ一つの値は1から−1までの幅があり、
1に近いほど、強い正の相関があり、−1に近いほど、強い負の相関があります。

データの特徴選択

回帰モデルの学習の精度をあげるために特徴選択に挑戦しましょう。
まずは目的変数(MEDV)と高い相関性をもつ特徴を探しましょう。
さっと見渡してみるとRMはMEDVと強い正の相関性(0.7)をもっています。
そしてLSTAT はMEDVと強い負の相関性(-0.74)をもってるといえます。

特徴選択の注意事項

もう一つ、特徴選択で気をつける事はマルチコ(多重共線性)を確認することです。
マルチコ(多重共線性)とは、とどのつまり、お互い強い相関関係をもった説明変数同士のことです。
こういった説明変数同士を一緒にしてしまうと、正しく回帰モデルの学習ができなくなってしまうため、
これらをすべて学習モデルに入れてはいけません。
それを踏まえた上でもう一度ヒートマップをみてみると、
RADとTAXは0.91ポイント。この2つは互いに強い相関性があります。
そして、DISとAGEも同じように相関性が近いのでどちらか一つを省く必要があります。

散布図にトライ

特徴選択の内容がなんとなく掴めたと思います。
そこで、散布図を使って相関関係というものがどうような状態か目で見て確認しておきましょう。
それでは目的変数(MEDV)と強い相関を示した、RMとLSTATの特徴がどうような関連性をもっているかグラフで見てみましょう。

# グラフの大きさを指定するplt.figure(figsize=(20, 5))# 2つの特徴に1つの目的変数をつかう。features = ['LSTAT', 'RM']target = boston['MEDV']# 2つのグラフを1ページで表示するため# For文を使い、一つずつグラフ作っていく。for i, col in enumerate(features): plt.subplot(1, len(features) , i+1) x = boston[col] y = target plt.scatter(x, y, marker='o') plt.title(col) plt.xlabel(col)plt.ylabel('MEDV')

相関関係の説明

左側はLSTAT、給与が低い人たちの割合が高かくなるほど、負の相関になる。
つまり住宅価格は下がっている。
逆に右側、RM、部屋の数が多いほど、正の相関になる。
つまり住宅価格は上がっている。

住宅価格予想

いよいよ回帰モデルを機械に学習させて住宅価格を予測させていきます。
学習に邪魔なノイズ的な特徴を排除して、強い相関性をもつLSTATとRMのみを使って学習モデルを作ります。

# numpy concatenateを使いリストを結合させます。# 新たに列名を指定して、Xつまり説明変数とします。X = pd.DataFrame(np.c_[boston['LSTAT'], boston['RM']], columns = ['LSTAT','RM'])# もちろんY、目的変数には住宅価格を入れます。Y = boston['MEDV']

過学習を避ける

ここで回帰分析においてもう一つ気をつけなければならない厄介者がいます。
それは過学習(Overfitting)と言って、手元にあるデータ全てを使ってしまい、未知のデータに対応できなくなってしまった学習モデルを指します。
その過学習を避けるために、もっとも手っ取り早いのが学習データを8対2程度の割合で分けて、
学習用と検証用にして、先に学習用で学習を行い、
検証用を擬似的に未知のデータとして使用して様子を見て、精度を確認する方法です。
そのためにScikit-Learnに用意されている便利な関数、train_test_splitを使います。

# train_test_splitをインポートします。from sklearn.model_selection import train_test_split# テストサイズを2割にして、Random Stateは5# つまり、乱数の種に5を指定して、乱数を生成させるという意味。# 疑似乱数を固定することにより、ランダムではあるが、再現性があるため# 機械学習におけるランダム設定には欠かせない。# なぜなら、学習結果がランダムにしたから変わったのか、判別がつかなければ、# 学習の検証にならないから。X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size = 0.2, random_state=5)print(X_train.shape)print(X_test.shape)print(Y_train.shape)print(Y_test.shape)

 

出力結果

(404, 2)(102, 2)(404,)(102,)

学習と検証

さあ、いよいよ大詰めです。Scikit-Learnの回帰アルゴリズム
LinearRegressionを使って学習用と検証用の回帰モデルを作っていきましょう。

from sklearn.linear_model import LinearRegression# 学習用モデルの箱を作ります。lin_model = LinearRegression()# トレーニング開始です。lin_model.fit(X_train, Y_train)

学習モデルの評価

学習が終わったら、きちんと精度がでているかを、
2つの回帰分析の精度評価指標を使って調べてみましょう。

# Root Mean Squared Error (RMSE) 関数from sklearn.metrics import mean_squared_error# R2 (決定係数) の計算関数from sklearn.metrics import r2_score# 学習用の目的変数の予測値を出す。y_train_predict = lin_model.predict(X_train)# Root Mean Squared Error (RMSE) 関数でRMSEの値を算出。rmse = (np.sqrt(mean_squared_error(Y_train, y_train_predict)))# R2 関数でR2の値を算出。r2 = r2_score(Y_train, y_train_predict)print("学習用モデル成果")print("--------------------------------------")print('RMSE の値は {}'.format(rmse))print('R2 スコアは {}'.format(r2))print("\n")# 検証用のモデルと評価値を作成。y_test_predict = lin_model.predict(X_test)rmse = (np.sqrt(mean_squared_error(Y_test, y_test_predict)))r2 = r2_score(Y_test, y_test_predict)print("検証用モデル成果")print("--------------------------------------")print('RMSE の値は {}'.format(rmse))print('R2 スコアは {}'.format(r2))

Root Mean Squared Error (RMSE)

2つの回帰分析の精度評価指標のうち1つ目です。
こちらは平均化された誤差の値を表します。
0に近いほど予測精度が高いことを表します。

R2 (決定係数)

R2 (決定係数)は1に近いほど精度の高いことを表します。

学習用と検証用とではさほど数値の開きは見られませんでしたが、
どうやら精度があまりよくないみたいです。特にRMSEの値が悪いです。
これらを改善するには、特徴量を増やしたり、アルゴリズムを変えるなどといった工夫が必要です。
(今回は、全体の流れを理解していただくため、改善の作業は行いませんでした)

終わりに

最後に、実際にこの学習済みモデルによって予測した数値を確認します。
実は上のコードで既に求めていたので、後はそれを見るだけです。

# 学習用の目的変数の予測値。y_train_predict = lin_model.predict(X_train)print("学習用モデル成果")print("--------------------------------------")print('学習用モデル予測値の数値 {}'.format(y_train_predict))print("\n")# 検証用の目的変数の予測値。y_test_predict = lin_model.predict(X_test)print("検証用モデル成果")print("--------------------------------------")print('学習用モデル予測値の数値 {}'.format(y_test_predict))print("\n")

学習に使用したデータを、学習済みモデルに予測させた出力数値

検証用に取っておいたデータを、学習済みモデルに予測させた出力数値

このままでは分かりづらいので、グラフ化して比較してみます。

# 分かりにくいのでグラフ比較print("学習用モデル成果")print("--------------------------------------")# figuresizeは描写するグラフの画面サイズです。sns.set(rc={'figure.figsize':(12,9)})# ヒストグラムを表示させます。binsはX軸のメモリの細かさです。sns.distplot(y_train_predict, bins=60)plt.show()print("検証用モデル成果")print("--------------------------------------")sns.set(rc={'figure.figsize':(12,9)})sns.distplot(y_test_predict, bins=60)plt.show()# 元のデータprint("本来のデータ")print("--------------------------------------")sns.set(rc={'figure.figsize':(12,9)})sns.distplot(boston['MEDV'], bins=60)plt.show()

学習に使用したデータを、学習済みモデルに予測させた出力数値のグラフ

検証用に取っておいたデータを、学習済みモデルに予測させた出力数値のグラフ

元のデータのグラフ

精度が良いモデルができていると、元のデータのグラフと近いグラフの形が予測結果のグラフとして表示されますが、あまりうまくいっていないことがわかります。
特徴量を増やす、データ集約をすると言ったデータの前処理と、線形回帰以外の機械学習アルゴリズムを利用するなどの2つの側面から試行錯誤をしていく必要があります。

AI初心者におすすめのセミナー

自分でAIのことを学ぼうにもAIの作り方が全く分からない!AIの仕組みやプログラミングの基礎も知らないからどこから手をつけたらいいかわからない!なんて時もあると思います。
独学があまり好きじゃない、上手くいかないと言う人は手っ取り早くAIの講座を受けてしまうのもおすすめです!
AIは一見初心者向けの講座なんてなさそうですが、全くAIが分からない人でも受けれる講座があるんです!
私のイチオシのAI講座は…

こちらの3つが主におすすめのAI講座になっています!

どのセミナーも初心者向けで、AIが全く分からなくても受けられる講座とのことなので安心です。
しかも最後には資格が取れるほどの経験までさせてくれるので、初心者から成りあがるにはセミナーが一番手っ取り早いです。
この機会にセミナーを受講してみてはいかがでしょうか?

最後まで長文にお付き合い頂き、ありがとうございました。

最新情報をチェックしよう!
企業向けAI人材育成サービス

企業向けAI人材育成サービス

AI事業発足やAI導入に必要な人材育成のステップとAI研究所が提供するサービス。AI研究所の人材育成サービスでは、3つのステップを軸に御社の業務内でAIを活用できる人材育成やAIプロジェクトの支援を行います。

CTR IMG