m0_61606716 2022-05-27 19:02 采纳率: 0%
浏览 139
已结题

机器学习算法—聚类分析之Kmeans

在做Kmeans算法的时候,聚类类别数是由参数k决定的,而在做这个算法的时候,k值在传参时是由人为指定的,也就是自己想分成几类就分成几类,但是这样做下来并不严谨,我们不知道k值指定为多少的时候分类效果是最好的,所以我查找了很多关于k值的选择的资料,常见的方法有手肘法则和轮廓系数,但是用这两个方法基本上都是通过作图来观察如何选k值,最后还是需要人为输入传参的k值。
最重要的来了,自动确定k值的Kmeans聚类!,写出一个能自动确定最好分类效果的k值的算法并返回k值,作为最后传参的值,我同样也查了很多资料,找到了一个博主的文档:

我用#CSDN#这个app发现了有技术含量的博客,小伙伴们求同去《Kmeans算法 python实现》, 一起来围观吧 https://blog.csdn.net/m0_37783096/article/details/79704517?utm_source=app&app_version=4.21.1

但是里面代码并不完整,就导致有些地方看不懂。
在这里呢,我自我介绍一下,本人是一名读计算机专业的大学生,对于机器学习算法就学到一些基础知识,想请看到我发布的问题的朋友能帮忙解决一下我所提出的问题。我把完整代码上传,求在这方面厉害的朋友帮忙写一个自动确定k值并返回这个值的算法。


import numpy as np
import pandas as pd
import random
import matplotlib.pyplot as plt
import matplotlib as mpl

def loadDataSet():
    data = np.random.uniform(-6,6,size=(500,2))
    return data

# 中心点在k个样本点中随机选取
def createCent(dataSet, k):
    center = random.sample(list(dataSet), k)
    return np.array(center)

# 计算聚类中心和数据点之间的距离
def evaDistan(vectA, vectB):
    return np.sqrt(np.sum(np.power((vectA - vectB), 2)))

def kMeans(dataSet, k, evaDistance, createCenter):
    numSamples = np.shape(dataSet)[0]
    clusterAssment = np.mat(np.zeros((numSamples, 2)))
    clusterCenter = createCenter(dataSet, k)
    changeFlag = True
    while changeFlag:
        changeFlag = False
        for i in range(numSamples):
            minDist = float("inf"); minIndex = -1
            for j in range(k):
                distJI = evaDistance(clusterCenter[j, :], dataSet[i, :])
                if distJI < minDist:
                    minDist = distJI; minIndex = j
            if clusterAssment[i, 0] != minIndex:
                changeFlag = True
            clusterAssment[i, :] = minIndex, minDist ** 2
        # 重新计算聚类中心
        for cent in range(k):
            sameCluster = dataSet[np.nonzero(clusterAssment[:, 0].A == cent)[0]]
            clusterCenter[cent, :] = np.mean(sameCluster, axis=0)
    return clusterCenter, clusterAssment

def show(dataSet, labelSet, k, clusterCenter):
    mpl.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
    mpl.rcParams['axes.unicode_minus'] = False
    fig = plt.figure(figsize=(20, 18))
    
    plt.subplot(221)
    for i in range(np.shape(dataSet)[0]):
        plt.scatter(dataSet[i, 0], dataSet[i, 1], color='black')
    plt.xlabel(u'X', fontsize=18)
    plt.ylabel(u'Y', fontsize=18)
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    plt.title(u"无聚类结果", fontsize=18)
    
    plt.subplot(222)
    """
    's' : 方块状, 'o' : 实心圆, '^' : 正三角形, 'v' : 反正三角形, '+' : 加号
    '*' : 星号, 'x' : x号, 'p' : 五边形, '1' : 三脚架标记, '2' : 三脚架标记
    """
    mark = ['sr', 'ob', '^g', '*y', '+m', 'vc', 'xk', 'pb', '<r', 'pg', '*k', '^g']
    for i in range(np.shape(dataSet)[0]):
        plt.plot(dataSet[i, 0], dataSet[i, 1], mark[labelSet[i]], markersize=6)
    for lei in range(k):
        plt.plot(clusterCenter[lei][0], clusterCenter[lei][1], mark[lei], markersize=15)
    plt.xlabel(u'X', fontsize=18)
    plt.ylabel(u'Y', fontsize=18)
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    plt.title(u"聚类结果", fontsize=18)
    plt.grid(True)
    plt.show()

if __name__ == "__main__":
    dataSet = loadDataSet()
    k = 4
    clusterCenter, clusterAssment = kMeans(dataSet, k, evaDistance=evaDistan, createCenter=createCent)
    labelSet = [int(x[0]) for x in clusterAssment]
    show(dataSet, labelSet, k, clusterCenter)

img

这是人为指定的k值,希望各位以我上传的代码来帮忙写一个自动确定k值的算法
十分感谢

  • 写回答

5条回答 默认 最新

  • De-Chang Wang 2022-05-27 21:47
    关注
    获得0.35元问题酬金

    kmeans算法中的K是无法自动确定的,这是kmeans算法的本质决定的。你能做的要么是换其它算法,要么是在kmeans之前通过其它方式来设定K值

    评论

报告相同问题?

问题事件

  • 系统已结题 6月4日
  • 创建了问题 5月27日

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog