实现文本K-Means聚类遇Schema不匹配错误,求解决方案
解决K-Means聚类中的Schema不匹配错误
错误原因
System.ArgumentOutOfRangeException: 'Schema mismatch for input column 'Features': expected scalar or vector of String, got VarVector<Single> (Parameter 'inputSchema')'的核心问题是原始数据模型与转换器输出列的类型冲突:
TextData类中定义的float[] Features属性未被赋值,ML.NET自动推断其类型为Vector<Single>。FeaturizeText转换器会生成可变长度的特征向量(VarVector<Single>),当指定输出列名为"Features"时,与已存在的列类型冲突,触发Schema不匹配错误。
解决方案
1. 修正TextData类定义
移除TextData中冗余的Features属性,特征列由转换器生成,无需在原始数据模型中声明:
class TextData { public string? Text { get; set; } public int Index { get; set; } }
2. 修正簇中心获取逻辑
当前代码从转换后的数据中提取Centroid列会得到大量重复值(每个样本对应所属簇的中心),正确做法是从训练好的K-Means模型中直接提取所有簇的中心:
// 训练模型后,提取K-Means参数 var kmeansModel = model.LastTransformer as KMeansModelParameters; var clusterCenters = kmeansModel.Centroids.ToArray();
3. 完整修改后的聚类循环代码
for (int k = 2; k <= 10; k++) { // 创建管道:将文本列转换为特征向量 var pipeline = context.Transforms.Text.FeaturizeText( outputColumnName: "Features", inputColumnName: "Text") .Append(context.Clustering.Trainers.KMeans( featureColumnName: "Features", numberOfClusters: k)); var model = pipeline.Fit(data); var transformedData = model.Transform(data); // 获取聚类结果 var clusterAssignments = transformedData.GetColumn<uint>("PredictedLabel").ToArray(); var kmeansModel = model.LastTransformer as KMeansModelParameters; var clusterCenters = kmeansModel.Centroids.ToArray(); var features = transformedData.GetColumn<float[]>("Features").ToArray(); var silhouetteScore = ComputeSilhouetteScore(features, clusterAssignments, clusterCenters); silhouetteScores[k - 2] = silhouetteScore; }
额外优化建议
- 处理文本中不存在"Description: "的情况,避免索引越界:
int descIndex = text.IndexOf("Description: "); string description = descIndex == -1 ? string.Empty : text.Substring(descIndex + "Description: ".Length);
内容的提问来源于stack exchange,提问作者Gerald Hughes
相关产品推荐
相关产品推荐

