faiss 聚类算法详解(聚类算法源码解析)

 聚类的步骤

  • 初始化中心点(因为聚类效果和初始中心点相关,容易出现局部最优,所以可以多初始化几次)。
  • 根据中心点,计算每个向量到中心点的距离。
  • 根据距离,把向量归属于不同的中心点
  • 然后对中心点周围的向量,累加取平均形成新的中心点。
  • 然后开始新一轮的聚类。
  • 从多次聚类中,选择最优的中心点,训练完成。

代码详解

    for (int redo = 0; redo < nredo; redo++) { ///切换初始的中心点(避免局部最优),

        if (verbose && nredo > 1) {
            printf("Outer iteration %d / %d\n", redo, nredo);
        }   

        // initialize remaining centroids with random points from the dataset
        centroids.resize (d * k); 
        std::vector<int> perm (nx);

        rand_perm (perm.data(), nx, seed + 1 + redo * 15486557L);
        for (int i = n_input_centroids; i < k ; i++) ///n_input_centroids:已有中心点的个数
            memcpy (&centroids[i * d], x + perm[i] * d,
                    d * sizeof (float)); ///初始化中心点

        post_process_centroids (); ///归一化中心点,中心点取整

        if (index.ntotal != 0) {
            index.reset();
        }   

        if (!index.is_trained) {
            index.train (k, centroids.data()); /// 
        }   

        for (int i = 0; i < niter; i++) { ///                                                                                                   
优化中心点(在当前中心点的周围聚集一批点,形成新的中心点,根据新中心点再聚类,直到中心点不再变化,可能会形成局部最优,因为和起始的中心点选择有关>
系)
            double t0s = getmillisecs();
            index.search (nx, x, 1, dis, assign); ///搜索每个向量对应的最近的1个向量(第0层对应的向量)
            InterruptCallback::check(); ///
            t_search_tot += getmillisecs() - t0s;

            err = 0;
            for (int j = 0; j < nx; j++)
                err += dis[j];
            obj.push_back (err);
            ///更新中心点, 把每个中心点周围的点取平均,另外对中心点周围没有点的情况做了处理(d:子空间维度; k:中心点个数)
            int nsplit = km_update_centroids (
                  x, centroids.data(),
                  assign, d, k, nx, frozen_centroids ? n_input_centroids : 0);

            if (verbose) {
                printf ("  Iteration %d (%.2f s, search %.2f s): "
                        "objective=%g imbalance=%.3f nsplit=%d       \r",
                        i, (getmillisecs() - t0) / 1000.0,
                        t_search_tot / 1000,
                        err, imbalance_factor (nx, k, assign),
                        nsplit);
                fflush (stdout);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值