ML.NET绘制K-means聚类结果?

我在一个无监督聚类场景中试验ML.NET。我的起始数据少于30条记录,每条记录有5个特征,数据存储在一个TSV文件中,例如(当然标签将被忽略):

Label   S1   S2   S3   S4   S5alpha   0.274167987321712   0.483359746434231   0.0855784469096672   0.297939778129952   0.0332805071315372beta   0.378208470054279   0.405409549510871   0.162317151706584   0.292342604802355   0.0551994848048085...

我的起点是iris教程,这是一个K-means聚类的示例。在我的案例中,我想要3个聚类。由于我只是在学习,一旦创建了模型,我想用它在原始文件的一个副本中为每条记录添加聚类数据,以便我可以检查它们并绘制散点图。

我从以下训练代码开始(假设MyModel是表示其模型的POCO类,具有S1S5的属性):

// 加载数据MLContext mlContext = new MLContext(seed: 0);IDataView dataView = mlContext.Data.LoadFromTextFile<MyModel>    (dataPath, hasHeader: true, separatorChar: '\t');// 训练模型const string featuresColumnName = "Features";EstimatorChain<ClusteringPredictionTransformer<KMeansModelParameters>>    pipeline = mlContext.Transforms    .Concatenate(featuresColumnName, "S1", "S2", "S3", "S4", "S5")    .Append(mlContext.Clustering.Trainers.KMeans(featuresColumnName,    numberOfClusters: 3));TransformerChain<ClusteringPredictionTransformer<KMeansModelParameters>>    model = pipeline.Fit(dataView);// 保存模型using (FileStream fileStream = new FileStream(modelPath,    FileMode.Create, FileAccess.Write, FileShare.Write)){    mlContext.Model.Save(model, dataView.Schema, fileStream);}

然后,我加载保存的模型,从原始数据中读取每条记录,并获取其聚类ID。这听起来有点复杂,但我的学习意图在这里是检查结果,在玩弄它们之前。结果应该保存在一个新文件中,包含质心坐标和点坐标。

然而,似乎这个API不够透明,无法轻松访问质心;我只找到一个帖子,这篇帖子相当旧,其代码不再编译。我将其用作通过反射恢复数据的提示,但这是一个权宜之计。

此外,我不确定框架提供的数据的细节。我可以看到每个质心有3个向量(在示例代码中命名为cx cy cz),每个向量有5个元素(我认为是5个特征,按其连接的输入顺序,即从S1到S5);此外,每个预测提供一个三倍距离(dx dy dz)。如果这些假设是正确的,我可以像这样为每条记录分配一个聚类ID:

// 对于原始数据中的每条记录foreach (MyModel record in csvReader.GetRecords<MyModel>()){    // 获取其聚类ID    MyPrediction prediction = predictor.Predict(record);    // 只获取一次质心,因为当然它们对于所有记录来说都是相同的    // 这些记录参考它们的距离    if (cx == null)    {        // 获取质心(通过反射...):        // https://github.com/dotnet/machinelearning/blob/master/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Clustering/KMeansWithOptions.cs#L49        // https://social.msdn.microsoft.com/Forums/azure/en-US/c09171c0-d9c8-4426-83a9-36ed72a32fe7/kmeans-output-centroids-and-cluster-size?forum=MachineLearning        VBuffer<float>[] centroids = default;        var last = ((TransformerChain<ITransformer>)model)            .LastTransformer;        KMeansModelParameters kparams = (KMeansModelParameters)            last.GetType().GetProperty("Model").GetValue(last);        kparams.GetClusterCentroids(ref centroids, out int k);        cx = centroids[0].GetValues().ToArray();        cy = centroids[1].GetValues().ToArray();        cz = centroids[2].GetValues().ToArray();    }    float dx = prediction.Distances[0];    float dy = prediction.Distances[1];    float dz = prediction.Distances[2];    // ... 计算并保存记录的完整细节 ...}

鉴于这种情况,我假设我可以以下列方式获取预训练模型中每条记录位置的所有细节:

  • dx, dy, dz 是距离。
  • cx[0] cy[0] cz[0] 加上距离(分别是dx, dy, 和dz)应该是S1点的位置;cx[1] cy[1] cz[1] 加上距离是S2的位置;依此类推直到S5(cx[4]等)。

在这种情况下,我可以将这些数据绘制在3D散点图中。然而,我对ML.NET完全是新手,因此我对这些假设并不确定,很可能我走错了路。能有人指导我正确的方向吗?


回答:

Related Posts

在使用k近邻算法时,有没有办法获取被使用的“邻居”?

我想找到一种方法来确定在我的knn算法中实际使用了哪些…

Theano在Google Colab上无法启用GPU支持

我在尝试使用Theano库训练一个模型。由于我的电脑内…

准确性评分似乎有误

这里是代码: from sklearn.metrics…

Keras Functional API: “错误检查输入时:期望input_1具有4个维度,但得到形状为(X, Y)的数组”

我在尝试使用Keras的fit_generator来训…

如何使用sklearn.datasets.make_classification在指定范围内生成合成数据?

我想为分类问题创建合成数据。我使用了sklearn.d…

如何处理预测时不在训练集中的标签

已关闭。 此问题与编程或软件开发无关。目前不接受回答。…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注