我有一个关于训练可以预测名称是否为女性的 ML.NET 的问题。该模型可以使用这样的管道进行训练:
var mlContext = new MLContext();
IDataView trainingDataView = mlContext.Data.LoadFromEnumerable(trainingData);
var dataPrepPipeline = mlContext
.Transforms
.Text
.FeaturizeText("FirstNameFeaturized", "FirstName")
.Append(mlContext.Transforms.Text.FeaturizeText("MiddleNameFeaturized", "MiddleName"))
.Append(mlContext.Transforms.Text.FeaturizeText("LastNameFeaturized", "LastName"))
.Append(mlContext.Transforms.Concatenate(
"Features",
"FirstNameFeaturized",
"MiddleNameFeaturized",
"LastNameFeaturized"))
.Append(mlContext.Transforms.NormalizeMinMax("Features", "Features"))
.AppendCacheCheckpoint(mlContext);
var prepPipeline = dataPrepPipeline.Fit(trainingDataView);
var preprocessedData = prepPipeline.Transform(trainingDataView);
var trainer = dataPrepPipeline.Append(mlContext
.BinaryClassification
.Trainers
.AveragedPerceptron(labelColumnName: "IsFemale", numberOfIterations: 10, featureColumnName: "Features"));
ITransformer trainedModel = trainer.Fit(preprocessedData);
我遗漏了trainingData
从代码。该模型如下所示:public class Person
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public bool IsFemale { get; set; }
}
然后我从某个地方(数据库、csv 等)获取人员列表并将其转换为 Person
对象。作为将人员转换为
Person
的一部分我正在使用如下代码:var trainingData = new List<Person>();
trainingData.AddRange(persons.Select(p => new Person
{
IsFemale = p.IsFemale,
FirstName = p.FirstName ?? "unknown",
MiddleName = p.MiddleName ?? "unknown",
LastName = p.LastName ?? "unknown"
}));
您可能想知道为什么我插入 unknown
如果名称部分之一为空。这样做是因为如果任何属性为空,则构建 ML.NET 管道将失败。所以这是我的问题。将名称部分设置为
unknown
时我怀疑这会产生一个糟糕的模型。示例:如果我有一个名字为 Thomas
的男性而我没有其他部分,会产生 Thomas unknown unknown
.如果缺少中间名和姓氏,这不会增加其他人被归类为非女性的可能性吗?假设我们有一个名为 Anna
的人我们没有剩下的部分。这将产生 Anna unknown unknown
这与已标记为非女性的另一个接近。
最佳答案
在 .NET Core 3.1 中使用 Microsoft.ML.AutoML 0.17.2,并对包含空值的数据集执行二进制分类实验,我发现如果我清理空值并替换它们,我不会收到任何错误和合理的结果与 任意 字符串,包括一个空字符串 .我当前的管道正在一次性使用所有文本列 - 我不确定这与您正在做的事情相比是否有所不同:
var options = new TextFeaturizingEstimator.Options();
options.KeepNumbers = true;
options.WordFeatureExtractor = null;
options.CharFeatureExtractor = null;
...
var initializer = mlContext.Transforms.Conversion.ConvertType("Label", "Column1", Microsoft.ML.Data.DataKind.Boolean)
.Append(mlContext.Transforms.Text.FeaturizeText("Features", options, propertyNames));
var initializedData = initializer.Fit(trainDataView).Transform(trainDataView);
但关键是它看起来 ML.NET 似乎并不关心你拥有什么,只要它不为空。我尝试了许多填充值,例如“?”、“”、“”和“_”,我得到了最合理的结果。希望这是有道理的,并有助于解决您的问题。
关于ml.net - 使用 ML.NET 训练模型时在空字符串上使用占位符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64758139/