ML.NET: Как решить «MatrixColumnIndex должен быть известным ключом U4 мощности, но вместо этого является ключом»

#c# #.net #ml.net

Вопрос:

Я пытаюсь адаптировать следующее ML.NET Пример рекомендации продукта C# для моего собственного варианта использования в тесте на проверку концепции : https://github.com/dotnet/machinelearning-samples/tree/master/samples/csharp/getting-started/MatrixFactorization_ProductRecommendation

Однако в моем наборе данных у меня есть два очень больших числовых идентификатора. Мой набор данных выглядит так:

 ProductID,CoPurchaseProductID
55006911127001,55006910976001
55006910976001,55006911127001
55006911328001,55006909963001
55006907339001,55006909963001
 

Вот исходный код

 var traindata = mlContext.Data.LoadFromTextFile(path:TrainingDataLocation,
    columns: new[]
            {
                new TextLoader.Column("Label", DataKind.Single, 0),
                new TextLoader.Column(name:nameof(ProductEntry.ProductID), dataKind:DataKind.UInt32, source: new [] { new TextLoader.Range(0) }, keyCount: new KeyCount(262111)), 
                new TextLoader.Column(name:nameof(ProductEntry.CoPurchaseProductID), dataKind:DataKind.UInt32, source: new [] { new TextLoader.Range(1) }, keyCount: new KeyCount(262111))
            },
    hasHeader: true,
    separatorChar: 't');
 

и я хочу сделать что-то вроде

 var traindata = mlContext.Data.LoadFromTextFile(path:TrainingDataLocation,
        columns: new[]
                {
                    new TextLoader.Column("Label", DataKind.Single, 0),
                    new TextLoader.Column(name:nameof(ProductEntry.ProductID), dataKind:DataKind.UInt64, source: new [] { new TextLoader.Range(0) }, keyCount: new KeyCount(99999999999999)), 
                    new TextLoader.Column(name:nameof(ProductEntry.CoPurchaseProductID), dataKind:DataKind.UInt64, source: new [] { new TextLoader.Range(1) }, keyCount: new KeyCount(99999999999999))
                },
        hasHeader: true,
        separatorChar: ',');

 

Класс продукта:

 public class ProductEntry
{
   [KeyType(count : 99999999999999)]
   public Int64 ProductID { get; set; }

   [KeyType(count : 99999999999999)]
   public Int64 CoPurchaseProductID { get; set; }
}
 

Тем не менее, я все еще получаю следующую ошибку:

 System.InvalidOperationException
 HResult=0x80131509
 Message=Column 'ProductID' with role MatrixColumnIndex should be a known cardinality U4 key, but is instead 'Key<UInt64, 0-99999999999998>'
 Source=Microsoft.ML.Recommender
 StackTrace:
  at Microsoft.ML.Recommender.RecommenderUtils.CheckRowColumnType(RoleMappedData data, ColumnRole role, Columnamp; col, Boolean isDecode)
  at Microsoft.ML.Recommender.RecommenderUtils.CheckAndGetMatrixIndexColumns(RoleMappedData data, Columnamp; matrixColumnIndexColumn, Columnamp; matrixRowIndexColumn, Boolean isDecode)
  at Microsoft.ML.Trainers.MatrixFactorizationTrainer.TrainCore(IChannel ch, RoleMappedData data, RoleMappedData validData)
  at Microsoft.ML.Trainers.MatrixFactorizationTrainer.Fit(IDataView trainData, IDataView validationData)
  at ProductRecommender.Program.Main(String[] args) in ***ML.NETmachinelearning-samplessamplescsharpgetting-startedMatrixFactorization_ProductRecommendationProductRecommenderProgram.cs:line 62
 

Заранее спасибо

ОБНОВЛЕНИЕ Я обновил свой код, чтобы создать небольшой набор данных и проверить, хорошо ли он создан, но все равно получаю ошибку в последней строке.

 string path = Environment.CurrentDirectory   @"datafile.txt";

// This text is added only once to the file.
if (!File.Exists(path))
{
    // Create a file to write to.
    string createText = "ProductID,CoPurchaseProductID"   Environment.NewLine
                          "55006911127001,55006910976001"   Environment.NewLine
                          "55006910976001,55006911127001"   Environment.NewLine
                          "55006911328001,55006909963001"   Environment.NewLine
                          "55006907339001,55006909963001"   Environment.NewLine;

    File.WriteAllText(path, createText);
}

MLContext mlContext = new MLContext();

var traindata = mlContext.Data.LoadFromTextFile(path: path,
        columns: new[]
        {
            new TextLoader.Column("Label", DataKind.Single, 0),
            new TextLoader.Column(name:nameof(ProductEntry.ProductID), dataKind:DataKind.UInt64, source: new [] { new TextLoader.Range(0) }, keyCount: new KeyCount(99999999999999)),
            new TextLoader.Column(name:nameof(ProductEntry.CoPurchaseProductID), dataKind:DataKind.UInt64, source: new [] { new TextLoader.Range(1) }, keyCount: new KeyCount(99999999999999))
        },
        hasHeader: true,
        separatorChar: ',');
        
//var table = ToDataTable(traindata);
//ShowTable(table);
//Console.ReadLine();

//STEP 3: Your data is already encoded so all you need to do is specify options for MatrxiFactorizationTrainer with a few extra hyperparameters
//        LossFunction, Alpa, Lambda and a few others like K and C as shown below and call the trainer. 
MatrixFactorizationTrainer.Options options = new MatrixFactorizationTrainer.Options();
options.MatrixColumnIndexColumnName = nameof(ProductEntry.ProductID);
options.MatrixRowIndexColumnName = nameof(ProductEntry.CoPurchaseProductID);
options.LabelColumnName= "Label";
options.LossFunction = MatrixFactorizationTrainer.LossFunctionType.SquareLossOneClass;
options.Alpha = 0.01;
options.Lambda = 0.025;
// For better results use the following parameters
//options.K = 100;
//options.C = 0.00001;

var est = mlContext.Recommendation().Trainers.MatrixFactorization(options);

ITransformer model = est.Fit(traindata);
 

Комментарии:

1. Вставленный вами код отлично работает без исключений, доказательство: dotnetfiddle.net/StrSIH Возможно, проблема в текстовом файле, который вы читаете.

2. Спасибо. Я обновил свой вопрос вашим кодом. Он все еще рушится… Еще раз спасибо