2023/05/10

AutoML:自動機械学習

ここまでの苦労を無駄にしない為に、モデルビルダーでやる事を自前でMicrosoft.ML.AutoMLを使ってやってみようと、チュートリアル通りに進めてみます。既にCSV出力部分はここまで書いた様に出来上がってるしCSVファイル自体もあるので、これをソースとして使う。まずは、InferColumnsメソッド使ってテキストローダーの準備をする。

ColumnInferenceResults columnInference = mlContext.Auto().InferColumns(path, labelColumnName: "Souha", groupColumns: false);

これは説明ではCSVから数行読み取り、カラム毎のデータの種類を推測してるらしい。で、今回はモデルビルダーの時にも指定してましたが、

// 競馬場コード
columnInference.ColumnInformation.NumericColumnNames.Remove("JouCD");
columnInference.ColumnInformation.CategoricalColumnNames.Add("JouCD");

// トラックコード
columnInference.ColumnInformation.NumericColumnNames.Remove("TrackCD");
columnInference.ColumnInformation.CategoricalColumnNames.Add("TrackCD");

// 天候コード
columnInference.ColumnInformation.NumericColumnNames.Remove("Tenko");
columnInference.ColumnInformation.CategoricalColumnNames.Add("Tenko");

// 馬場状態コード
columnInference.ColumnInformation.NumericColumnNames.Remove("Baba");
columnInference.ColumnInformation.CategoricalColumnNames.Add("Baba");

// 繁殖登録番号_父
columnInference.ColumnInformation.NumericColumnNames.Remove("Chichi");
columnInference.ColumnInformation.CategoricalColumnNames.Add("Chichi");

これらのカラムは数値だけどカテゴリ別なだけで特段数値的な要素ではないのでその為の変更を入れる。で、テキストローダーを準備してデータビューを読み込む。

TextLoader loader = mlContext.Data.CreateTextLoader(columnInference.TextLoaderOptions);

IDataView data = loader.Load(path);

読み込んだデータビューの内、TrainTestSplitメソッドでトレーニングと検証に使うデータの割合を指定。パイプライン定義して、最適な予測方法を探す指示をする訳です。

TrainTestData trainValidationData = mlContext.Data.TrainTestSplit(data, testFraction: 0.2);

SweepablePipeline pipeline =
    mlContext.Auto().Featurizer(data, columnInformation: columnInference.ColumnInformation)
        .Append(mlContext.Auto().Regression(labelColumnName: columnInference.ColumnInformation.LabelColumnName));

AutoMLExperiment experiment = mlContext.Auto().CreateExperiment();

experiment
    .SetPipeline(pipeline)
    .SetRegressionMetric(RegressionMetric.RSquared, labelColumn: columnInference.ColumnInformation.LabelColumnName)
    .SetTrainingTimeInSeconds(300)
    .SetDataset(trainValidationData);

SetTrainingTimeInSecondsで秒数で時間指定(チュートリアルでは60秒でしたが5分にしてみた)して待つ訳ですが、進捗状況観る為に、

mlContext.Log += (_, e) => {
    if (e.Source.Equals("AutoMLExperiment"))
    {
        if (this.InvokeRequired)
        {
            this.logMessage = e.RawMessage + Environment.NewLine + Environment.NewLine;
            this.Invoke(new Action(this.OutputLog));
        }
        else
        {
            this.rtbLog.AppendText(e.RawMessage + Environment.NewLine + Environment.NewLine);
        }
    }
};

これ、チュートリアルではInvokeとか無しに単純にConsole.WriteLineしてるんですが、コンソールアプリじゃないので、RichTextBoxにログ表示させているんですがそのままではエラー出ます。で、その回避策としてInvoke使ってます。AutoMLの実行は、

TrialResult experimentResults = await experiment.RunAsync();

でしますが、これawaitしてるので、ログ出力が別スレッドからだとエラー起こす訳で↑のInvokeって事です。で、この一連のメソッド定義にもasyncが必要になる。ここまではスムーズに書き上げて実際に実行するとだらだらと何やらログが出て終わります。

ここから更に色々と修正加えるっぼいので一旦ここまでです。

0 件のコメント:

コメントを投稿