覚え書きブログ

scikit-learnを用いた機械学習(Pythonの基礎 3/4)

<< scikit-learnを用いた機械学習(Pythonの基礎 2/4)

参考書

本ブログの内容の詳細は、「機械学習スタートアップシリーズ ゼロからつくるPython機械学習プログラミング入門」に掲載されています。
機械学習に必要な数学の復習から、機械学習アルゴリズムの導出およびPythonの基本ライブラリのみを用いた実装方法まで学びたい方は、本書籍をご活用ください。
bookclub.kodansha.co.jp



pdbを用いたデバッグ

※jupyter notebookとGoogle Colaboratoryでは動作しません。
pdbモジュールをインポートし、スクリプトの任意の行に「pdb.set_trace()」を設置し実行すると、その行で処理を止めてデバッグをすることができます。

# デバッガをインポート
import pdb

pdb.set_trace()

以下のように、「pdb.set_trace()」を設置したコードを「pdb_example.py」という名前でファイルに保存し、powershell上で実行してみましょう。

import numpy as np
import pdb

price = np.array([120,180,300,150])

pdb.set_trace()

price += 100

print(f"和={np.sum(price)}")
print(f"平均={np.mean(price)}")
print(f"分散={np.var(price)}")
print(f"標準偏差={np.std(price)}")

以下のようにPdbのコンソールがでます。

> python pdb_example.py
-> print(f"和={np.sum(price)}")
(Pdb)

次に「l」を入力し、Enterを押すと、現在実行中のコードを表示できます。

(Pdb) l
  3
  4     price = np.array([120,180,300,150])
  5
  6     pdb.set_trace()
  7
  8  -> price += 100
  9
 10     print(f"和={np.sum(price)}")
 11     print(f"平均={np.mean(price)}")
 12     print(f"分散={np.var(price)}")
 13     print(f"標準偏差={np.std(price)}")
(Pdb)

次に、変数名「price」を入力し、Enterを押すことにより、処理途中の変数priceの値を表示できます。

(Pdb) price
array([120, 180, 300, 150])
(Pdb)

現在の行を実行するために「n」を入力し、Enterを押します。
そして、再度「price」を入力し、Enterを押すと更新された変数priceの値を表示できます。

(Pdb) n
> pdb_example.py(10)<module>()
-> print(f"和={np.sum(price)}")
(Pdb) price
array([220, 280, 400, 250])

最後に「c」を入力し、Enterを押すと終了(実際には次のpdb.set_trace()まで実行)します。
このように、任意の行で処理を止めて、処理途中の変数の値を確認したり、新たな処理を試したりすることが出来るので、効率よく実装ができます。

Pythonにおけるグラフのプロット

Pythonでは、グラフのプロットにmatplotlib.pylabライブラリが用いられます。

散布図

以下は、plot関数を用いた2つの散布図

  • 横軸にLotArea(敷地面積)、縦軸にSalePrice(価格)
  • 横軸にMSSubClass(建物の等級)、縦軸にSalePrice(価格)

のプロットの例です。

import pandas as pd
import matplotlib.pylab as plt

# データの読み込み
data = pd.read_csv('house_prices_train.csv')

# Figureの初期化
fig = plt.figure()

# LotArea対SalePriceの散布図
ax=fig.add_subplot(1,2,1)  #グラフの位置指定(1行2列の1列目)
ax.plot(data['LotArea'],data['SalePrice'],'.')
ax.set_xlabel('LotArea')  #x軸のラベル
ax.set_ylabel('SalePrice')   #y軸のラベル

# MSSubClass対SalePriceの散布図
ax=fig.add_subplot(1,2,2)  #グラフの位置指定(1行2列の2列目)
ax.plot(data['MSSubClass'],data['SalePrice'],'.')
ax.set_xlabel('MSSubClass')  #x軸のラベル
ax.set_ylabel('SalePrice')  #y軸のラベル

fig.tight_layout()  # グラフ間に隙間をあける
plt.show()  # グラフの表示

f:id:hirotaka_hachiya:20190527131524p:plain

ここでは、以下のように、グラフの数(列数、行数)と、位置インデックスを指定し、add_subplotを用いて2つのグラフを追加しています。

add.subplot(列数、行数、位置インデックス)

位置インデックスは、「1」から始まり、左端の列から右に、そして右端の列まで行くと、次の行の左端の列に戻るように、「2」、「3」と順番に割り当てられています。

左のグラフでは、plot関数「ax.plot(data['LotArea'],data['SalePrice'],'.')」を用いて、LotAreaを横軸、SalePriceを縦軸にとった散布図をプロットしています。
また、右のグラフでは、同様にMSSubClassを横軸、SalePriceを縦軸にとった散布図をプロットしています。

これらのグラフから、LotArea(敷地面積)とSalePrice(価格)の間には正の相関があり、MSSubClassが60(2階建て、1946年以降)の場合にSalePrice(価格)が高い傾向があることがわかります。

複数の散布図

1つのグラフに複数の散布図をプロットすることも可能です。

以下は、1つのグラフに2つの散布図

  • 建物の等級MSSubClass=30(1階建て、1945年以前)の敷地面積LotAreaに対する販売価格SalePrice
  • 建物の等級MSSubClass=60(2階建て、1946年以降)の敷地面積LotAreaに対する販売価格SalePrice
import matplotlib.pylab as plt
fig = plt.figure()

ax=fig.add_subplot(1,1,1)  #グラフの位置指定

# MSSubClass=30の時のLotArea対SalePriceの散布図
ax.plot(data[data['MSSubClass']==30]['LotArea'],data[data['MSSubClass']==30]['SalePrice'],'.',label="1-Story 1945 & Older")

# MSSubClass=60の時のLotArea対SalePriceの散布図
ax.plot(data[data['MSSubClass']==60]['LotArea'],data[data['MSSubClass']==60]['SalePrice'],'.',label="2-Story 1946 & Newer")

ax.set_xlabel('LotArea')  # x軸のラベル
ax.set_ylabel('SalePrice')  # y軸のラベル
ax.legend()  # 凡例

fig.tight_layout()  # グラフ間に隙間をあける
plt.show()  # グラフの表示

f:id:hirotaka_hachiya:20190527143705p:plain
plot関数の引数の「label="名前"」にて、レジェンド(凡例)に表示する散布図の名前を指定することができます。

このグラフから、MSSubClass=60(2階建て、1946年以降)の建物の多くが、MSSubClass=30(1階建て、1945年以前)の建物より価格が高いことがわかります。

ヒストグラム

以下は、hist関数を用いた3つのヒストグラム

  • SalePrice(価格)
  • LotPrice(敷地面積)
  • MSSubClass(建物の等級)

のプロットの例です。

fig = plt.figure()

ax = fig.add_subplot(1,3,1) # グラフの位置指定(1行3列の1列目)
ax.hist(data['SalePrice']) # SalePriceのヒストグラム
ax.set_xlabel('SalePrice')  # x軸のラベル

ax = fig.add_subplot(1,3,2) # グラフの位置指定(1行3列の2列目)
ax.hist(data['LotArea'])  # LotAreaのヒストグラム
ax.set_xlabel('LotArea')  # x軸のラベル

ax = fig.add_subplot(1,3,3) # グラフの位置指定(1行3列の3列目)
ax.hist(data['MSSubClass'])  # MSSubClassのヒストグラム
ax.set_xlabel('MSSubClass')  # x軸のラベル

plt.tight_layout()  # グラフ間に隙間をあける
plt.show() # グラフの表示

f:id:hirotaka_hachiya:20190527140920p:plain

演習2

建物の等級MSSubClassが20(1階建て、1946年以降), 30(1階建て、1945年以前), 60(2階建て、1946年以降)および70(2階建て、1945年以前)のそれぞれの場合において、敷地面積LotAreaと販売価格SalePriceとの関係を表す散布図を作成しプロットし、比較しましょう。
以下のように、4つのグラフをプロットしてください。

  • 各グラフのタイトルは、「ax.set_title("タイトル")」を用いて設定してください。
  • 各グラフのx軸の範囲は、ax.set_xlim([最小値、最大値])を用いて、データ全体におけるLotAreaの最小値・最大値を設定してください。
  • 各グラフのy軸の範囲は、ax.set_ylim([最小値、最大値])を用いて、データ全体におけるSalePriceの最小値・最大値を設定してください。

f:id:hirotaka_hachiya:20190527155536p:plain

scikit-learnを用いた機械学習(Pythonの基礎 4/4)>>