ML.NET を利用したシンプルな分類判定プログラム - C#

ML.NET を利用してシンプルな分類判定プログラムを作成します。

作成するプログラム

2つの数値x,yを与えます。x,y の範囲は0から1の間とします。 xがyより大きければ、分類ラベル:1、xがyより小さければ、分類ラベル:0 とします。
学習データを与えて学習させたのち、2つの値を与えて、分類ラベルが0か1かを判定します。

図で表すと下図になります。

データの準備

学習用のデータを作成します。今回はプログラムで作成します。

UI

Windows Formアプリケーションを作成し下図のフォームを作成します。
ボタンとMultilineプロパティをTrueに設定したテキストボックスを配置します。

コード

下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CreateData
{
  public partial class FormXYData : Form
  {
    public FormXYData()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {

      Random r = new Random();

      textBox1.Text += "x\ty\tLabel\r\n";

      for (int i = 0; i < 50; i++)
      {
        double x = r.NextSingle();
        double y = r.NextSingle();
        int c;
        if (x < y) c = 0; else c = 1;

        textBox1.Text += String.Format("{0:f}\t{1:f}\t{2:d}\r\n", x, y, c);
      }
    }
  }
}

解説

乱数を作成するため、Randomオブジェクトのインスタンスを作成します。
   Random r = new Random();

結果を出力するテキストボックスにヘッダのラベル行を出力します。
  textBox1.Text += "x\ty\tLabel\r\n";

forループでデータを作成します。今回は50個の学習用データを生成します。
  for (int i = 0; i < 50; i++)
  {
    // ....
  }

ループ内で2つの乱数、x y を作成します。 xがyより小さければ、ラベルの値である変数cに0を代入し、それ以外の場合は1を代入します。
    double x = r.NextSingle();
    double y = r.NextSingle();
    int c;
    if (x < y) c = 0; else c = 1;

変数の値をテキストボックスに出力します。
        textBox1.Text += String.Format("{0:f}\t{1:f}\t{2:d}\r\n", x, y, c);

実行結果

プログラムを実行し、button1をクリックします。テキストボックスに生成されたデータが表示されます。

Machine Learning Modelの作成

Machine Learning Modelを作成します。

使用する学習データ

先ほどのプログラムで作成した学習用データを用意します。今回は以下の値を利用します。
タブ区切りのテキストファイルです。データはテキストファイルで保存します。
x	y	Label
0.31	0.20	1
0.60	0.60	1
0.71	0.10	1
0.95	0.28	1
0.69	0.30	1
0.75	0.84	0
0.17	0.38	0
0.73	0.16	1
0.70	0.23	1
0.65	0.87	0
0.56	0.83	0
0.57	0.11	1
0.11	0.89	0
0.48	0.33	1
0.54	0.51	1
0.99	0.71	1
0.21	0.85	0
0.65	0.68	0
0.52	0.02	1
0.17	0.81	0
0.66	0.46	1
0.91	0.46	1
0.47	0.98	0
0.01	0.04	0
0.52	0.84	0
0.04	0.96	0
0.57	0.36	1
0.25	0.76	0
0.25	0.37	0
0.85	0.27	1
0.08	0.30	0
0.67	0.59	1
0.87	0.12	1
0.03	0.23	0
0.46	0.00	1
0.08	0.49	0
0.80	0.28	1
0.66	0.74	0
0.43	0.86	0
0.75	0.97	0
0.92	0.93	0
0.61	0.88	0
0.38	0.23	1
0.16	0.78	0
0.15	0.52	0
0.76	0.17	1
0.30	0.13	1
0.94	0.01	1
0.51	0.11	1
0.40	0.03	1

図で表すと下図になります。

事前準備 : ML.NET のインストール

ML.NET と ML.NET Model Builder をインストールします。インストールの手順はこちらの記事を参照してください。

モデルの作成

準備したデータを利用してモデルを作成します。

ソリューションエクスプローラーで Windows Form アプリケーションのプロジェクトを作成します。


作成したWindows Formaアプリケーションのプロジェクトのノードをクリックして選択して右クリックします。 下図のポップアップメニューが表示されます。[追加]のサブメニューの [機械学習モデル]の項目を クリックします。


下図の[新しい項目の追加]ダイアログが表示されます。[Machine Learning Model (ML.NET)]の項目が選択された状態になっています。 下部の[名前]のテキストボックスにモデルのファイル名を入力します。今回はデフォルトの "MLModel1.mbconfig" のままとします。 ダイアログ右下の[追加]ボタンをクリックします。


[Machine Learning Model のファイルが作成され、下図の画面が表示されます。


[シナリオの選択]画面が表示されます。今回は一番左の [データ分類] のシナリオを利用します。 タイルをクリックします。


[トレーニング環境の選択]画面が表示されます。今回のシナリオではローカル(CPU)のみが利用できます。 [次の手順]をクリックします。


[データの追加]画面が表示されます。


[入力]のセクションの [データ ソースの種類]を[ファイル (.csv、.tsv、.txt)]に設定します。 先ほど準備したデータのテキストファイルを参照します。
ファイルを参照すると画面下部の[データのプレビュー]セクションにファイルの先頭部分の値が表示されます。


[予測する列(ラベル)]のコンボボックスをクリックします。データファイルの列名が表示されます。 今回は、与えた x y の値から Label を判定するため、予測する列は [Label] を設定します。


[詳細なデータ オプション...]のリンクをクリックして設定を確認します。


[詳細なデータ オプション]のダイアログが表示されます。
x,y の列の[目的]の値が "Feature" に設定されていることを確認します。 また、Label の[目的]の値が "Label" に設定されていること、[カテゴリ別] にチェックが入っていることを確認します。
設定ができたらダイアログ右下の[保存]ボタンをクリックします。


[入力]の画面に戻ります。下にスクロールして画面下部の[次の手順]のボタンをクリックします。


[トレーニングする]画面が表示されます。[トレーニングする時間(秒)]を設定します。今回はデータの数が少ないため、デフォルトの10秒で 問題ありません。[トレーニングの開始]ボタンをクリックします。


トレーニングが開始されます。


トレーニングが完了すると下図の画面が表示されます。画面下部の[次の手順]のボタンをクリックします。


[評価]画面が表示されます。


[独自のモデルを試す]セクションの[サンプルデータ]のテキストボックスに検証する値を入力します。 テストで、xに0.85 yに0.42 を入力します。入力後 [予測] ボタンをクリックします。


右側の[結果]のセクションに学習モデルの結果が表示されます。Labelは 1 であり、確からしさが65%と表示されます。


別の値を入力します。xに0.22 yに0.46 を入力し[予測]ボタンをクリックします。右側の[結果]セクションに 結果が表示され、Label は 0 であり、確からしさが56%と表示されます。
xがyより大きければ、Labelは1ですので、どちらの結果もあっています。
検証ができたら画面下部の [次の手順] のボタンをクリックします。


[使用] 画面が表示されます。学習モデルをプログラムから利用するコードのサンプルが表示されています。
[次の手順]ボタンをクリックします。


モデルのデプロイの画面が表示されます。今回はデプロイは不要のため、以上で終了です。

学習モデルファイルの確認

学習結果のモデルはプロジェクトのディレクトリ内の、(Machine Learning Model のファイル名).zip ファイルに生成されます。

学習モデルを利用するプログラムの作成

Windows Formアプリケーションを実装します。
Windows FormアプリケーションにはML.NETのパッケージをインストールします。 ML.NETのインストールの手順はこちらの記事を参照してください。

UI

下図のフォームを作成します。テキストボックスを2つ、MultilineプロパティをTrueに設定した複数行テキストボックスを1つ、ボタンを1つ配置します。

コード

下記のコードを記述します。
namespace SimpleClassified
{
  public partial class FormMain : Form
  {
    public FormMain()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      //Load sample data
      var sampleData = new MLModel1.ModelInput()
      {
        X = Convert.ToSingle(textBox1.Text),
        Y = Convert.ToSingle(textBox2.Text)
      };

      //Load model and predict output
      var result = MLModel1.Predict(sampleData);

      textBox3.Text += String.Format("{0:f} (Score 0:{1:f}, 1:{2:f})\r\n", result.Prediction, result.Score[0], result.Score[1]);
    }
  }
}

解説

Machine Learning Model作成画面の[Consume] 画面で生成されたコードを利用しています。
入力データは、ModelInputクラスを作成し、メンバ変数に代入して作成します。 判定処理は、モデルクラスの Predict メソッドで実行します。引数に入力データの ModeiInput オブジェクトを与えます。
結果は、ModelOutput オブジェクトがPredictメソッドの戻り値で戻ります。Prediction プロパティに判定結果のLabelの値が設定されます。 ScoreプロパティにそれぞれのLabelのスコアが設定されています。

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。[button1]ボタンをクリックします。


下部のテキストボックスに結果が表示されます。x=0.25, y=0.55 の場合は Labelは0の判定になります。


数値を変えて、結果が変わるか確認します。x=0.86, y=0.22 の場合は Labelは1の判定になります。


x=0.49, y=0.60 の場合は Labelは0の判定になります。


xがyより大きい場合にLabelは1となるため、3つとも結果はあっています。

ML.NET を利用したシンプルな学習プログラムを作成できました。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2021-12-31
iPentec all rights reserverd.