c# - ML.Net 预测分数返回 NaN
问题描述
ML.Net 预测分数始终返回 NaN(空)。
这个想法是教一个回归算法来学习我的家庭日常生活。我尝试了几种 ML.Net nuget 包和代码示例的变体,但结果相同: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;
}
public class AutomationPrediction
{
public float Label;
public float Score;
}
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);
}
}
}
这是回归算法尝试使用的 data.csv 的剪辑。
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
我希望预测状态返回 0 或 1(开或关)的值,以及一个分数(浮点数),它将显示回归认为它是正确的接近程度。
解决方案
它返回Nan,因为没有足够的数据来进行预测。我的意思是,矩阵分解将预测作为相似值的近似值。
在您的示例中,您仅在矩阵分解中使用 TimeOfDay 和 Device 列,因此对于您要使用的单个预测(新 AutomationData { Device = 117, TimeOfDay = 0945 }),模型将Nan作为分数返回,因为,它不能真正从学习模型中预测出一个值。
做一个测试,预测一个已知的值,比如
new AutomationData { Device = 73, TimeOfDay = 0910 };
你会得到一个实际的分数。
此外,您不应使用与测试相同的训练数据,这会使您的模型评估变得不必要。
毕竟,矩阵分解可能不是您的用例的理想选择。
推荐阅读
- hibernate - Hibernate 带宽问题:比 SQL Developer 花费更多的时间
- azure - 带有 PowerShell 5+ 的 Azure 的应用程序、创建日期、权限和 2FA 设置列表
- go - 如果我的密钥都被命名为“密钥”,如何从 BSON 获取 JSON?
- git - 列出 git 中最新编辑的文件
- javascript - 我需要在 Gatsby 插件中设置什么?
- selenium - webdriver W3C 协议是什么意思。它与 JSON 协议有何不同
- java - HTTP 响应显示 Accept=multipart/form-data 但未设置此标头并设置 CamelAcceptContentType, "application/json"
- oracle - 计数在使用条件的触发器中不起作用
- python - 如何读取文本文件的特定部分(Py 3x)
- java - 我运行我的 android 应用程序,但没有应用程序启动并在日志中显示错误?我该如何解决?