机器学习全解 - K均值聚类算法 (含算法介绍,公式,手写代码实现,调包实现)

1. K均值聚类

1.1 算法介绍

先来看看官方的定义:

Kmeans算法是最常用的聚类算法,主要思想是:在给定K值和K个初始类簇中心点的情况下,把每个点(亦即数据记录)分到离其最近的类簇中心点所代表的类簇中,所有点分配完毕之后,根据一个类簇内的所有点重新计算该类簇的中心点(取平均值),然后再迭代的进行分配点和更新类簇中心点的步骤,直至类簇中心点的变化很小,或者达到指定的迭代次数。

OMG,头都大了,不复杂的东西硬生生的弄得让人搞不明白。

这个图很好的展现了什么是Kmeans方法。通俗点讲,算法就是将相似的的样本聚合在一起,例如说170-180的人为一个团体,180-190的人一个团体。这个团体就是定义中所说的簇,给定K值就是我们需要分k个团体,怎样,这样解释是不是一下就豁然开朗了呢。

大家可能会想,不就是分类么,为什么不叫Kmeans分类呢,让我们解读一下两者的定义。

分类:类别是已知的,通过对已知分类的数据进行训练和学习,找到这些不同类的特征,再对未分类的数据进行分类。属于监督学习。

聚类:事先不知道数据会分为几类,通过聚类分析将数据聚合成几个群体。聚类不需要对数据进行训练和学习。属于无监督学习。

聚类是需要我们手动设置数据分为几个群体,也不需要对数据进行训练与学习,这也就是Kmeans的关键点所在。

1.2 算法原理

既然是分类,那么总会需要一个分类标准,Kmeans中的分类标准就是要找到组的簇,类似于一个组的大哥,剩下的样本就是小弟,与大哥离得越近,这些小弟就被分在了最近大哥的组。这样形容已经将算法本质给讲出来了,就是距离,聚类簇质心越近,我们就将这些样本分为一类。

根据每个样本的特征与质心的特征计算之间的差值,谁离得近大家就能在一起抱团。

问题来了,既然要跟着老大抱团,谁是老大?

每个样本谁也不服谁,老大的位置总该定个规矩:集众家之所长的人是老大。

在最开始,选取样本任意k个点作为老大(质心),结成不同的组,在内部推举,根据组内每个点的加总取平均找到新的质心,再重复进行上述操作,直到质心不再改变为止。

总结一下Kmeans的过程就是:

1.将数据分为K类;

2.随机选取K个数据作为初始的聚类中心,计算每个数据与各个聚类中心之间的距离,把每个数据分配给距离它最近的聚类中心。

3.聚类中心以及分配给它们的数据就代表一个聚类。每分配一个数据,聚类的聚类中心会根据聚类中现有的数据被重新计算。这个过程将不断重复直到满足某个终止条件。

4.终止条件可以是没有(或最小数目)数据被重新分配给不同的聚类,没有(或最小数目)聚类中心再发生变化,误差平方和局部最小。

1.3 距离标准

样本点到质心的距离有多种方式进行计算:

2. 手写代码实现

def distEclud(vecA,vecB): #距离算法
    return np.sqrt(np.sum(np.power(vecA - vecB,2),1))

def randCent(dataSet,k):
    n = np.shape(dataSet)[1] #特征数量
    centroids = np.mat(np.zeros((k,n)))
    for j in range(n):
        minJ = min(dataSet[:,j]) #特征中的最小值
        rangeJ = float(max(dataSet[:,j]) - minJ) #最大值与最小值的差
        centroids[:,j] = minJ + rangeJ * np.random.rand(k,1) #生成最小值与最大值之间中间的值
    return centroids

在实现算法之前我们先将辅助函数定义,distEclud计算样本到质心的欧几里得距离。

第二个函数随机产生k个质心点。 

#K-均值聚类算法
def kMeans(dataset,k,distMeans=distEclud,createCent=randCent):
    m = np.shape(dataset)[0] #获得样本个数
    clusterAssment = np.mat(np.zeros((m,2)))  #存放样本的分类信息
    centroids = createCent(dataset,k) #随机生成簇
    clusterChanged = True #判断质心是否改变
    while clusterChanged:
        clusterChanged = False
        for i in range(m): #对于每个样本
            minDist = 10000; minIndex = -1 #默认最小句无穷大,最小簇为 -1
            for j in range(k): #样本对于每个簇
                distJI = distMeans(centroids[j,:],dataset[i,:]) #向量运算,保存每个样本与簇之间的距离
                #print(distJI)
                if distJI < minDist: #保存样本距离最小的质心
                    minDist = distJI #替换最小
                    minIndex = j #最小距离的簇
            if clusterAssment[i,0] != minIndex: clusterChanged = True  #如果最小距离的簇发生了改变
            clusterAssment[i,:] = minIndex,minDist**2 #存放该样本的簇,最小距离的平方
        #print(centroids)
        for cent in range(k): #对于每个簇进行更新
            ptsInClust = dataset[np.nonzero(clusterAssment[:,0].A==cent)[0]] #clusterAssment中与簇相同的取出
            centroids[cent,:] = np.mean(ptsInClust,axis=0) #对于每个簇中的每个特征取均值
    return centroids,clusterAssment

通过不断的计算迭代,最终得到我们的k个簇。

3. 调包实现

from sklearn.cluster import KMeans
Kmeans = KMeans(n_clusters=4)
Kmeans.fit(X)
y_kmeans = Kmeans.predict(X)

4. K均值聚类算法优点与局限性

4.1 优点

1. 高效:算法收敛速度快,通常几次迭代后就能达到收敛状态。

2. 适用性广泛: 在许多实际应用中表现良好,例如图像压缩,文本分类与市场细分

4.2 局限性

1. 需要预先指定k值:通常需要通过实验或其他方式来选择合适的k值。

2.对初始值敏感:结果对初始质心的选择非常敏感,不同初始质心可能导致不同的聚类结果。

3. 无法处理不同大小和密度的簇:对于不同大小或密度的簇,K均值可能无法正确聚类。

5. 应用前景

1. 图像处理和计算机视觉:

-图像压缩:将图像的像素聚类到K个簇,每个簇的质心表示簇内所有像素,达到压缩的效果。

-图像分割:聚类到不同簇,识别和分割图像中的不同对象。

2. 市场营销:

-客户细分与产品推荐。

3. 交通与物流:

-路线优化: 对地理位置数据进行聚类,优化运输路线与物流配送。

-交通流量分析: 对交通流量数据进行聚类,识别出交通拥堵区域和高峰时段。

4. 生物信息学:

-基因表达分析: 将基因表达数据聚类,以此识别具有相似表达模式的基因。

-蛋白质结构分类: 根据蛋白质的特征进行聚类。

5. 文本分析和自然语言处理:

-文本分析: 将相似的文本或文档聚类在一起,用于新闻分类。

-情感分析: 通过对文本进行聚类,识别出不同的情感或者观点。

6. 参考资料

Kmeans聚类算法详解-CSDN博客

百度安全验证

k均值聚类-python - 知乎

《机器学习实战》

  • 29
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
机器学习中最常用的数学工具是线性代数、微积分和概率论。下面是一些基本的数学概念和 Python 代码示例: 1. 向量和矩阵 向量是一列数字,矩阵是一个二维数组。在 Python 中,可以使用 NumPy 库来创建和操作向量和矩阵。 ```python import numpy as np # 创建向量 v = np.array([1, 2, 3]) # 创建矩阵 m = np.array([[1, 2], [3, 4], [5, 6]]) # 矩阵乘法 result = np.dot(m, v) print(result) ``` 2. 梯度下降 梯度下降是一种优化算法,用于最小化损失函数。在 Python 中,可以使用 NumPy 和 SciPy 库来实现梯度下降算法。 ```python import numpy as np from scipy.optimize import minimize # 定义损失函数 def loss_function(w, X, y): y_hat = np.dot(X, w) return np.mean((y_hat - y) ** 2) # 定义梯度函数 def gradient(w, X, y): y_hat = np.dot(X, w) return np.dot(X.T, y_hat - y) / len(y) # 使用梯度下降算法求解 X = np.array([[1, 2], [3, 4], [5, 6]]) y = np.array([1, 2, 3]) w0 = np.zeros(X.shape[1]) res = minimize(loss_function, w0, args=(X, y), jac=gradient) print(res.x) ``` 3. 偏导数和梯度 偏导数是多元函数中某个变量的导数,梯度是多元函数的导数向量。在 Python 中,可以使用 SymPy 库来计算偏导数和梯度。 ```python from sympy import symbols, diff # 定义符号变量和函数 x, y = symbols('x y') f = x ** 2 + y ** 3 # 计算偏导数 df_dx = diff(f, x) df_dy = diff(f, y) print(df_dx, df_dy) # 计算梯度 grad = [diff(f, var) for var in [x, y]] print(grad) ``` 4. 概率分布和随机变量 概率分布是随机变量可能取值的概率分布。在 Python 中,可以使用 SciPy 库来计算概率分布和随机变量。 ```python from scipy.stats import norm # 定义正态分布 mu, sigma = 0, 1 dist = norm(mu, sigma) # 计算概率密度函数和累积分布函数 x = np.linspace(-3, 3, 1000) pdf = dist.pdf(x) cdf = dist.cdf(x) # 生成随机变量 samples = dist.rvs(1000) ``` 以上是一些基本的数学概念和 Python 代码示例。在机器学习中,还会涉及到更高级的数学工具,如矩阵分解、优化理论、贝叶斯统计等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值