【HTM - Python】Sine関数の予測、新皮質モデルで機械学習
HTM記事全体のの目次は以下。
【HTM - Python】新皮質モデルで機械学習(目次) - FUNC-RETURN
Sine関数の時系列データを生成
# -*- coding: utf-8 -*- import csv import math def generateData(num, file_name): ''' Generate Sine wave data. Args: num: number of data. file_name: output csv file name. ''' file_handler = open(file_name, 'w') writer = csv.writer(file_handler) writer.writerow(['angle', 'sine']) writer.writerow(['float', 'float']) writer.writerow(['', '']) for i in range(num): angle = i * math.pi / 50.0 sine_value = math.sin(angle) writer.writerow([angle, sine_value]) file_handler.close() if __name__ == '__main__': generateData(num=1000, file_name="sine.csv")
スウォーミング
モデルパラメータを自動的に取得するためにSwarmingを実行しておきます。OPF-API
モデルパラメータからモデルを生成
opfのAPIで提供されるModelFactory
を使って生成します。
Online Prediction Framework (OPF) — NuPIC 1.0.3 documentation
from nupic.frameworks.opf.modelfactory import ModelFactory from swarm.model_0.model_params import MODEL_PARAMS ... model = ModelFactory.create(MODEL_PARAMS) model.enableInference({ "predictedField": "sine" })
opfを一回実行
nupic.frameworks.opf.model.Model.run
で一回分実行します。
今回のサインウェーブ予測ではforのループ毎にこれを実行してます。
result = model.run({ "angle": angle, "sine": sine })
InferenceShifter
上記の
nupic.frameworks.opf.model.Model.run
は、T(i)
のデータをインプットしてT(i + 1)
の時の予測値をアウトプットします。なので、例えば、for文でループして実行する際に、前のループの予測値と今のループの正解インプットデータを比較したくなります。
そういう際に、このShifterを使うと便利です。
Shifterのドキュメント
Model Results — NuPIC 1.0.3 documentation
Shifterのコード
nupic/inference_shifter.py at master · numenta/nupic · GitHub
from nupic.data.inference_shifter import InferenceShifter ... result = model.run({ "angle": angle, "sine": sine }) # 一つ前の予測がシフトされたModelResultオブジェクトが返ってくる。 result = shifter.shift(result)
Let's Sine関数予測
グラフの説明
上のグラフは、青のラインがインプットデータ(正しいサインウェーブ)で、緑のラインがNupicが予測したラインです。下は、異常検知を示すグラフです。
これは、Swarmingで
inferenceType
をTemporalAnomaly
にしたので、異常検知もしてくれるモデルが作られたからです。はじめの方は、HTMモデルが、頻出する時間シーケンスをまだ学習できてないので異常値が高くなり、
進んでいくに従って、パターンを学習していくので異常値が下がって行きます。
実行ファイルのコード
# -*- coding: utf-8 -*- import csv from nupic.data.inference_shifter import InferenceShifter from nupic.frameworks.opf.modelfactory import ModelFactory import nupic_output from swarm.model_0.model_params import MODEL_PARAMS def createModel(): ''' Create nupic.frameworks.opf.model.Model from ModelFactory. Return: An opf model. ''' model = ModelFactory.create(MODEL_PARAMS) model.enableInference({ "predictedField": "sine" }) return model def runModel(model, file_name): ''' Run predictions by a given model. Args: model: Opf model. ''' input_file = open(file_name, "rb") csv_reader = csv.reader(input_file) # ヘッダーをスキップ csv_reader.next() csv_reader.next() csv_reader.next() shifter = InferenceShifter() # これは、結果を描画する用のクラス。 # 実際に書かれてるのはMatplotlib周りの実装 # 内容に関してはレポジトリでみてください。 output = nupic_output.NuPICPlotOutput("Sine", show_anomaly_score=True) for row in csv_reader: angle = float(row[0]) sine = float(row[1]) # Modelを一回実行 result = model.run({ "angle": angle, "sine": sine }) # 今のインプットと一つ前の予測値が入ったModelResultを生成 result = shifter.shift(result) # NuPICPlotOutputで図が更新される output.write(angle, sine, result) input_file.close() output.close() if __name__ == "__main__": model = createModel() runModel(model=model, file_name="sine.csv")
コード全体は以下。
github.com