【簡単・お手軽】AI講座07.単回帰分析 <Python実装編>|Pythonで始める人工知能入門講座

AI講座07-480x360
AI開発入門講座

この記事の執筆・監修

キノコード
キノコード

テクノロジーアンドデザインカンパニー合同会社のCEO。
日本最大級のプログラミング教育のYouTubeチャンネル「キノコード」や、プログラミング学習サービス「キノクエスト」を運営。
著書「あなたの仕事が一瞬で片付くPythonによる自動化仕事術」や、雑誌「日経ソフトウエア」や「シェルスクリプトマガジン」への寄稿など実績多数。

挨拶&はじめに

こんにちは、kinocodeです。
前回の動画、Excelを使って単回帰分析をする動画はご覧いただけましたか。
前回の動画では、Excelを使って単回帰分析を行いました。
Excelでやったら単回帰分析でやっていることの理論の理解が深まったのではないでしょうか。
今回の動画では、Pythonを使って単回帰分析を行っていきます。
Excelよりずっと簡単に単回帰分析をすることができます。
Pythonの便利さをご理解いただけると思います。
Pythonで単回帰分析を行う方法はいくつもあります。
今回はその中から、2つの方法をご紹介します。
1つ目は、Seabornを使用した方法です。
2つ目は、Numpyを使用した方法です。
詳しくはレッスンには説明いたします。

キノコードでは、人工知能のレッスンの他に、データをグラフにするレッスン、データ集計・加工に関するレッスン、Pythonを使った仕事の自動化のレッスン、SQLのレッスンなどを配信しています。
他にも、これからはWebアプリケーション開発の動画なども配信していく予定です。
新着通知がいきますので、ぜひチャンネル登録をお願いします。
それでは、レッスンスタートです。

ボストンの住宅価格データセットの読み込み

import pandas as pd
from sklearn.datasets import load_boston

bs = load_boston()
df = pd.read_csv(bs.filename, header =1)
df

それでは、前回のレッスン同様、ボストンの住宅価格のデータをPandasのデータフレームに読み込ませましょう。
実行します。
データを読み込めました。
前回の動画を見ていない人のために、データセットについて少し説明します。
このデータセットは、ボストンを506の区画に分けた各区画のデータが入っています。
各区画に関するデータとは、その区画の犯罪率や住宅価格などです。
データの各項目に関する詳しい情報を知りたい方は、print関数で、bs.DESCRと書いて実行してみてください。
このデータセットに関するリファレンスが表示されます。
このデータセットを、住宅価格を目的変数、それ以外を説明変数として使用します。
つまり、住宅価格を色々なデータで予測するために使用します。
前回のレッスンでは、住宅価格を目的変数、部屋数を説明変数として単回帰分析を行いました。
つまり、部屋数が多ければ、住宅価格があがりそうという経験に基づいて説明変数を選びました。
表示されているデータフレームの列名だと、MEDVが住宅価格のデータ、RMが部屋数のデータです。

print(bs.DESCR)

散布図行列・相関行列から説明変数を選ぶ

import seaborn as sns
sns.pairplot(df)

しかし、Seabornを使用すれば、全てのデータを眺めてから説明変数を選ぶことができます。
実際にやってみましょう。
まず、Seabornをsnsという名前で使用できるようにインポートします。
次に、pairplotメソッドを使用して全てのデータの散布図を表示させます。
sns.pairplot丸括弧。丸括弧の中に、ボストンデータが入ったデータフレームdfを渡します。
実行します。
全てのデータの散布図を表示できました。
このように、pairplotメソッドは、引数の全てのデータ同士の散布図を表示してくれるメソッドです。
行列で散布図が表示されているのものを、そのまま散布図行列と言ったりします。
散布図行列の見方を説明します。
縦軸、横軸にはそれぞれ、与えられたデータのカラム名が書かれています。
縦軸の一番下には、MEDV、つまり、住宅価格の散布図が並んでいます。
横軸の一番左のデータ名が、CRIMなので、区画一人当たりの犯罪発生率が横軸となった時の散布図が表示されています。
犯罪は、少ない方が、住宅価格は高くなりそうですよね。
確かに、横軸の値が0に近いほど縦軸、住宅価格は高くなっていることが読み取れます。
なお、一番右下は、縦軸と横軸が同じデータ、MEDVが来るので、ヒストグラムで表示されています。
これは、他のデータ同士も同じで、全ての散布図の左上から右下に向けての対角方向にはヒストグラムが並ぶことになります。
このように、全てのデータ同士の散布図が並んで表示されているのが、散布図行列です。
散布図行列を使用すれば、視覚的に相関がありそうなデータを説明変数として選ぶことができます。
また、とりあえず、全体のデータの傾向を見たい時などにも非常に便利です。

df.corr()

また、Pandasのcorr()メソッドを使用すれば、全てのデータ同士の相関係数を求めることができます。
ボストンデータが入っている、df.corr丸括弧と書きます。
実行します。
各データ同士の相関係数が出されました。
このように、相関係数が並んだ行列も、そのまま相関行列といいます。
このように、corr()メソッドと先程のpairplotを使用すれば、pairplotでデータを視覚的に見ることができ、相関係数をデータでも確認する作業が一瞬で行えます。
Excelも便利ですが、Pythonも便利ですよね。
さて、ここで先程、正の相関がありそうだとお話をした、住宅価格MEDVと部屋数RMの相関係数を確認します。
0.695...とやはり、住宅価格に対する正の相関係数としては、全てのデータの中で一番高くなっています。
このように、散布図行列と相関行列を組み合わせれば、単回帰分析の説明変数としてよさそうなものを選ぶことができます。

Seabornを使った単回帰分析

#データの散布図を描く
sns.regplot(x = df['RM'], y = df['MEDV'], fit_reg=False)

それでは、ここから、単回帰分析をpythonで行う方法を解説していきます。
1つ目は、Seabornを使用したやり方です。
まずは、先程、単回帰分析を行うのに良さそうだと判断した、住宅価格と部屋数の散布図を表示してみます。
Seabornで、散布図を表示するには、いくつか手法がありますが、ここではregplotメソッドを使用します。
snsと書いて、ドット、regplot丸括弧。
エックスと書いて、イコール、横軸になる、部屋数のデータを渡します。
dfと書いて、角括弧、RMをシングルクォーテーションで括り、角括弧を閉じます。
カンマを書いて、yイコール、縦軸になる、住宅価格MEDVの列を取り出して渡します。
最後に、fit_reg=Falseと書き、かっこを閉じます。
実行します。
散布図が表示されました。

#単回帰分析を行う
sns.regplot(x = df['RM'], y = df['MEDV'], fit_reg=True, ci = None)

それでは、Seabornで単回帰分析をおこないます。
Seabornで回帰直線を引くには、先ほどと同じregplotメソッドを使用します。
書き方は、2つ目の引数まで同じです。
3つ目の、fit_reg=Flaseの部分をTrueに変えます。
先程、解説はしませんでしたが、この3つ目の引数が、回帰直線を表示するかどうかの引数です。
ただし、regplotメソッドでは、この引数はデフォルトでは、Trueなので、書かなくても回帰直線は表示されます。
そして、最後の引数をci = Noneとしましょう。
これは、信頼区間と呼ばれるものを表示するかどうかの引数です。
今は、回帰直線のみを表示させたいので、信頼区間を表示しないようにNoneを渡しました。
実行します。
回帰直線を引くことができました。
この、Seabornを使った回帰分析には、欠点があります。
それは、回帰直線のw0とw1の係数を数字として出力することができないということです。
もしかしたら、Seabornでも出力する方法はあるのかもしれません。
ですが、私が調べた範囲では、わかりませんでした。
ここで補足ですが、w0、w1とは、機会学習の分野風に、直線の方程式の係数を置き換えたものです。

Numpyを使った単回帰分析

import numpy as np
import matplotlib.pyplot as plt
plt.scatter(df['RM'], df['MEDV'])

それでは、続いて、Numpyを使用した単回帰の手法を説明します。
まずは、Numpyをnpという文字で使えるようにインポートします。
また、可視化のライブラリとして、matplotlibのpyplotも、pltという名前で、使えるようにインポートします。
散布図は、matplotlibのscatterで表示して見ましょう。
pltと書いて、ドット、scatter、かっこ、1つ目の引数に、横軸のデータ、2つ目の引数に、縦軸のデータを渡します。
こちらも、先程同様、データフレームから、必要な列のデータを指定して引数として渡しています。
実行します。
散布図が表示されました。

#2つ目:numpyのpolyfitを使用した場合
x = df['RM']
y = df['MEDV']
w1, w0 = np.polyfit(x, y, 1)
print(w0, w1)

それでは、ここから、単回帰分析を行っていきます。
まず、「x」という変数に、説明変数になる、部屋数の数のデータを入れます。
続いて「y」という変数に、目的変数になる、住宅価格のデータを入れます。
そして、次に、Numpyのployfitを使って、w0とw1、つまり回帰直線の係数を求めます。
ployfitは、1つ目の引数に、説明変数のデータ、2つ目の引数に、目的変数のデータを渡します。
そして、3つ目の引数に、近似する多項式の次数を渡すことで使えます。
また、現在求めたい直線の次数は、1なので、今回は、1という引数を渡します。
ployfitは、回帰直線の係数を求めるものなので、返り値は2つです。
返り値の受け取り方は、返り値を受け取りたい変数をカンマで区切り、2つ書いておくことです。
w1、w0と書いて=np.ployfit()、先程データを入れた、xとy最後に、直線の次数である1を渡します。
返り値が何になっているか見るために、プリント関数で、w0、w1の値を表示してみましょう。
実行します。
回帰直線の係数となる、w0とw1を計算できました。

fx = w0 + w1 * x 
fx

それでは、求めた係数から、回帰直線の数式を作ります。
直線の数式は、機械学習の分野では、y = w0 + w1 x でした。
ですが、yはすでに変数として使用しています。
ですので、混乱をさけるために、今回は、yの部分を関数の表記としてよく使用される、fxとしています。
fx = w0 + w1
x と書きます。
fxの中身を見るために、最後にfxと書きます。
実行します。
求めた係数から、回帰直線のfxの値を求めることができました。
これは、回帰直線から予測された住宅価格の予測値とも言い換えることができます。

plt.scatter(df['RM'], df['MEDV'])
plt.plot(x, fx)

この求めた、回帰直線を、先程の散布図と重ねて表示したいと思います。
散布図の部分は先程と同じです。
次に、直線を引きたいので、プロットを使用します。
plt.plot丸括弧、1つ目に横軸となるエックスを渡します。
2つ目に先程求めた、回帰直線のyの値、fxを渡します。
実行します。
Seabornの時と同じように、散布図と回帰直線を表示できました。

sns.regplot(x = df['RM'], y = df['MEDV'], fit_reg=True, ci = None)
plt.plot(x, fx)

確認のために、SeabornとNumpyで求めた回帰直線を重ねて表示してみたいと思います。
Seabornの回帰直線のコードをコピペします。
Numpuの方も同じく、プロットで回帰直線を引くコードをコピペしてきます。
実行します。
2つの回帰直線が重なっています。
どちらの手法で求めた回帰直線もあっていそうですね。  

決定係数を求める

#決定係数を求める
from sklearn.metrics import r2_score

#yの現実の値のデータを作成
y_true = df['MEDV']

それでは、最後に決定係数を求めたいと思います。
決定係数を求める方法もいくつか考えられますが、ここでは、サイキットランを使用して求めます。
sklearnのmetricsから、r2_scoreを使えるようにします。
この、r2_scoreで決定係数を求めるには、引数が2つ必要です。
その必要な引数とは、1つは、与えられた目的変数のデータです。
実際に観測されている値なので、実測値とここでは呼ぶことにします。
2つ目は、回帰直線で予測された、目的変数のデータです。
ここでは、そのまま、予測値と呼ぶことにします。
今回の実測値のデータは、住宅価格、MEDVなので、そのデータをデータフレームから取り出します。
実測値なので、y_trueという変数に、住宅価格の部分を代入します。
実行します。

#yの予測値データを作成
x = df['RM']

#yの予測値は w0 + w1 * x にxを与えた時の値
y_pred = w0 + w1 * x

次に予測値のデータを作成します。
説明変数を変数xに代入しておきます。
予測値のデータは、回帰直線の式から作成します。
作成方法は、先程のfxの時と同様です。
ここでは、予測値なので、予測値の変数名としてよく使用されるy_predを使用しています。

#決定係数の値
r2_score(y_true, y_pred)

それでは、決定係数の値を求めます。
r2_score、かっこ、引数として、実測値のデータと予測値のデータを渡します。
実行します。
決定係数が求められました。

df.corr().loc['RM','MEDV']

決定係数は、相関係数の2乗の値でした。
相関係数は先程、Pandasのcorr()で求められることを紹介しました。
Pandasのcorr()で求めた、住宅価格と部屋数の相関係数を2乗して、求めた決定係数と同じ値になるか確認して見ましょう。
dfと書いて、.corr()、データフレームから特定の値を取り出すために、locを使います。
locでは、列名と行名から特定の値を取り出すことができます。
実行します。
住宅価格と部屋数の相関係数の値を取り出せました。

corr = df.corr().loc['RM','MEDV']
corr ** 2

さらにこの相関係数を、corrという変数に代入します。
corr、イコール、先程の相関係数を取り出したコードを書きます。
最後にこの、corrを2乗します。
pythonで、2乗は、アスタリスク2つです。
実行します。
先程、r2_scoreで求めた決定係数と同じになりました。

エンディング

人工知能レッスン7、単回帰分析、「python実装編」お疲れ様でした。
このレッスンで、人工知能、単回帰分析のレッスンは全て終了となります。
単回帰分析、「ゼロからわかる理論編」で、説明しましたが、単回帰分析は、データ分析では基本的な分析手法です。
一見簡単に見えますが、しっかりと理解するのは難しかったのではないでしょうか。
私自身、この人工知能レッスンをするにあたってかなり勉強しました。
動画にする関係上、ある程度綺麗に見えるようにまとめているつもりです。
ですが、まだまだ説明できていない部分、私自身の理解が追いついていない部分もあります。
これからも、みなさんと一緒に勉強できれば嬉しいです。
それでは次のレッスンでお会いしましょう。