在Microsoft.ML(C#)中无法实现KMeans聚类的问题求助
问题分析与修复方案
核心错误点
- 管道未正确添加训练器:ML.NET的
EstimatorChain是不可变对象,Append方法会返回新的管道实例,原代码中没有将返回值重新赋值给pipeline,导致KMeans训练器根本没被加入到管道中,最终预测结果里没有生成Score列,触发Schema不匹配异常。 - 输入模型字段类型错误:
SimpleVector字段标记了[VectorType(3)],但类型却是float,正确类型应该是float[],否则无法正确加载向量数据。 - 输入与预测模型未分离:将输入特征字段和预测输出字段混在同一个类中,容易导致数据加载时的Schema混淆,建议拆分输入模型和预测模型。
修正后的代码示例
拆分模型类
// 仅包含输入特征的模型类 public class SampleInput { [VectorType(3)] public float[] SimpleVector { get; set; } } // 包含预测结果的模型类 public class SamplePrediction { [ColumnName("PredictedLabel")] public uint PredictedClusterId; [ColumnName("Score")] public float[] Distances; }
修正测试方法
[Fact] public void Sample() { var mlContext = new MLContext(seed: 1); var random = new Random().NextDoubleSequence(); var dummyData = new SampleInput[100]; for (int i = 0; i < 100; i++) { var val = (float)random.ElementAt(i); dummyData[i] = new SampleInput { SimpleVector = new float[] { val, val, val } }; } // 加载训练数据 var trainingData = mlContext.Data.LoadFromEnumerable(dummyData.Take(50)); // 正确构建管道:Append后重新赋值 var pipeline = mlContext.Transforms.Concatenate("Features", "SimpleVector") .Append(mlContext.Clustering.Trainers.KMeans("Features", numberOfClusters: 3)); var trainedModel = pipeline.Fit(trainingData); // 加载测试数据 var testData = mlContext.Data.LoadFromEnumerable(dummyData.TakeLast(50)); var predictions = trainedModel.Transform(testData); // 评估聚类结果 var metrics = mlContext.Clustering.Evaluate(predictions, scoreColumnName: "Score", featureColumnName: "Features"); }
额外说明
- 当指定
numberOfClusters:3时,Score列会是固定大小为3的向量,此时可以在SamplePrediction的Distances字段上添加[VectorType(3)]特性,这样能让ML.NET在类型检查时更严谨,避免潜在的Schema问题。 - 如果仍然遇到异常,检查训练和测试数据的特征维度是否一致,确保所有输入样本的向量长度符合
VectorType指定的大小。
内容的提问来源于stack exchange,提问作者Fredrik Claesson
相关产品推荐
相关产品推荐

