Je regarde un fichier cs ici: https://www.Microsoft.com/net/learn/apps/machine-learning-and-ai/ml-dotnet/get-started/windows et tout fonctionne bien.
Maintenant, j'aimerais améliorer l'exemple: j'aimerais prédire un ensemble de données numérique et non un ensemble de données numérique, par exemple, la sortie d'un affichage à sept segments.
Voici mon jeu de données super facile, la dernière colonne est le nombre int que je veux prédire:
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
Et voici mon code de test:
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();
}
Comme vous pouvez le constater, il est très similaire à l'exemple fourni, à l'exception de la dernière colonne ("Label") qui traite le problème car je dois prédire un nombre et non une chaîne. J'essaye avec:
pipeline.Add(new ColumnConcatenator("Label", "DigitValue"));
mais ça ne marche pas, exception:
Training label column 'Label' type is not valid for multi-class: Vec<R4, 1>. Type must be R4 or R8.
Je suis sûr que quelque chose me manque, mais en réalité je ne trouve rien sur Internet qui puisse m'aider à résoudre ce problème.
METTRE &AGRAVE; JOUR
J'ai trouvé que l'ensemble de données doivent avoir une colonne Label
comme celle-ci:
[Column("7")] [ColumnName("Label")] public float Label;
et la colonne DigitPrediction
une colonne Score
comme:
public class DigitPrediction
{
[ColumnName("Score")] public float[] Score;
}
Maintenant, le système "fonctionne" et j'ai, en tant que prediction.Score
, une valeur Single[]
dans laquelle l'index associé à la valeur la plus élevée correspond à la valeur prédite . Est-ce la bonne approche?
UPDATE 2 - Exemple de code complet
Après la réponse et d’autres suggestions, j’ai obtenu le bon résultat. Si vous en avez besoin, vous pouvez trouver le code complet ici .
On dirait que vous auriez besoin d'ajouter ce champ à votre classe 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
}
Et je pense que vous auriez besoin de changer la ligne où il écrit le résultat pour:
Console.WriteLine($"Predicted digit is: {prediction.ExpectedDigit}");
Une dernière chose, il semble y avoir un bogue dans l’API où le chiffre attendu sera décalé d’un chiffre, mais si vous le décalez en ajoutant +1 à la valeur prédite, il s’agira de la valeur correcte. Je m'attends à ce qu'ils résolvent ce problème à l'avenir, il y a un problème: ( https://github.com/dotnet/machinelearning/issues/235 )
Vous pouvez également essayer d’échanger ColumnConcatenator avec ColumnCopier, dans le pipeline, pour la colonne Label.
pipeline.Add(new ColumnCopier ("Label", "DigitValue"));
Cela indiquera au pipeline la colonne qui est l'étiquette, mais la sortie de ColumnCopier ne sera pas un vecteur, contrairement à la sortie de ColumnConcatenator.
Et pourrait également ajouter une colonne Score.
Maintenant, il est essentiel de suivre le modèle:
Fonctionnalités de colonne (toutes les fonctionnalités - elles doivent avoir le même type)
Étiquette de colonne (vos "réponses")
Si le jeu de données d'origine a une autre colonne de réponse, utilisez:
pipeline.Add(new ColumnCopier(("DigitValue", "Label")));
Le premier est la source, le second est la destination. Comme je vois, double '(' est requis.