参考書
本ブログの内容の詳細は、「機械学習スタートアップシリーズ ゼロからつくるPython機械学習プログラミング入門」に掲載されています。
機械学習に必要な数学の復習から、機械学習のアルゴリズムの導出およびPythonの基本ライブラリのみを用いた実装方法まで学びたい方は、本書籍をご活用ください。
bookclub.kodansha.co.jp
線形回帰のテンプレート
intelligentSystemTrainingフォルダ下の線形回帰のテンプレートregression_template.pyに定義されているlinearRegressionクラスに、演習1で作成したtrain関数を組み込み、学習から評価および結果の可視化までのパスを通していきます。
以下は、linearRegressionクラスには、以下のようなメソッドが定義されています。
1)__init__: 学習データの初期化
2)train:最小二乗法を用いたモデルパラメタself.wの最適化※未実装(演習1)
2)trainMat:最小二乗法を用いたモデルパラメタself.wの最適化(行列演算を用いた高速化)※未実装(演習3)
3)predict: 学習したモデルを用いてyを予測 ※未実装(演習2)
4)loss: 二乗損失の計算※未実装(演習2)
#------------------- # クラスの定義始まり #------------------- # クラスの定義始まり class linearRegression(): #------------------------------------ # 1) 学習データおよびモデルパラメータの初期化 # x: 学習入力データ(入力ベクトルの次元数×データ数のnumpy.array) # y: 学習出力データ(データ数のnumpy.array) # kernelType: カーネルの種類(文字列:gaussian) # kernelParam: カーネルのハイパーパラメータ(スカラー) def __init__(self, x, y, kernelType="linear", kernelParam=1.0): # 学習データの設定 self.x = x self.y = y self.xDim = x.shape[0] self.dNum = x.shape[1] # カーネルの設定 self.kernelType = kernelType self.kernelParam = kernelParam #------------------------------------ #------------------------------------ # 2) 最小二乗法を用いてモデルパラメータを最適化 # (分子・分母の計算にFor文を用いた場合) def train(self): self.w = np.zeros([self.xDim,1]) #------------------------------------ #------------------------------------ # 2) 最小二乗法を用いてモデルパラメータを最適化 # (分子・分母の計算に行列演算を用いた場合) def trainMat(self): self.w = np.zeros([self.xDim,1]) #------------------------------------ #------------------------------------ # 3) 予測 # x: 入力データ(入力次元 x データ数) def predict(self,x): y = [] return y #------------------------------------ #------------------------------------ # 4) 二乗損失の計算 # x: 入力データ(入力次元 x データ数) # y: 出力データ(データ数) def loss(self,x,y): loss = 0.0 return loss #------------------------------------ # クラスの定義終わり #-------------------
以下は、学習から評価および可視化までを実行するメインです。
メインでは、以下のようにフローなっています。
1)regressionData.artificialクラスをインスタンス(myData)化し、学習用・評価用データの生成
2)linearRegressionクラスをインスタンス(classifier)化し、モデルの初期化
3)linearRegression.trainを用いて最小二乗法を用いてパラメータの最適化および処理時間の測定
4)linearRegression.trainMatを用いて最小二乗法の行列演算版を用いてパラメータの最適化および処理時間の測定
5)linearRegression.lossを用いて評価データに対する二乗損失を計算
6)linearRegression.predictを用いて評価データに対する予測値を計算し、regressionData.artificial.plotを用いてプロット
#------------------- # メインの始まり if __name__ == "__main__": # 1) 学習入力次元が2の場合のデーター生成 myData = rg.artificial(200,100, dataType="1D") # 2) 線形回帰モデル regression = linearRegression(myData.xTrain,myData.yTrain) # 3) 学習(For文版) sTime = time.time() regression.train() eTime = time.time() print("train with for-loop: time={0:.4} sec".format(eTime-sTime)) # 4) 学習(行列版) sTime = time.time() regression.trainMat() eTime = time.time() print("train with matrix: time={0:.4} sec".format(eTime-sTime)) # 5) 学習したモデルを用いて予測 print("loss={0:.3}".format(regression.loss(myData.xTest,myData.yTest))) # 6) 学習・評価データおよび予測結果をプロット predict = regression.predict(myData.xTest) myData.plot(predict) #メインの終わり #-------------------
演習2
以下のlinearRegressionクラスのtrain, lossおよびpredictメソッドを実装し完成させましょう。
#------------------------------------
# 2) 最小二乗法を用いてモデルパラメータを最適化
# (分母の計算にFor文を用いた場合)
def train(self):
【演習1の内容をlinearRegressionクラスに合うように変形したコード】
#------------------------------------
#------------------------------------
# 3) 予測
# x: 入力データ(入力次元 x データ数)
def predict(self,x):
【入力xから学習したモデルを用いてyを予測するコード】
return y
#------------------------------------#------------------------------------
# 4) 二乗損失の計算
# x: 入力データ(入力次元 x データ数)
# y: 出力データ(データ数)
def loss(self,x,y):
【入力xに対する予測と、yの平均二乗誤差を計算しlossに設定するコード】
return loss
#------------------------------------
行列演算による高速化
Pythonのfor文は、C言語などのコンパイル言語と異なり、インタプリタが解釈し実行するため処理に時間がかかります。そのため、出来るだけfor文は使わず実装が最適化されているnumpyの行列演算を用いて方が処理の効率上良いとされています。
線形回帰の最適化におけるモデルパラメータの式に、分子および分母の計算に和があり、特に工夫をしなければfor文を使ってしまうと思います。これを行列演算に置き換えることを考えましょう。
演習3
モデルパラメータの最適化の式の分母の計算を、行列演算に置き換えられることを式の上で確認し、linearRegression.trainMatメソッドを実装し、クラスを完成させましょう。
線形回帰の実行例
linearRegressionクラスのパスが一通り通り実行すると、以下のような出力が得られます。
【入力次元が1次元の場合】
> train with for-loop: time=0.006868 sec train with matrix: time=0.002006 sec loss=0.011
【入力次元が2次元の場合】
> python .\regression.py train with for-loop: time=0.007021 sec train with matrix: time=0.002 sec loss=0.0132