算法面经总结(8)聚类

1、K-means

        是无监督,思想:对于给定的样本集,按照样本之间的距离大小,将样本划分为k个簇,让簇内点距离近,簇间距离远。

时间复杂度:O(tKmn),其中,t为迭代次数,K为簇的数目,m为记录数,n为维数。

空间复杂度:O((m+K)n),其中,K为簇的数目,m为记录数,n为维数

影响性能因素:样本输入顺序;模式相似性测度;初始类中心的选取

        流程:

                输入样本集D={x1,x2..,xn},簇数k,最大迭代次数N

                输出是簇划分C={c1,...ck}

                (1)从数据集中随机选取k个样本作为初始的簇的中心:{u1...,uk}

                (2)对于n=1,2,...N

                        (a)将簇划分C初始化为C_{t}=\phi

                        (b)对于i=1,2,...m,计算样本xi和各个中心uj的距离(欧式距离),将xi标记的最小的d_{ij}所对应的类别\lambda _{i},此时更新C_{\lambda _{i}}=C_{\lambda _{i}}\bigcup \left \{ x_{i} \right \}

                        (c)对于j=1,2,...k,对C_{j}中所有样本点重新计算新的质心u_{j}=\frac{1}{\left | C_{j} \right |}\sum_{x\in C_{j} }^{}x

                        (d)如果质心无变化,则跳出循环

                (3)输出C

2、K-means优缺点

优点:

        原理简单,实现容易,收敛快

        效果较好,可解释性好

        仅需要调参数k

缺点:

        k值选择不容易

        对于不是凸的数据集不好收敛

        对噪音和异常点敏感

        可能得到的结果是局部最优解

3、初始簇怎么选取

        选择批次距离尽可能远的k个点

        选用层次聚类或者Canopy算法进行初始聚类

4、代码实现

def euclDistance(vector1, vector2):
    return np.sqrt(sum((vector2 - vector1) ** 2))

def initCentroids(data, k):
    numSamples, dim = data.shape
    # k个质心,列数跟样本的列数一样
    centroids = np.zeros((k, dim))
    # 随机选出k个质心
    for i in range(k):
        # 随机选取一个样本的索引
        index = int(np.random.uniform(0, numSamples))
        # 作为初始化的质心
        centroids[i, :] = data[index, :]
    return centroids

# 传入数据集和k值
def kmeans(data, k):
    # 计算样本个数
    numSamples = data.shape[0]
    # 样本的属性,第一列保存该样本属于哪个簇,第二列保存该样本跟它所属簇的误差
    clusterData = np.array(np.zeros((numSamples, 2)))
    # 决定质心是否要改变的质量
    clusterChanged = True
    # 初始化质心
    centroids = initCentroids(data, k)
    while clusterChanged:
        clusterChanged = False
        # 循环每一个样本
        for i in range(numSamples):
            # 最小距离
            minDist = 100000.0
            # 定义样本所属的簇
            minIndex = 0
            # 循环计算每一个质心与该样本的距离
            for j in range(k):
                # 循环每一个质心和样本,计算距离
                distance = euclDistance(centroids[j, :], data[i, :])
                # 如果计算的距离小于最小距离,则更新最小距离
                if distance < minDist:
                    minDist = distance
                    # 更新最小距离
                    clusterData[i, 1] = minDist
                    # 更新样本所属的簇
                    minIndex = j
            # 如果样本的所属的簇发生了变化
            if clusterData[i, 0] != minIndex:
                # 质心要重新计算
                clusterChanged = True
                # 更新样本的簇
                clusterData[i, 0] = minIndex
        # 更新质心
        for j in range(k):
            # 获取第j个簇所有的样本所在的索引
            cluster_index = np.nonzero(clusterData[:, 0] == j)
            # 第j个簇所有的样本点
            pointsInCluster = data[cluster_index]
            # 计算质心
            centroids[j, :] = np.mean(pointsInCluster, axis=0)
    return centroids, clusterData

5、优化

        使用kd树或者ball tree。
        将所有的观测实例构建成一颗kd树,之前每个聚类中心都是需要和每个观测点做依次距离计算,现在这些聚类中心根据kd树只需要计算附近的一个局部区域即可。

6、其他聚类算法

(1)均值漂移聚类

(2)基于密度的聚类算法(DBSCAN)

(3)用高斯混合模型的最大期望(EM)聚类

7、影响聚类算法结果的因素

        分类准则; 特征选取;模式相似性测度

 以上内容均来源于各个版主、牛客网总结

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值