Shark源码分析(六):k-means算法

Shark源码分析(六):k-means算法

k-means算法是原型聚类算法中一个非常典型的算法。关于聚类算法,我之后应该会在博客中进行详细说明。

对于整个聚类算法来说,可以分为两类:硬聚类与软聚类。对于硬聚类,每一个数据点只能属于某一个簇。对于软聚类来说,则没有这一限制。

首先还是来看一下整个聚类算法基类。

ClusteringModel类

ClusteringModel类定义在<include/shark/Models/Clustering/ClusteringModel.h>文件中。

template <class InputT, class OutputT>
class ClusteringModel : public AbstractModel<InputT, OutputT>
{
public:
    typedef AbstractModel<InputT, OutputT> base_type;
    typedef AbstractClustering<InputT> ClusteringType;
    typedef typename base_type::BatchInputType BatchInputType;
    typedef typename base_type::BatchOutputType BatchOutputType;

    ClusteringModel(ClusteringType* clustering)
    : mep_clustering(clustering)
    { SHARK_CHECK(clustering, "[ClusteringModel] Clustering must not be NULL"); }

    //稍后你可能会发现AbstractClustering类其实并没有parameterVector这一函数,其子类中是含有的,那么编译起来不会报错吗
    //注意到这里mep_clustering的定义类型是ClusteringType*,那么它肯定会使用到多态
    //只要其传入的对象中定义有parameterVector这一函数即可
    RealVector parameterVector() const
    { return mep_clustering->parameterVector(); }

    void setParameterVector(RealVector const& newParameters)
    { mep_clustering->setParameterVector(newParameters); }

    std::size_t numberOfParameters() const
    { return mep_clustering->numberOfParameters(); }

    void read(InArchive& archive)
    { archive & *mep_clustering; }

    void write(OutArchive& archive) const
    { archive & *mep_clustering; }

    using base_type::eval;
    //计算数据所属簇的标签
    void eval(BatchInputType const& patterns, BatchOutputType& outputs,  State& state)const{
        eval(patterns,outputs);
    }

protected:
    ClusteringType* mep_clustering; // 使用的是基类指针,方便使用多态
};

AbstractClustering类

在ClusteringModel类中你可能发现了AbstractClustering这个类,那么这个类又是干什么的呢?如果你熟悉基于原型的聚类算法的话,你应该知道,其中最重要的一点就是计算各个簇的中心,Shark中将聚类中心也包装成为一个类,而AbstractClustering类就是聚类中心类的基类。

ClusteringModel类包含了AbstractModel类和AbstractClustering类。其中只是提供了一些访问的接口,主要的数据是存储在AbstractClustering类中。

该类的定义位于<include/shark/Models/Clustering/AbstractClustering.h>文件中。

template <class InputT>
class AbstractClustering : public INameable, public IParameterizable, public ISerializable
{
public:
    typedef InputT InputType;
    typedef unsigned int OutputType;
    typedef typename Batch<InputType>::type BatchInputType;
    typedef Batch<OutputType>::type BatchOutputType;

    enum Feature {
        HAS_SOFT_MEMBERSHIP = 1,
    };
    SHARK_FEATURE_INTERFACE;

    //表示该聚类方法是否能进行软聚类
    bool hasSoftMembershipFunction()const{
        return m_features & HAS_SOFT_MEMBERSHIP;
    }

    //返回聚类结果中簇的数目
    virtual std::size_t numberOfClusters() const = 0;

    //计算一个数据所对应的簇的标号,有batch与非batch的重载版本
    //这个函数是针对硬聚类来说的,对于软聚类也有同样的版本
    virtual unsigned int hardMembership(InputType const& pattern) const{
        typename Batch<InputType>::type b = Batch<InputType>::createBatch(pattern);
        get(b,0) = pattern;
        return hardMembership(b)(0); //将非batch形式转换为batch形式进行处理
    }

    // 默认语意是返回softMembership函数返回值的最大值
    // 可以看出,硬聚类也是建立在软聚类之上的,只是输出最可能的簇
    virtual BatchOutputType hardMembership(BatchInputType const& patterns) const{
        std::size_t numPatterns = boost::size(patterns);
        RealMatrix f = softMembership(patterns); // 函数返回的应该是对每个簇的隶属度
        SHARK_ASSERT(f.size2() > 0);
        SHARK_ASSERT(f.size1() == numPatterns);
        BatchOutputType outputs(numPa
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值