KMeans ignores example weights in centroid updates and default initialization

未关闭
#7,876 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
40/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
csharp

调研方向

Start with src/Microsoft.ML.KMeansClustering/KMeansPlusPlusTrainer.cs: the centroid accumulation around lines 1114-1142, the division by cluster size near 1213-1214, and the K-means|| sampling and candidate weighting near 843-888 and 918-928. First run the one-cluster repro to confirm the centroid is 5 rather than the expected 9. Done means centroids are weighted means and the K-means|| path uses example weights, with tests covering both.

由索引模型根据 Issue 内容生成。

描述

area-Trainers bug

KMeans accepts an ExampleWeightColumnName, but appears to ignore weight magnitudes during the main training loop and the default K-means|| initialization.

Expected behavior

Centroids should be weighted means of their assigned examples:

centroid = sum(weight * features) / sum(weight)

Initialization should also account for example weights where appropriate.

Actual behavior

Source inspection shows:

  • Centroid updates accumulate unweighted feature vectors and divide by the number of assigned rows.
  • Default K-means|| initialization samples using distance-based weights without incorporating example weights. Its candidate-reduction step also counts rows rather than summing their weights.
  • Explicit K-means++ initialization does use example weights, but the subsequent training loop still computes unweighted centroids.

Consequently, a weight column can affect initialization differently depending on the selected algorithm, without producing weighted centroid updates.

Minimal repro

The following example isolates the centroid calculation by requesting one cluster:

using System;
using Microsoft.ML;
using Microsoft.ML.Data;
using Microsoft.ML.Trainers;

var mlContext = new MLContext(seed: 1);
var data = mlContext.Data.LoadFromEnumerable(new[]
{
    new Input { Features = new[] { 0f }, Weight = 1f },
    new Input { Features = new[] { 10f }, Weight = 9f }
});

var model = mlContext.Clustering.Trainers.KMeans(
    new KMeansTrainer.Options
    {
        NumberOfClusters = 1,
        ExampleWeightColumnName = nameof(Input.Weight),
        InitializationAlgorithm =
            KMeansTrainer.InitializationAlgorithm.KMeansPlusPlus,
        NumberOfThreads = 1
    }).Fit(data);

VBuffer<float>[] centroids = default;
model.Model.GetClusterCentroids(ref centroids, out _);
Console.WriteLine(centroids[0].GetValues()[0]);

public class Input
{
    [VectorType(1)]
    public float[] Features { get; set; } = new float[1];

    public float Weight { get; set; }
}

Expected centroid: 9, from (1 * 0 + 9 * 10) / (1 + 9).

Source inspection predicts 5, the unweighted mean. This repro has not yet been executed.

Relevant source

Found while improving the weight-column documentation for #6746 in #7875.

[!NOTE]
This report was drafted with GitHub Copilot assistance.

主要语言
C#
星标
9.4k
派生
2k
平均合并
2 天 18 小时
30 天内合并 PR
64

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

dotnet/machinelearning 的其他 Issue

查看 dotnet/machinelearning 的全部 Issue

相似的 Issue

更多 C# Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。