覚え書きブログ

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

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

Pythonオブジェクト指向

Pythonでは、関数とクラスの定義を以下のような形式で記述します。

def 関数名(引数1,引数2, ...):
	関数の処理
class クラス名:
    def __init__(self, 引数1, 引数2, ….):
        #コンストラクタの定義

    def メソッド名(self, 引数1, 引数2, ….):
        #メソッドの定義

ここで、self.xxxはインスタンス変数で、コンストラクタとメソッドの最初の引数はselfを記述しなければなりません。

以下は、物件価格データを読み込み、散布図をプロットするクラスの定義の例です。

import pandas as pd
import numpy as np
import matplotlib.pylab as plt

class HousePriceData:
    #---------------
    # コンストラクタ
    def __init__(self, datapath="house_prices_train.csv"):
        self.data = pd.read_csv(datapath)  # DataFrameの読み込み
    #---------------
    
    #---------------
    # 散布図をプロットするメソッド
    # nrow:行数(int型、例:2)
    # ncol:列数(int型、例:5)
    # data:データ(numpy array型、)
    # titles: タイトル(numpy array型)
    # xattri:xの属性(str型)
    # yattri:yの属性(str型)
    def plotScatter(self, nrow, ncol, data, titles, xattri, yattri):
        # Figureの初期化
        fig = plt.figure()
        
        xrange = [np.min(self.data[xattri].values), np.max(self.data[xattri].values)]  # x軸の範囲
        yrange = [np.min(self.data[yattri].values), np.max(self.data[yattri].values)]  # y軸の範囲
        
        # 散布図をプロット
        for ind in range(np.min([len(data),nrow*ncol])): 
            ax=fig.add_subplot(nrow,ncol,ind+1)  # グラフの位置を指定(nrows行、ncols列のindex番目)
            ax.set_title(titles[ind])  # タイトルの設定
            ax.plot(data[ind][xattri].values,data[ind][yattri].values,'.')   # 散布図のプロット
            
            ax.set_xlim([xrange[0], xrange[1]])   # x軸の範囲設定
            ax.set_ylim([yrange[0], yrange[1]])   # y軸の範囲設定            
            ax.set_xlabel(xattri)  # x軸のラベル
            ax.set_ylabel(yattri)  # y軸のラベル

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

上記のコードでは、以下の変数とメソッドを持つHousePriceというクラスを定義しています。

  • インスタンス変数self.data:読み込んだデータを格納するpandas.DataFrame
  • コンストラクタ:指定されたdatapath(デフォルトでは、"house_prices_train.csv"に設定)のcsvファイルからデータを読み込み、self.dataに設定する
  • メソッドplotScatter(self, nrow, ncol, data, titles, xattri, yattri):指定された複数のデータの散布図を作成する

nrow:行数(int型、例:2)
ncol:列数(int型、例:5)
data:データ(numpy array型、)
titles: タイトル(numpy array型)
xattri:xの属性(str型)
yattri:yの属性(str型)

以下は、定義されたクラスを実行する例です。クラスHousePriceDataをmyDataとしてインスタンス化しています。

# 物件価格データのインスタンス化
myData = HousePriceData()

# プロットする4種類のデータの準備
data=[]
data.append(myData.data[myData.data['MSSubClass']==20])
data.append(myData.data[myData.data['MSSubClass']==30])
data.append(myData.data[myData.data['MSSubClass']==60])
data.append(myData.data[myData.data['MSSubClass']==70])

# データに対応するタイトルの準備
titles=[]
titles.append('1-Story 1946 & Newer')
titles.append('1-Story 1945 & Older')
titles.append('2-Story 1946 & Newer')
titles.append('2-Story 1945 & Older')
#---------------
# 散布図をプロット
myData.plotScatter(2,2,data,titles,'LotArea','SalePrice')
#---------------

f:id:hirotaka_hachiya:20190527182015p:plain
煩わしい繰り返し処理を、クラスのメソッド化することにより、コードをすっきりさせることができました。

演習3

1)任意のデータのヒストグラムをプロットするメソッドplotHistogram(self, nrow, ncol, data, titles, xattri)を作成しましょう
2)plotHistgramを用いて、建物の等級MSSubClassが、20, 30, 60および70の時の販売価格SalePriceのヒストグラムをプロットしましょう。

f:id:hirotaka_hachiya:20190821183358p:plain