web-dev-qa-db-ja.com

ML.NETを使用して整数値を予測する方法は?

私はここでcsファイルを見ています: https://www.Microsoft.com/net/learn/apps/machine-learning-and-ai/ml-dotnet/get-started/windows =そしてすべてがうまく機能します。

ここで、例を改善したいと思います。たとえば、7セグメントディスプレイの出力を予測するなど、数値文字列データセットではなく、数値のみのデータセットを予測したいと思います。

これが私の非常に簡単なデータセットです。最後の列は、予測したい整数です。

1,0,1,1,1,1,1,0
0,0,0,0,0,1,1,1
1,1,1,0,1,1,0,2
1,1,1,0,0,1,1,3
0,1,0,1,0,1,1,4
1,1,1,1,0,0,1,5
1,1,1,1,1,0,1,6
1,0,0,0,0,1,1,7
1,1,1,1,1,1,1,8
1,1,1,1,0,1,1,9

そして、これが私のテストコードです:

public class Digit
{
    [Column("0")] public float Up;

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

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

    [Column("3")] public float UpLeft;
    [Column("4")] public float BottomLeft;
    [Column("5")] public float TopRight;
    [Column("6")] public float BottomRight;

    [Column("7")] [ColumnName("DigitValue")]
    public float DigitValue;
}

public class DigitPrediction
{
    [ColumnName("PredictedDigits")] public float PredictedDigits;
}

public PredictDigit()
{
    var pipeline = new LearningPipeline();
    var dataPath = Path.Combine("Segmenti", "segments.txt");
    pipeline.Add(new TextLoader<Digit>(dataPath, false, ","));
    pipeline.Add(new ColumnConcatenator("Label", "DigitValue"));
    pipeline.Add(new ColumnConcatenator("Features", "Up", "Middle", "Bottom", "UpLeft", "BottomLeft", "TopRight", "BottomRight"));
    pipeline.Add(new StochasticDualCoordinateAscentClassifier());
    var model = pipeline.Train<Digit, DigitPrediction>();
    var prediction = model.Predict(new Digit
    {
        Up = 1,
        Middle = 1,
        Bottom = 1,
        UpLeft = 1,
        BottomLeft = 1,
        TopRight = 1,
        BottomRight = 1,
    });

    Console.WriteLine($"Predicted digit is: {prediction.PredictedDigits}");
    Console.ReadLine();
}

ご覧のとおり、文字列ではなく数値を予測する必要があるため、最後の列( "Label")の処理を除いて、提供されている例と非常によく似ています。私は試してみます:

pipeline.Add(new ColumnConcatenator("Label", "DigitValue"));

しかし、それは機能しません、例外:

Training label column 'Label' type is not valid for multi-class: Vec<R4, 1>. Type must be R4 or R8.

私は何かを見逃していると確信していますが、実際にはこの問題を解決するのに役立つものをインターネット上で見つけることができません。

[〜#〜]更新[〜#〜]

データセットに次のようなLabel列があることがわかりました。

[Column("7")] [ColumnName("Label")] public float Label;

DigitPrediction a Score列は次のようになります:

public class DigitPrediction
{
    [ColumnName("Score")] public float[] Score;
}

これでシステムは「機能」し、prediction.Score a Single[] valueここで、高い値に関連付けられたインデックスは予測値です。それは正しいアプローチですか?

UPDATE 2-完全なコード例

答えと他の提案に従って、私は正しい結果を得ました、あなたがそれを必要とするならば、あなたは完全なコードを見つけることができます ここ

8
Rowandish

このフィールドをクラスに追加する必要があるようですDigitPrediction

public class DigitPrediction
{
    [ColumnName("PredicatedLabel")]
    public uuint ExpectedDigit; // <-- This is the predicted value

    [ColumnName("Score")]
    public float[] Score; // <-- This is the probability that the predicted value is the right classification
}

そして、結果を書き込む行を次のように変更する必要があると思います。

    Console.WriteLine($"Predicted digit is: {prediction.ExpectedDigit}");

もう1つ、APIにバグがあり、予想される桁が1桁ずれているようですが、予測値に+1を追加してシフトすると、正しい値になります。私は彼らが将来これを修正することを期待しています、それには問題があります:( https://github.com/dotnet/machinelearning/issues/235

4
Kyle B

パイプラインで、Label列のColumnConcatenatorをColumnCopierと交換してみることもできます。

pipeline.Add(new ColumnCopier ("Label", "DigitValue"));

これは、どの列がLabelであるかをパイプラインに示しますが、ColumnConcatenatorの出力とは異なり、ColumnCopierの出力はベクトルにはなりません。

同様に、スコア列を追加することもできます。

1
amy8374

さて、パターンに従うことが不可欠です:

  • 列の機能(すべての機能-同じタイプである必要があります)

  • 列ラベル(あなたの「答え」)

元のデータセットに別の回答列がある場合は、次を使用します。

pipeline.Add(new ColumnCopier(("DigitValue", "Label")));

1つ目は送信元、2つ目は宛先です。ご覧のとおり、double '('が必要です。

0
Arhisan