FANN(Fast Artificial Neural Network Library)を使って最高気温をAIに予測させる ~Delphiでお手軽プログラミング
FANNを使用する為のファイルの準備
https://mam-mam.net/delphi/fann.html からfannfloat.dll、fann.pas、MamFann.pasをダウンロードする。学習(トレーニング)の為のCSVファイルを気象庁のHPからダウンロードする
気象庁のHP(https://www.data.jma.go.jp/gmd/risk/obsdl/index.php)から 「大阪府大阪市」の「日別の日最高気温」の「2010/1/1~2019/12/31」のデータ仕様「年月日などに分けて格納」としてCSVファイルをダウンロードします。ダウンロードしたdata.csvファイルを編集して項目を「年」「月」「日」「最高気温」のみに編集して保存します。
Delphiを起動して新規作成を行い、必要なコンポーネントをドラッグ&ドロップする
Delphi起動⇒ファイル⇒新規作成⇒WindowsVCLアプリケーション を選択します。TButton 2個、 TImage 1個、 TChart 1個をフォームへドラッグ&ドロップします。
Chart1をダブルクリックして、「Editing Chart1」ウィンドウを表示させます。「Add...」ボタンをクリックします。
「すべて保存ボタン」を押して、プロジェクトとユニットを保存します。
プロジェクトフォルダ内にダウンロードしたfann.pas、MamFann.pasファイルを配置します。
fannfloat.dllファイル(32Bit版)をパスの通ったフォルダ(c:\Windows等)に入れます。
data.csvをプロジェクトフォルダ内に入れます。
ソースコードを記述する
Form1のOnDestroyイベント、、 Button1のOnClickイベント、Button2のOnClickイベント、等に以下ソースコードを記述します。unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, VCLTee.TeEngine, VCLTee.TeeProcs, VCLTee.Chart, VclTee.TeeGDIPlus, VCLTee.Series, System.DateUtils,fann, MamFann; type TForm1 = class(TForm) Chart1: TChart; Button1: TButton; Button2: TButton; Image1: TImage; Series1: TLineSeries; procedure Button1Click(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private 宣言 } MamFann: TMamFann; public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var NeuronNumInLayer:array of Cardinal; stl,stll:TStringList; i:integer; inputs : array [0..2] of TFann_type;//入力層(年,月,日) outputs: array [0..0] of TFann_type;//出力層(最高気温) epoch:integer;//トレーニングの反復 begin if Assigned(MamFann) then FreeAndNil(MamFann); setlength(NeuronNumInLayer,3);//レイヤー(層)の数 NeuronNumInLayer[0]:=3; //入力層のニューロン数(年,月,日) NeuronNumInLayer[1]:=3; //中間層のニューロン数 NeuronNumInLayer[2]:=1; //出力層のニューロン数(最高気温) //TMamFannクラスのインスタンス化 MamFann:=TMamFann.Create(NeuronNumInLayer); //CSVファイル(年,月,日,最高気温)の読み込み stl:=TStringList.Create; stl.LoadFromFile('..\..\data.csv'); stll:=TStringList.Create; stll.QuoteChar:='"'; stll.Delimiter:=','; stll.StrictDelimiter:=True; //FANNのトレーニングを開始(100反復) for epoch := 1 to 100 do for i := 1 to stl.Count-1 do begin stll.DelimitedText:=stl[i]; //年を正規化 0(2000年)~1(2100年) inputs[0]:=(StrToFloat(stll[0])-2000)/100; //月を正規化 0(1月)~1(12月) inputs[1]:=(StrToFloat(stll[1])-1)/11; //日を正規化 0(1日)~1(31日) inputs[2]:=(StrToFloat(stll[2])-1)/30; //最高気温を正規化 0(-20℃)~1(+50℃) outputs[0]:=(StrToFloat(stll[3])+20)/70; MamFann.Train(inputs,outputs); end; stll.Free; stl.Free; //ニューロンネットワーク図の描画 MamFann.CreateNeuronBmp(Image1.Picture.Bitmap); end; procedure TForm1.Button2Click(Sender: TObject); var i:integer; dt:TDate; inputs : array [0..2] of TFann_type;//入力層(年,月,日) outputs: array [0..0] of TFann_type;//出力層(最高気温) begin if not Assigned(MamFann) then exit; dt:=Date(); Series1.XValues.DateTime:=True; Chart1.BottomAxis.DateTimeFormat:='yyyy/mm/dd'; Chart1.Legend.Visible:=False; Chart1.Title.Text.Text:= FormatDateTime('yyyy/mm/dd',dt)+'~1年間の最高気温予想'; //システム日付から365日間の最高気温を予想させてグラフ表示を行う for i := 0 to 365 do begin inputs[0]:=(YearOf(dt)-2000)/100; inputs[1]:=(MonthOf(dt)-1)/11; inputs[2]:=(DayOf(dt)-1)/30; MamFann.Run(inputs,outputs); Series1.AddXY(dt,outputs[0]*70-20); dt:=dt+1; end; end; procedure TForm1.FormDestroy(Sender: TObject); begin if Assigned(MamFann) then FreeAndNil(MamFann); end; end.
実行する
実行ボタンを押して実行します。(デバッグ実行でもOK)Button1をクリックすると、トレーニングが開始され、ニューロンネットワーク図が描画されます。
Button2をクリックすると、今から1年間の最高気温予測がグラフ表示されます。