k聚类python实现

算法流程

算法流程分为以下几个步骤

  1. 随机在数据点内选取k个点,这个k值为你要划分的聚类数。
  2. 然后计算所有点到每个选取点的距离,然后记录距离最短的那个点
  3. 然后重新计算新的点作为聚落质点。
  4. 计算出新的点后重复步骤二和步骤三,直到到达所设定的停止条件为止

停止条件

一般有三个条件

  1. 每个质心分配得到的点在下一次分配完后没有发生改变。
  2. 上一次的计算得到的所有质心和这一次计算得到的质心没有发生变化
  3. 重复一个固定次数后就不再重复

python实现

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from turtle import color
plt.rcParams['toolbar'] = 'None'


def assigment(centralPoint, dateTable):
    for i in centralPoint.keys():
        dateTable["distance{}".format(i)] = ( #计算点到质点距离,采用欧式距离
            ((dateTable['x']-centralPoint[i][0])**2 +
             (dateTable['y']-centralPoint[i][1])**2 
             )**0.5
        )
    dateTable['minPoint'] = dateTable.loc[:, [
        'distance{}'.format(i) for i in centralPoint.keys()]].idxmin(axis=1)
    dateTable['minPoint'] = dateTable['minPoint'].map( # 找到距离最近的质点
        lambda x: int(x.lstrip('distance')))
    return dateTable


def updatePoint(centralPoint, dateTable):
    # 计算新的质点,将同一个集合内的点求平均值得到新的点
    for i in centralPoint.keys():
        centralPoint[i][0] = np.mean( 
            dateTable[dateTable['minPoint'] == i]['x'])
        centralPoint[i][1] = np.mean(
            dateTable[dateTable['minPoint'] == i]['y'])


if __name__ == '__main__':
    k = 3 # k值设定为3

    # 生成三组正态分布数据集
    cov = np.array([[100, 10], [10, 100]])  # 协方差矩阵
    srcTable = pd.DataFrame(columns=['x', 'y'], dtype='float')  # 数据表
    for i in range(k):
        mean = np.array([np.random.randint(0, 100),
                        np.random.randint(0, 100)])
        data = np.random.multivariate_normal(mean, cov, 1000)
        x, y = data.T
        srcTable = pd.concat([srcTable, pd.DataFrame(  # 合并数据集
            {'x': x[:], 'y':y[:]}, dtype='float')], ignore_index=True)
    srcTable = srcTable.drop_duplicates()  # 去除重复点

    # 随机选取样本点作为质心
    srcList = srcTable.to_numpy().tolist()
    centralPoint = {
        i+1: srcList[np.random.randint(0, len(srcList))] for i in range(k)
    }

    # 分配样本点所属质心
    assigment(centralPoint, srcTable)

    # 重复更新数据以及分配,直到所属质心的集合不在更改退出
    while True:
        oleDate = srcTable['minPoint'].copy(deep=True)
        updatePoint(centralPoint, srcTable)
        assigment(centralPoint, srcTable)
        if oleDate.equals(srcTable['minPoint']):
            break

    # 绘图
    colormap = {1: 'r', 2: 'g', 3: 'b'}
    srcTable['color'] = srcTable['minPoint'].map(lambda x: colormap[x])
    fig = plt.figure(figsize=(10, 10))
    plt.scatter(x=srcTable['x'], y=srcTable['y'],
                color=srcTable['color'], alpha=0.5, edgecolors='k')
    for i in centralPoint.keys():
        plt.scatter(*centralPoint[i], color=colormap[i])
    plt.xlim(0, 100)
    plt.ylim(0, 100)
    plt.show()

在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是高斯混合聚类Python实现: ```python import numpy as np from scipy.stats import multivariate_normal class GMM: def __init__(self, k, max_iterations=100): self.k = k self.max_iterations = max_iterations def fit(self, X): self.n, self.m = X.shape self.phi = np.full(shape=self.k, fill_value=1/self.k) self.weights = np.full(shape=self.k, fill_value=1/self.k) self.means = np.random.rand(self.k, self.m) self.covs = np.array([np.eye(self.m)] * self.k) self.log_likelihoods = [] self.responsibilities = np.zeros(shape=(self.n, self.k)) for i in range(self.max_iterations): self._e_step(X) self._m_step(X) log_likelihood = self._compute_log_likelihood(X) self.log_likelihoods.append(log_likelihood) def _e_step(self, X): for j in range(self.k): self.responsibilities[:, j] = self.phi[j] * multivariate_normal.pdf( X, self.means[j], self.covs[j]) self.responsibilities = (self.responsibilities.T / np.sum(self.responsibilities, axis=1)).T def _m_step(self, X): for j in range(self.k): resp = self.responsibilities[:, j] total_resp = np.sum(resp) self.weights[j] = total_resp / self.n self.phi[j] = np.mean(resp) self.means[j] = np.sum(X * resp.reshape(-1, 1), axis=0) / total_resp x_mean = (X - self.means[j]) self.covs[j] = np.dot(resp * x_mean.T, x_mean) / total_resp def _compute_log_likelihood(self, X): log_likelihood = 0 for i in range(self.n): tmp = 0 for j in range(self.k): tmp += self.phi[j] * multivariate_normal.pdf(X[i], self.means[j], self.covs[j]) log_likelihood += np.log(tmp) return log_likelihood def predict(self, X): resp = np.zeros((X.shape[0], self.k)) for j in range(self.k): resp[:, j] = self.weights[j] * multivariate_normal.pdf( X, self.means[j], self.covs[j]) return np.argmax(resp, axis=1) ``` 其中,fit方法用于拟合数据,predict方法用于预测新数据的类别。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值