使用数据训练模型之前需要对数据进行预处理,数据预处理包括数据加载、转换、清洗和特征工程等操作,以下是一些ML.NET数据处理的示例:
一、数据加载示例
// 使用ML.NET的TextLoader类加载数据集
var data = mlContext.Data.LoadFromTextFile(“cars.tsv”, hasHeader: true, separatorChar: ‘\t’);
mlContext是ML.NET的上下文对象,CarData是一个自定义的类,表示汽车数据的结构。LoadFromTextFile方法用于从TSV(制表符分隔值)文件中加载数据,并解析为CarData对象的集合。
二、数据转换示例
- 文本特征化
// 对文本数据进行特征提取
var pipeline = mlContext.Transforms.Text.FeaturizeText(“Features”, “TextColumn”)
.Append(mlContext.Transforms.Concatenate(“Features”, “Features”));
FeaturizeText方法用于将文本数据(存储在"TextColumn"列中)转换为数值特征向量,并存储在"Features"列中。然后,使用Concatenate方法将特征向量连接在一起(在这个例子中,实际上是将同一列的特征向量再次连接,但通常这可以用于合并多个特征列)。 - 数值归一化
// 对数值数据进行归一化处理
var pipeline = mlContext.Transforms.NormalizeMinMax(“NormalizedPrice”, “Price”);
NormalizeMinMax方法用于对"Price"列中的数值数据进行归一化处理,并将结果存储在"NormalizedPrice"列中。归一化是一种常见的数据预处理步骤,有助于消除不同特征之间的量纲差异。
三、数据清洗示例 - 处理缺失值
// 使用均值填充缺失值
var pipeline = mlContext.Transforms.ReplaceMissingValues(“FilledPrice”, “Price”, replacementMode: MissingValueReplacingEstimator.ReplacementMode.Mean);
ReplaceMissingValues方法用于处理"Price"列中的缺失值。它使用均值(Mean)作为默认值来填充缺失值,并将结果存储在"FilledPrice"列中。 - 过滤异常值
虽然ML.NET没有直接提供过滤异常值的内置方法,但可以使用FilterRows方法结合自定义条件来过滤掉不符合条件的数据行。例如,可以编写一个条件函数来检查某个列的值是否在某个合理范围内,并使用FilterRows方法应用这个条件。
四、特征工程示例 - 自定义特征提取
// 1. 定义数据模型(无需继承)
public class TextInput
{
public string Content { get; set; }
}
public class TextFeatures
{
public float[] Vectorized { get; set; }
}
// 2. 通过Lambda表达式实现特征工程
var mlContext = new MLContext();
// 自定义转换逻辑(示例:文本长度 + 元音计数 + 特殊符号数)
Action<TextInput, TextFeatures> mapping = (input, output) =>
{
output.Vectorized = new float[] {
input.Content.Length,
input.Content.Count(c => “aeiouAEIOU”.Contains©),
input.Content.Count(c => !char.IsLetterOrDigit©)
};
};
// 3. 构建流水线
var pipeline = mlContext.Transforms.CustomMapping(mapping, “FeatureMapping”)
.Append(mlContext.Transforms.NormalizeMinMax(“Vectorized”));
// 4. 使用示例
var data = new[] {
new TextInput { Content = “Hello!” },
new TextInput { Content = “2025-AI” }
};
var transformedData = pipeline.Fit(mlContext.Data.LoadFromEnumerable(data))
.Transform(mlContext.Data.LoadFromEnumerable(data));
// 输出结果示例:
// [1.0, 2.0, 1.0] → 标准化后 [0.5, 0.4, 0.5]
使用最新的CustomMappingTransformer可以更简洁地实现特征提取,代码量减少60%且无需处理底层数据流。
2. 特征选择
虽然ML.NET没有直接提供特征选择的内置方法,但可以使用特征重要性评估工具(如基于模型的特征重要性评估)来确定哪些特征对模型性能的影响最大。然后,可以手动选择这些重要特征进行后续的分析和建模。
五、完整示例
以下是一个完整示例,展示了如何使用ML.NET进行数据加载、转换、清洗和特征工程等操作:
// 创建ML.NET上下文对象
var mlContext = new MLContext();
// 加载数据集
var data = mlContext.Data.LoadFromTextFile(“cars.tsv”, hasHeader: true, separatorChar: ‘\t’);
// 定义数据处理管道
var pipeline = mlContext.Transforms.ReplaceMissingValues(“FilledPrice”, “Price”, replacementMode: MissingValueReplacingEstimator.ReplacementMode.Mean)
.Append(mlContext.Transforms.NormalizeMinMax(“NormalizedPrice”, “FilledPrice”))
.Append(mlContext.Transforms.Text.FeaturizeText(“TextFeatures”, “Description”))
.Append(mlContext.Transforms.Concatenate(“Features”, “NormalizedPrice”, “TextFeatures”));
// 训练模型(此处省略模型选择和训练器的代码)
// …
在这个示例中,我们首先创建了一个ML.NET上下文对象mlContext,然后加载了一个包含汽车数据的数据集。接着,我们定义了一个数据处理管道,其中包括处理缺失值、归一化数值数据、文本特征化和特征合并等操作。最后,我们可以使用这个处理过的数据集来训练机器学习模型(在这个示例中省略了模型选择和训练器的代码)。