机器学习7 K-Means

7 K-Means

7.1 K-Means

''' Kmeans
1 . 设置中心点  a.随机抽取一个样本作为初始中心点 m,n = X.shape
                b.设置距离矩阵[m,n_clusters-1]和中线点矩阵[n_clusters,n]
                c.计算所有样本到簇中心的距离,找出每个样本到簇距离的最小值求和np.min(distances)
                d.以[0, sum(nds))的均匀分布产生一个随机值,判断随机值r落于哪个区域, 对应实例被选为簇中心.
2 . 训练
3 . 预测
4 . 测试
'''
import numpy as np
#from matplotlib import pyplot as plt

class keans():
    # 初始化参数
    def __init__(self, k_clusters, tol=1e-4, max_iter=300, n_init=10):
        self.k_clusters = k_clusters  # 分为k簇
        self.tol = tol                # 新旧中心点差异的阈值
        self.max_iter = max_iter      # 最大迭代次数
        self.n_init = n_init          # 重新初始化中心点运行kmeans的次数


    # 1 . 设置中心点
    def _init_centers_kpp(self, X, n_clusters):
        m , n = X.shape
        distances = np.empty([m,n_clusters-1])
        centers = np.empty([n_clusters,n])
        np.copyto(centers[0],X[np.random.randint(m)])  # 随机选择第一个簇中心

        for i in range(1,n_clusters): # i=1,2
            distances[:,i-1]=np.sum((X-centers[i-1])**2,axis=1) # 计算样本到中心点的距离
            if i == 1:
                mds = distances[:,0]
            else:
                mds = np.min(distances[:,:i-1], axis=1)        # 找出最小距离
            sum1 = np.sum(mds,axis=0)*np.random.random()       # 距离和乘以随机值

            for j in range(m):    # 循环找出簇的坐标
                sum1 -= mds[j]
                if sum1 < 0:
                    break
            np.copyto(centers[i],X[j])
        return centers


# 2 . 训练
    def _kmeans(self, X):
        # 1 初始参数设置
        m,n = X.shape
        labels = np.empty(m)
        centers_old = np.empty([self.k_clusters,n])
        distances = np.empty([m,self.k_clusters])
        centers = self._init_centers_kpp(X, self.k_clusters)

        # 2 循环
        for  _ in range(self.max_iter):
            # 2.1 找出每个样本所属的类别
            for i in range(self.k_clusters):
                distances[:, i] = np.sum( (X-centers[i])**2,axis = 1 )
            labels = np.argmin(distances,axis=1)

            # 2.2 重新计算每个类别的中心
            np.copyto(centers_old, centers)
            for i in range(self.k_clusters):
                cluster = X[labels==i]
                if cluster.size == None:
                    return None
                centers[i] = np.mean(cluster,axis=0)

            # 2.3 计算新中心和旧中心的距离,判断是否收敛
            delta_centers = np.sqrt(np.sum((centers - centers_old) ** 2, axis=1))
            if np.all(delta_centers < self.tol):
                break
        # 3 计算每个类别中样本的距离之和
        sse = np.sum(distances[range(m),labels])
        return labels,centers,sse
# 3 . 预测
    def predict(self, X):
        # 1 result用来存储centers,labels,sse
        result = np.empty((self.n_init, 3), dtype=np.object)

        # 2 遍历self.n_init次,直到找到结果
        for i in range(self.n_init):
            res = None
            while not res:
                res = self._kmeans(X)
            result[i] = res

        # 3 在result中找出sse最小的下标
        k = np.argmin(result[:,-1],axis=0)
        labels, self.centers_, self.sse_ = result[k]
        return labels

# 4 . 测试
def circle(r=5,m=100):  # a^2 + b^2 = r^2
    x1 = []
    x2 = []
    for i in range(3):
        a = np.random.randn(m)*0.3+i
        b = np.sqrt(r**2-a)*0.3+i
        x1.append(a)
        x2.append(b)
    x1 = np.array(x1).reshape(-1,1)
    x2 = np.array(x2).reshape(-1,1)
    X = np.concatenate([x1,x2],axis=1)
    return X

if __name__ == '__main__':
    X = circle(r=5,m=100)
    kean = keans(k_clusters=3, tol=1e-4, max_iter=100, n_init=60)
    labels = kean.predict(X[:10])
    print(labels)
'''
[1 1 1 1 1 1 1 1 1 1]

Process finished with exit code 0
'''
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值