4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ML.NET のチュートリアルをやってみた

Last updated at Posted at 2018-07-21

ML.NET

ML.NET は、Mirosoft が提供しているオープンソース機械学習フレームワークで

以下のページで紹介されています。
ML.NETガイド https://docs.microsoft.com/ja-jp/dotnet/machine-learning/)

チュートリアルがあったので実行したときのメモ

環境構築

環境構築には、quick-start
を見ながらすすめていきます。ざくっと説明すると。

.NET SDKのインストール

Download .NET Core SDK をダウンロードすれば良いと思います。
ファイルは、 dotnet-sdk-2.1.XXX-win-x64.exe とかなので、
インストールします。

アプリケーションのベースを作成

.NET Core にはコマンドラインツールの dotnet というビルド環境が提供されています。

dotnet new console -o myApp
cd myApp

dotnet new XXX で、雛形を作ってくれます。-o は、フォルダに出力。

Visual Studio Code で実装環境を整備

myApp のフォルダで、Visual Studio Code(以下 Code)を立ち上げます。

右下にdialog が表示されているかもしれません。

Required assets to build and debug are missingfrom 'myApp'. Add them?

Codeからプログラムのデバックができるように環境についかしましょうか?ということなので、Yes と返事

ML.NET パッケージをダウンロード

dotnet コマンドは、pip , npm のように必要なパッケージをネットからダウンロードして
使えるようにしてくれます。

dotnet add package Microsoft.ML --version 0.3.0

Codeの統合ターミナルで上のコマンドを入力すると nuget というネットからダウンロードするプログラムが複数の依存パッケージをダウンロードします。
終わると、右下にダイアログが

There are unresolved dependencies from 'myApp.csproj'. Please execute the restore command to continue. [Restore]

dotnet でパッケージなどをインストールすると、それらの依存関係をリストアという仕組みで整えてくれるので、ここでは restore ボダンもしくは

dotnet restore

を実行。これで補完機能とか使いやすくなる。

データのダウンロード

チュートリアルでは、データは提供しているページのテキストをコピペしてね。と書かれています。

上のリンクを右ボタンで、「名前をつけてリンク先を保存」(chromeの場合)で、myAppのフォルダに

iris-data.txt

というファイル名で保存しておきます。中身は、CSV形式のテキストで

5.1,3.5,1.4,0.2,Iris-setosa
4.9,3.0,1.4,0.2,Iris-setosa
4.7,3.2,1.3,0.2,Iris-setosa
4.6,3.1,1.5,0.2,Iris-setosa
    :

というデータになっています。1行が一つのデータで、前の4つの浮動小数点が4つの特徴量について数値化したもので、次の文字列が花のアヤメ(Iris)の種類を示しています。

ここでの課題は、この数値を受け取ってアヤメの名前を推定することを機械学習しましょうというものです。

プログラムを実装

dotnet create で作成したコンソール向けのアプリケーションの雛形には、Program.csというファイルが作られています。

チュートリアルで示されているプログラムで Program.cs を上書きしてします。

プログラムの実行

dotnetコマンドには、

  • dotnet build プログラムのビルド
  • dotnet run プログラムの実行

ここでは、コピペした場合には文法エラーなど無いので、dotnet run でコンパイル&実行されます。

dotnet run

を統合ターミナルでコンパイル&実行をすると、以下の出力が表示されました

Using 2 threads to train.
Automatically choosing a check frequency of 2.
Auto-tuning parameters: maxIterations = 9998.
Auto-tuning parameters: L2 = 2.667734E-05.
Auto-tuning parameters: L1Threshold (L1/L2) = 0.
Using best model from iteration 806.
Not training a calibrator because it is not needed.
Predicted flower type is: Iris-virginica

まずは、動作確認ができたところまで、何かよくわからないが iris-data.txt から分類問題を学習したという結果が表示されています。

プログラムの分析

プログラムが何をしたのかちょっと見ます。

  • 依存パッケージ
using Microsoft.ML;
using Microsoft.ML.Data;
using Microsoft.ML.Runtime.Api;
using Microsoft.ML.Trainers;
using Microsoft.ML.Transforms;
using System;

Microsoft.ML.XXX が、先程 dotnet add package で追加したパッケージ。

  • データの定義

使用するデータを IrisData としてクラス定義してます。

        public class IrisData
        {
            [Column("0")]
            public float SepalLength;

            [Column("1")]
            public float SepalWidth;

            [Column("2")]
            public float PetalLength;

            [Column("3")]
            public float PetalWidth;

            [Column("4")]
            [ColumnName("Label")]
            public string Label;
        }

Column("0") は、CSVの1つ目のデータを float 型の SepalLength という変数で定義

変数名 意味
SepalLength がく片の長さ
SepalWidth がく片の幅
PetalLength 花弁の長さ
pPetalWidth 花弁の幅

5番目の項目だけラベル名も追加で ColumnName("Label")

  • 推論する項目

推論する項目もクラス定義し、ColumnNameで定義

        public class IrisPrediction
        {
            [ColumnName("PredictedLabel")]
            public string PredictedLabels;
        }
  • 学習

ここからMain関数での処理です。まずは、学習させるためにデータと変数を結びつけるパイプラインを作成

    var pipeline = new LearningPipeline();

読み込むデータをセットします。CSVのファイル名を TextLoader のフィルターで処理するようにセット。データファイル形式は、先程定義した IrisData にデータをマッピングする。データの切り分け(separator)は、カンマ。

    string dataPath = "iris-data.txt";
    pipeline.Add(new TextLoader(dataPath).CreateFrom<IrisData>(separator: ','));

データ処理を数値計算のみにするため、入力した項目のラベルを辞書として文字列と数値を作成する。Dictionarizer という辞書化オブジェクで辞書の名前は Label。

    pipeline.Add(new Dictionarizer("Label"));

取り扱うデータをベクトルにするため、各項に名前をつける ColumnConcatenator でパイプラインに追加

    pipeline.Add(new ColumnConcatenator("Features", "SepalLength", "SepalWidth", "PetalLength", "PetalWidth"));

次に学習するためのアルゴリズムを追加。

    pipeline.Add(new StochasticDualCoordinateAscentClassifier());

SDCA法として、scikit-learnの lightning.classification.SDCAにも実装されてますね

推論するデータラベルを数値に変換する対応を設定。先程のDictionarizer への入力する文字列と推論結果のIrisPredictionへの変換を意味するみたい(よくわかってない)。

    pipeline.Add(new PredictedLabelColumnOriginalValueConverter() {     PredictedLabelColumn = "PredictedLabel" });

ここで、ようやく学習データと推論値との関係を設定して学習をセットして開始。

    var model = pipeline.Train<IrisData, IrisPrediction>();

この時点で学習が2つのスレッドを使ってあっという間に最適化されます。
最後に、本当に結果があっているかをチェックするため推論してみます。
IrisData のクラスに、パラメータをセットして model.Predict で結果を得ます。

    var prediction = model.Predict(new IrisData()
    {
        SepalLength = 3.3f,
        SepalWidth = 1.6f,
        PetalLength = 0.2f,
        PetalWidth = 5.1f,
    });

model.Predict の戻り値は、IrisPrediction となっているので、その結果を文字列として表示します。

    Console.WriteLine($"Predicted flower type is: {prediction.PredictedLabels}");

まとめ

個人的な感想

  • パイプラインというデータ処理の流れに、処理をadd していくスタイルなので流れが良くわかる。
  • Python の numpy のように行列データにくらべて、データをクラスで定義するので内容はわかりやすいが、他のデータなどを行う場合など使い回しするときにためらう。
  • Python だったら、このような問題を解く方法は山のようにあるのに対して、.NET での選択肢は少ないなぁと思った
  • 普段はpython で jupyter-notebook で試行錯誤しながらデータ処理しているので、このようなプログラミングタイプは内容をしっかりわかっていないと書けない
  • 簡単な識別問題は ML.NETで Deep Learningをしたい場合には CNTK ということですよね?
4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?