C# ML.净预测分数返回NaN

C# ML.净预测分数返回NaN,c#,ml.net,C#,Ml.net,ML.Net预测分数始终返回NaN(空) 我的想法是教一个年轻人学习我的家庭日常生活。 我尝试了几个不同的ML.NETNuget包和代码示例,但结果相同:Score==NaN。 下面是一些代码和数据集的一部分,它是从我的家庭自动化系统中记录的 这是MSDN中电影推荐回归示例的变体: public class AutomationData { [LoadColumn(0)] //0 - 6 p

ML.Net预测分数始终返回NaN(空)

我的想法是教一个年轻人学习我的家庭日常生活。 我尝试了几个不同的ML.NETNuget包和代码示例,但结果相同:Score==NaN。 下面是一些代码和数据集的一部分,它是从我的家庭自动化系统中记录的

这是MSDN中电影推荐回归示例的变体:

        public class AutomationData
        {

            [LoadColumn(0)]
            //0 - 6
            public int Day; 
            [LoadColumn(1)]
            //example: 0947 == 9:47am
            public int TimeOfDay; 
            //Device Id
            [LoadColumn(2)]
            public int Device; 
            //This is the State of the device (0 OFF - 1 ON) 
            // Seems it has to be float? (Vector R4)
            [LoadColumn(3)]
            public float Label; 
        }

我希望预测状态返回0或1(开或关)的值,以及一个分数(浮点数),这将显示回归认为它正确的程度。

它返回Nan,因为没有足够的数据进行预测。 我的意思是,矩阵分解会做出一个预测,作为相似值的近似值

在您的示例中,您仅在矩阵分解中使用TimeOfDay和Device列, 因此,对于您想要使用的单一预测(new AutomationData{Device=117,TimeOfDay=0945}),模型返回Nan作为分数,因为它无法从学习的模型中真正预测值

做一个测试,预测一个已知的值,比如

new AutomationData { Device = 73, TimeOfDay = 0910 };
你会得到一个实际分数

此外,您不应该使用与测试相同的列车数据,这会使您的模型评估变得不必要


毕竟,对于您的用例来说,矩阵分解可能不是理想的选择。

谢谢,我想知道我的数据集太小了。我决定尝试一种新的代码方法。我尝试了MSDN的例子来计算出租车票价。这比电影推荐示例更容易理解。它还使用FastTree进行预测。也许我会再填写几周的数据集,然后再次测试培训师。你提到了另一种解决我处境的方法。哪个选项更适合我的项目。谢谢。@user2224583假设这是一个多分类问题,您可以使用LogisticRegressionClassifier、NaiveBayesClassifier或SdcaMultiClassTrainer@user2224583这是一个有效的答案吗?
        public static void  Regression()
        {
            MLContext mlContext = new MLContext();
            IDataView trainingDataView = LoadData(mlContext).training;
            IDataView testDataView = LoadData(mlContext).test;

            ITransformer model = BuildAndTrainModel(mlContext, trainingDataView);
            EvaluateModel(mlContext, testDataView, model);

            UseModelForSinglePrediction(mlContext, model);

        }

        public static (IDataView training, IDataView test) LoadData(MLContext mlContext)
        {
            var trainingDataPath = Path.Combine(Environment.CurrentDirectory, "MachineLearning/Data", "data.csv");
            var testDataPath = Path.Combine(Environment.CurrentDirectory, "MachineLearning/Data", "data.csv");
            IDataView trainingDataView = mlContext.Data.LoadFromTextFile<AutomationData>(trainingDataPath, hasHeader: true, separatorChar: ',');
            IDataView testDataView = mlContext.Data.LoadFromTextFile<AutomationData>(testDataPath, hasHeader: true, separatorChar: ',');
            return (trainingDataView, testDataView); 
        }

        public static ITransformer BuildAndTrainModel(MLContext mlContext, IDataView trainingDataView)
        {
            IEstimator<ITransformer> estimator = mlContext.Transforms.Conversion.MapValueToKey(outputColumnName: "deviceEncoded", inputColumnName: "Device")
           .Append(mlContext.Transforms.Conversion.MapValueToKey(outputColumnName: "timeOfDayEncoded", inputColumnName: "TimeOfDay"))
            .Append(mlContext.Transforms.Conversion.MapValueToKey(outputColumnName: "dayEncoded", inputColumnName: "Day"));

            var options = new MatrixFactorizationTrainer.Options
            {
                MatrixColumnIndexColumnName = "deviceEncoded",
                MatrixRowIndexColumnName = "timeOfDayEncoded",
                LabelColumnName = "Label",
                NumberOfIterations = 20,
                ApproximationRank = 100
            };

            var trainerEstimator = estimator.Append(mlContext.Recommendation().Trainers.MatrixFactorization(options));


            ITransformer model = trainerEstimator.Fit(trainingDataView);
            return model; 
        }

        public static void EvaluateModel(MLContext mlContext, IDataView testDataView, ITransformer model)
        {

            var prediction = model.Transform(testDataView);
            var metrics = mlContext.Regression.Evaluate(prediction, label: DefaultColumnNames.Label, score: DefaultColumnNames.Score);

            Console.WriteLine("Rms: " + metrics.Rms.ToString());
            Console.WriteLine("RSquared: " + metrics.RSquared.ToString());

        }

        public static void UseModelForSinglePrediction(MLContext mlContext, ITransformer model)
        {

            var predictionEngine = model.CreatePredictionEngine<AutomationData, AutomationPrediction>(mlContext);
            var testInput = new AutomationData { Device = 117, TimeOfDay = 0945 };
            var automationPrediction = predictionEngine.Predict(testInput);
            Console.WriteLine("Prediction Score: " + Math.Round(automationPrediction.Score, 1)); //Is Always 'NaN' (null)
            if (Math.Round(automationPrediction.Score, 1) > 3.5)
            {
                Console.WriteLine("State: " + testInput.Label);
            }
            else
            {
                Console.WriteLine("State " + testInput.Label);
            }
        }

    }
Day,TimeOfDay,Device,State
6,0827,999,1
6,0827,117,1
6,0827,117,0
6,0838,18,1
6,0838,79,1
6,0838,6,1
6,0901,117,1
6,0908,999,0
6,0910,73,0
6,0913,72,1
6,0914,72,0
6,0915,79,0
6,0915,6,0
6,0915,5,0
6,0915,4,0
6,0915,18,0
6,1015,18,1
6,1015,79,1
6,1015,6,1
6,1015,5,1
6,1015,4,1
6,1726,18,1
6,1726,79,1
6,1726,51,0
6,1726,128,0
6,1726,69,0
new AutomationData { Device = 73, TimeOfDay = 0910 };