6. 線形回帰分析

6.1. はじめに

6.1.1. 開始前に行うこと(重要)

まず,Chrome 等のブラウザを利用して,本教材の URL にアクセスし,画面の指示に従い Google アカウントにログインしてください.その後,ブラウザ表示画面左上の「ファイル」をクリックし,さらにポップアップで出てくる項目から「ドライブにコピーを保存」をクリックしてください.これにより,本教材のコピーが自分のGoogleドライブに保存され,自分で書いたプログラムを実行できるようになります.

また,多くのセルが非表示になっていると思われるため,同じくブラウザ表示画面上の「表示」をクリックし,さらにその項目から「セクションを展開」をクリックし,非表示のセルを表示させてください.

Hint

各ページの上部にロケットのアイコン があるのでこれをクリックして各ページのファイルを Google Colaboratory 上で開いて利用してください.

6.1.2. 到達目標

scikit-learn を利用して線形回帰分析をする方法を身に着けることを目標とします.

6.1.3. scikit-learn とは

scikit-learn とは Python で機械学習を行うためのライブラリです.機械学習という初学者の人は身構えてしまうかもしれませんが,この講義で行うことは線形回帰です.scikit-learn は線形回帰法を実装するためだけに利用するものなので気楽に取り組んでください.

Note

線形回帰法も機械学習法のひとつと考えることもできます.

6.1.4. scikit-learn のインポート

scikit-learn で線形回帰を実行するための方法は以下のようにインポートします.

from sklearn.linear_model import LinearRegression

一緒に利用する他のライブラリもインポートしておきましょう.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
sns.set()

6.1.5. 学習の進め方

上から順に読み進み,【実習】と書いてある箇所でコードを書いて実行してください.基本的に入力するコードの前に見本のコードが書かれており,見本と同じコードを書けば正しく動作するようになっています(見本コードの上下に入っている区切り線は入力する必要ありません).理解を深めるには,見本とは異なるコードを書いて試してみることも役立つと思います. なお, Colab では,コードが書かれている領域をコードセル,説明文等が書かれている領域をテキストセルといいます.

6.2. scikit-learn の基本操作

6.2.1. データの準備

いくつかの地方の1月の気象データを利用する.

【実習】データを読み込む.

#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#
name = ["hachinohe", "sendai", "tokyo", "osaka", "naha"]
latitude = [40.512449, 38.268201, 35.689634, 34.686246, 26.212378]
longitude = [141.48862, 140.869426, 139.692101, 135.519865, 127.679316]
sunshine = [141.3, 158.4, 206.1, 172.7, 74.9]
rainfall = [14, 50, 48.5, 51.5, 150.5]
under0 = [28, 26, 13, 8, 0]
over30 = [0, 0, 0, 0, 0]
max_temp = [9.3, 12.2, 16, 14.9, 24.1]
min_temp = [-9.6, -6.7, -4, -2.5, 9.3]
jan = pd.DataFrame(
    {"name" : name, "latitude" : latitude, "longitude": longitude, "sunshine" : sunshine,
     "rainfall" : rainfall, "under0" : under0, "over30" : over30, "max_temp" : max_temp, "min_temp" : min_temp})
jan
#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#

6.2.2. データの概要確認

【実習】1月の気象データについて基本統計量を計算する.

#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#
jan.describe()
#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#

【実習】1月の気象データについて相関行列を求める.

#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#
jan.corr(numeric_only=True)
#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#

【実習】緯度と最高気温に関して散布図を作成する.

#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#
import matplotlib.pyplot as plt
plt.scatter(jan["latitude"], jan["max_temp"])
plt.xlabel("latitude")
plt.ylabel("max temp")
plt.title("Jan. 2018")
plt.show()
#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#

6.2.3. 線形回帰の計算

ここでは,線形回帰法を用いて,緯度から最高気温を求める関数を作ります.scikit-learnの線形回帰の関数を使用します.説明変数の指定の仕方がやや特殊なので注意が必要です.

Hint

df["列名"]でなく,df[["列名"]]とします.df["列名"]とするとSeriesというデータ構造でデータ取り出されるが,今回は1列からなるDataframeをライブラリに渡す必要があるため,このような書き方になります(df[リスト]と指定するとデータフレームが返されます).

【実習】緯度情報だけからなるDataframeを作成する.

#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#
jan[["latitude"]]
#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#

【実習】最高気温の情報を取り出す(こちらは通常どおりDataframeから1列を取り出す).

#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#
jan["max_temp"]
#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#

【実習】緯度から最高気温を予測する線形関数を作る.

Hint

  • つまり最高気温 = a * 緯度 + bという関数を作り,a,bを求めます.

  • scikit-learn LinearRegressionのfit()関数を使用して学習します.

  • 学習後,説明変数の係数aがmodel.coef_に,切片bがmodel.intercept_に格納されます(説明変数が複数指定されることもあるので,model.coef_はリストになっています.

#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(jan[["latitude"]], jan["max_temp"])
aa = model.coef_
b = model.intercept_
print("aa = ", aa)
print("b = ", b)
#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#

【実習】八戸(緯度=40.512449)での最高気温の予測値を求める(自分で計算する).

#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#
aa[0] * 40.512449 + b
#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#

【実習】predict()関数を使って八戸(緯度=40.512449)の最高気温の予測値を求める.

Note

リストに複数の入力を入れると,各入力に対する予測値を計算してくれます.各入力値はリストで指定されます.

#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#
model.predict([[40.512449]])
#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#

【実習】predict()関数を使って仙台(緯度=38.268201)と那覇(緯度=26.212378)の最高気温の予測値を求める.

#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#
model.predict([[38.268201], [26.212378]])
#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#

【実習】学習した直線を描画する.

Hint

各都市の緯度(jan["latitude"])に対する最高気温の予測値(model.predict(jan[["latitude"]]))を計算し,それらを直線でつなぎます.

#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#
plt.scatter(jan["latitude"], jan["max_temp"])
plt.plot(jan["latitude"], model.predict(jan[["latitude"]]), "red")
plt.xlabel("latitude")
plt.ylabel("max temp")
plt.title("Jan. 2018")
plt.show()
#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#

【実習】一関(緯度=38.93469)の最高気温を予測する.

#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#
model.predict([[38.93469]])
#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#

Note

実際は10.6度でした.

Note

終わりです.