K-means算法小结

k-means算法是经典的聚类算法. 我自己手写了一个k-means++的放在后面, 效果似乎不太好 , 希望大佬指点

sklearn实现

import numpy as np 
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets.samples_generator import make_blobs

原始数据

# 绘图函数
def plot_img(x,y=True):
    fig=plt.figure(figsize=(7,5))
    if y:
        plt.scatter(x[:,0],x[:,1],c=x[:,2],cmap=plt.cm.Spectral,marker='o')
    else:
        plt.scatter(x[:,0],x[:,1],marker='o')
    plt.title('Scatter')
    plt.xlabel('feature 2')
    plt.ylabel('feature 1')
    plt.show()
'''构造数据'''
# X为样本特征,Y为样本簇类别, 共1000个样本,每个样本2个特征,共4个簇,
#簇中心在[-1,-1], [0,0],[1,1], [2,2], 簇方差分别为[0.4, 0.2, 0.2]
X,Y = make_blobs(n_samples=1000, n_features=2, centers=[[-1,-1], [0,0], [1,1], [2,2]], cluster_std=[0.4, 0.2, 0.2, 0.2], 
                  random_state =9)
# 可视化
data=np.c_[X,Y]
plot_img(data,y=True)

在这里插入图片描述

传统的k-means聚类

from sklearn.cluster import KMeans
from sklearn import metrics
plt.figure(figsize=(10,10))
for i,k in enumerate([2,3,4,5]):
    km=KMeans(n_clusters=k,# 即k值,即要形成的质心数
              max_iter=300,# 凸数据集不用管这个,如果是非凸数据集可能会无法收敛,设置最大迭代次数
              n_init=10,# 用不同的初始化质心运行算法的次数. 默认是10,不需要改.如果k值较大,
                        # 则可以适当增大这个值。
              init='k-means++',# 初始化质心的方法,可以选择'random'随机,推荐用默认'k-means ++'
              algorithm='auto',)# 优化方法,推荐使用默认'auto',通过数据的稀疏性,自动选择合适的方法

    km.fit(X)
    y_pred=km.predict(X)
    '''calinske_harbaz_score是聚类算法的衡量标准,值越大越好'''
    score=metrics.calinski_harabaz_score(X, y_pred)
    plt.subplot(2,2,i+1)
    plt.scatter(X[:,0],X[:,1],c=y_pred,cmap=plt.cm.Spectral)
    plt.title('Clusters=%d\nScore=%f'%(k,score))

在这里插入图片描述

MiniBatchKMeans

应用于大数据集,选取一部分合适的数据集来迭代质心
from sklearn.cluster import MiniBatchKMeans

plt.figure(figsize=(10,10))
for i,k in enumerate((2,3,4,5)):
    y_pred=MiniBatchKMeans(n_clusters=k, 
                           batch_size = 200,# 即用来跑Mini Batch KMeans算法的采样集的大小,
                                            #默认是100.如果发现数据集的类别较多或者噪音点较多,
                                            #需要增加这个值以达到较好的聚类效果。
                           random_state=9).fit_predict(X)
    score= metrics.calinski_harabaz_score(X, y_pred)
    plt.subplot(2,2,i+1)
    plt.scatter(X[:,0],X[:,1],c=y_pred,cmap=plt.cm.Spectral)
    plt.title("Clusters={0}\nScore={1}".format(k,score))

在这里插入图片描述

手动实现

class K_mean(object):
    
    def __init__(self,c,n_iterations):
        self.n_iterations=n_iterations
        self.c=c
    
    def init_params(self,X):
        self.X=X
        self.init_u()
    
    def init_u(self):
        all_u=[]
        for i in range(self.c):
            uid=np.random.choice(self.X.shape[0],1)
            u=self.X[uid]
            delta=u-self.X
            d_delta=np.apply_along_axis(lambda x:np.dot(x,x),1,delta)
            best_u=X[np.argmax(d_delta)]
            all_u.append(best_u)
        self.U=np.array(all_u)
        
    
    def get_label(self):
        labels=[]
        for i in range(len(self.X)):
            di=self.X[i].reshape(1,-1)-self.U
            di=np.apply_along_axis(lambda x:x.dot(x),1,di)
            k=di.argmin()
            labels.append(k)
        return labels
    
    def update_u(self):
        U_up=[]
        labels=self.get_label()
        X_new=np.c_[self.X,labels]
        self.X_complete=X_new
        label_map=set(labels)
        for i in label_map:
            group=X[labels==i]
            u=group.sum(axis=0)/len(group)
            U_up.append(u)
        self.U=np.array(U_up)
        
    def fit_transform(self,X):
        self.init_params(X)
        old_u=None
        iters=0
        for iter in range(self.n_iterations):
            self.update_u()
            iters+=1
        self.iters=iters
        
        return self.X_complete
c=4
n_iters=100
km=K_mean(c,n_iters)
X_show=km.fit_transform(X)
plot_img(X_show)

在这里插入图片描述
完整代码:https://github.com/TaoistNie/The-road-to-ML/blob/master/K-means/readme.md

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值