<< scikit-learnを用いた機械学習(教師あり学習 1/3)
教師あり学習のフローのクラス化
以下は、教師あり学習(回帰)の一連のフローを、クラス化したものです。
import pandas as pd import numpy as np import matplotlib.pylab as plt from sklearn import linear_model from sklearn.model_selection import train_test_split # Regressionクラス class Regression: #--------------- # コンストラクタ def __init__(self, datapath="house_prices_train.csv"): self.data = pd.read_csv(datapath) # 予測のフラグ self.isPred = False #--------------- #--------------- # 回帰用のデータを作成するメソッド def createRegData(self, xattriReg, yattriReg, data): self.xattriReg = xattriReg # 入力xのデータ名 self.yattriReg = yattriReg # 出力yのデータ名 self.X = data[xattriReg].values # 入力xの設定 self.y = data[yattriReg].values # 出力xの設定 #--------------- #--------------- # 標準化するメソッド def normalize(self): self.Xmean = np.mean(self.X,axis=0) # 平均 self.Xstd = np.std(self.X,axis=0) # 標準偏差 self.X = (self.X-self.Xmean)/self.Xstd # 標準化 #--------------- #--------------- # 訓練用と評価用とに分割するメソッド # trRatio:学習データの割合((0,1]の少数で指定、例:0.8) def split2TrainTest(self,trRatio=0.8): self.Xtr, self.Xte, self.ytr, self.yte = \ train_test_split(self.X,self.y,train_size=trRatio,test_size=1-trRatio) #--------------- #--------------- # 回帰用の関数する学習メソッド def trainRegression(self): self.f = linear_model.LinearRegression() # 関数fの定義 self.f.fit(self.Xtr, self.ytr) # 関数fの学習 #--------------- #--------------- # 回帰の予測 def predict(self): self.isPred = True # 予測のフラグをオン self.ypre = self.f.predict(self.Xte) # 予測 #--------------- #--------------- # 回帰の評価 def evalRegression(self): # 予測 if not self.isPred: self.predict() # 平均絶対差の計算 self.absError = np.mean(np.abs(self.yte - self.ypre)) print("評価データの絶対誤差=",self.absError) #--------------- #--------------- # 予測結果の散布図を作成するメソッド def plotResults(self): # 予測 if not self.isPred: self.predict() # 元のスケールに戻す Xtmp = self.Xte*self.Xstd+self.Xmean fig = plt.figure() for ind in range(len(self.xattriReg)): ax=fig.add_subplot(len(self.xattriReg),1,ind+1) # 予測のプロット ax.plot(Xtmp[:,ind], self.ypre,'.',label='predict') # 真値のプロット ax.plot(Xtmp[:,ind], self.yte,'.',label='true') ax.set_ylim([np.min(self.yte), np.max(self.yte)]) # y軸の範囲 ax.set_xlabel(self.xattriReg[ind]) # x軸のラベル ax.set_ylabel(self.yattriReg) # y軸のラベル plt.tight_layout() # グラフ間に隙間をあける plt.show() # グラフの表示 #---------------
クラスRegressionを用いて、教師あり学習を実行すると以下のようになります。
myData = Regression() # Regressionクラスのインスタンス化 myData.createRegData(['LotArea'],'SalePrice', myData.data[myData.data['MSSubClass']==20]) # 教師ありデータの作成 myData.normalize() # 標準化 myData.split2TrainTest() # 訓練用と評価用とに分割 myData.trainRegression() # 関数の学習 myData.evalRegression() # 誤差の評価 # 散布図で可視化 myData.plotResults()
演習1
敷地面積LotAreaだけを入力として用いて、販売価格SalePriceを予測した場合、上記のように約600万円ほどの誤差がでます。
この回帰の精度を改善するために、入力に車庫の面積GarageAreaと、居住面積GrLivAreaを追加してみましょう。
具体的には、上記のRegressionクラスを利用して、以下のような、平均絶対誤差と、散布図を3つ作りましょう。