最近对clustering感兴趣就自己写了一个k mediods的实现. 这个算法据说是比kmeans要robust. 我觉得关键的不同就是cluster的中心点是一个真实的数据点  而不是构想出来的mean.

写起来倒是很简单, 最后vectorize用了cdist() 函数 很好用.

先看结果 : 这是3个类 总共3000 个点的结果.

上代码: 

各种imports:

import matplotlib as plt
from pylab import *
import collections
import copy
import pdb
import numpy as np
from scipy.spatial.distance import cdist
import random

这里介绍一下我主要的数据结构 :

medoids 是一个字典,

-2 是total cost

-1: 一个numpy array 存了medoids的index.

0 - k 存了各个cluster的成员的index

data是一个array, 每一行是一个数据点.

下面这个函数计算total cost 根据当前的情况:

def total_cost(data, medoids):'''
compute the total cost based on current setting.
'''med_idx = medoids[-1];k = len(med_idx);cost = 0.0;med = data[ med_idx]dis = cdist( data, med, 'euclidean')cost = dis.min(axis = 1).sum()# rewrite using the cdist() function, which should be way faster# for i in range(k):# med = data[med_idx[i]]# for j in medoids[i]:# cost = cost + np.linalg.norm(med - data[j])#
    medoids[-2] = [cost]

clustering()函数 分配每一点的归属 根据当前的情况.

def clustering(data, medoids):'''
compute the belonging of each data point according to current medoids centers, and eucludiean distance.
'''# pdb.set_trace()med_idx = medoids[-1]med = data[med_idx]k = len(med_idx)dis = cdist(data, med)best_med_it_belongs_to = dis.argmin(axis = 1)for i in range(k):medoids[i] =where(best_med_it_belongs_to == i)

最重要的kmedoids() 函数, 用来循环找到最优的clutering

old... 和cur... 比较 直到没有变化了 就退出循环

cur...每次交换一对 ( 中心点, 非中心点) 构成tmp.... , 从所有的tmp...中找到最优的best....

def kmedoids( data, k):'''
given the data and # of clusters, compute the best clustering based on the algorithm provided in wikipedia: google pam algorithm.
'''# cur_medoids compare with old_medoids, convergence achieved if no change in the list of medoids in consecutive iterations.# tmp_medoids is cur_medoids swapped only one pair of medoid and non-medoid data point.# best_medoids is the best tmp_medoids through all possible swaps.
N = len(data)cur_medoids = {}cur_medoids[-1] = range(k)clustering(data, cur_medoids)total_cost(data, cur_medoids)old_medoids = {}old_medoids[-1] = []iter_counter = 1# stop if not improvement.while not set(old_medoids[-1]) == set(cur_medoids[-1]):print 'iteration couter:' , iter_counteriter_counter = iter_counter + 1best_medoids = copy.deepcopy(cur_medoids)old_medoids = copy.deepcopy(cur_medoids)# pdb.set_trace()# iterate over all medoids and non-medoidsfor i in range(N):for j in range(k):if not i ==j :# swap only a pairtmp_medoids = copy.deepcopy(cur_medoids)tmp_medoids[-1][j] = iclustering(data, tmp_medoids)total_cost(data, tmp_medoids)# pick out the best configuration.if( best_medoids[-2] > tmp_medoids[-2]):best_medoids = copy.deepcopy(tmp_medoids)cur_medoids = copy.deepcopy(best_medoids)print 'current total cost is ', cur_medoids[-2]return cur_medoids

最后写一个test() 函数, 3个gaussian类 总共1000个点.

def test():dim = 2N =1000# create datas with different normal distributions.d1 = np.random.normal(1, .2, (N,dim))d2 = np.random.normal(2, .5, (N,dim))d3 = np.random.normal(3, .3, (N,dim))data = np.vstack((d1,d2,d3))# need to change if more clusters are needed .k = 3medoids = kmedoids(data, k)# plot different clusters with different colors.scatter( data[medoids[0], 0] ,data[medoids[0], 1], c = 'r')scatter( data[medoids[1], 0] ,data[medoids[1], 1], c = 'g')scatter( data[medoids[2], 0] ,data[medoids[2], 1], c = 'y')scatter( data[medoids[-1], 0],data[medoids[-1], 1] , marker = 'x' , s = 500)show()

最后执行代码就好了  只要2min

if __name__ =='__main__':test()

另外, 我还找到了python很好使的scikit-learn toolbox , 是machine learning相关的. 就练了下手 写个kmeans

先上图: 这是gaussian 3 个类, 每个类3000 个点

代码: 首先还是imports

import time
import numpy as np
import pylab as pl
from sklearn.cluster import KMeans
from sklearn.metrics.pairwise import euclidean_distances
from sklearn.datasets.samples_generator import make_blobs

然后是生成数据, 并且很简单的train kmeans:

np.random.seed(0)
centers = [[1,1], [-1,-1], [1, -1]]
k = len(centers)
x , labels = make_blobs(n_samples=3000, centers=centers, cluster_std=.7)kmeans = KMeans(init='k-means++', n_clusters=3, n_init = 10)
t0 = time.time()
kmeans.fit(x)
t_end = time.time() - t0

最后是画图:

colors = ['r', 'b', 'g']
for k , col in zip( range(k) , colors):members = (kmeans.labels_ == k )pl.plot( x[members, 0] , x[members,1] , 'w', markerfacecolor=col, marker='.')pl.plot(kmeans.cluster_centers_[k,0], kmeans.cluster_centers_[k,1], 'o', markerfacecolor=col,\markeredgecolor='k', markersize=10)
pl.show()

很多时候都觉得python比matlab好用多了, 最重要的是matlab和vim的结合不是很好 用起来很不顺手.

转载于:https://www.cnblogs.com/wenhoujx/p/3147563.html

PAM for Kmedoids algorithm, PAM算法的实现, kmeans 算法实现. 利用scikit-learn toolbox.相关推荐

  1. 机器学习题5:请简述ID3算法的实现步骤,并利用ID3算法构建天气数据集的决策树模型,实现决策树的可视化。

    ID3算法的实现步骤: 输入:数据集(训练集)S及属性A 输出:属性A对训练数据集S的信息增益 ① 先将S作为根节点,其目标属性y有c个类别属性.假设S中出现的概率,计算数据集S的信息熵. ② 假设属 ...

  2. K-Means算法和K-Means++算法的聚类

    在构成圆形的30000个随机样本点上,设置7个簇,使用K-Means算法聚类 from math import pi, sin, cos from collections import namedtu ...

  3. kmeans算法和kmeans++算法精简总结

    1. kmeans kmeans作为传统的无监督学习算法.很容易受到初值的影响,最后会产生错误的收敛结果,这时候就要借助kmeans++算法进行改进. 2. kmeans++ kmeans++的实际计 ...

  4. Dijkstra 算法的实现(算法笔记)

    算法笔记:  1) Dijkstra 算法的伪代码: /**1) Dijkstra 算法的伪代码:void Dijkstra(G,d[],s){初始化:for(循环 n 次){u=使d[u] 最小的还 ...

  5. python怎么生成伪代码_Python零基础入门—算法的实现与伪代码

    同学们好.在前面一节课,我们了什么是算法,知道了在一个算法中,要有输入.计算过程.还要有输出.这节课我们来讨论算法的实现. 这节课的内容与前面课程的课后练习有关.在课后练习中要求同学们写出计算长方形面 ...

  6. 数据挖掘案例——ReliefF和K-means算法的医学应用

    [原创]数据挖掘案例--ReliefF和K-means算法的医学应用 阅读目录 1.数据挖掘与聚类分析概述 2.特征选择与聚类分析算法 3.一个医学数据分析实例 4.主要的Matlab源代码 数据挖掘 ...

  7. 聚类优化算法——基于Kmeans算法

    聚类优化算法--基于Kmeans算法 Kmeans算法 Kmeans算法的基本原理及计算流程见上文--Kmeans算法及简单案例 Kmeans算法的优缺点 优点 - 原理简单(靠近中心点),实现容易 ...

  8. K-Means算法、层次聚类、密度聚类及谱聚类方法详述

    1.聚类算法概述 (1)什么是聚类? 聚类就是对大量未知标注的数据集,按照数据内部存在的数据特征将数据集划分为多个不同的类别,使类别内的数据比较相似,类别之间的数据相似度比较小,属于无监督学习. 聚类 ...

  9. 基于 ReliefF和K-means算法的应用

    数据挖掘方法的提出,让人们有能力最终认识数据的真正价值,即蕴藏在数据中的信息和知识.数据挖掘 (DataMiriing),指的是从大型数据库或数据仓库中提取人们感兴趣的知识,这些知识是隐含的.事先未知 ...

  10. 机器学习之K均值(K-Means)算法

    1.K-Means简介 K均值(K-Means)算法是无监督的聚类方法,实现起来比较简单,聚类效果也比较好,因此应用很广泛.K-Means算法针对不同应用场景,有不同方面的改进.我们从最传统的K-Me ...

最新文章

  1. python max和min函数的高级用法
  2. 计算机基础——原码、反码、补码转换
  3. java 遍历100以内的偶数,偶数的和,偶数的个数
  4. Windows环境下安装redis以及出现的一些未解决的问题
  5. Javascript学习总结 - JS基础系列三
  6. java中多叉树(tree)的生成与显示
  7. 对信号函数sigaction的sa_mask的学习
  8. Android通过广播接收者调用服务内方法
  9. vscode代码对比功能
  10. 前端,html,css,js,vue
  11. 【无标题】用ubuntu通过c语言实现俄罗斯方块小游戏的方案及改进思路
  12. Ubuntu 16.04安装sogou 拼音输入法
  13. IFI Claims:2018年中国企业在美国申请专利数量7298件
  14. centos 7 使用certbot解决域名证书续签最佳实践
  15. 对this.name=name的理解
  16. 学习笔记21--高精地图技术概述
  17. 任我发财663311conm_任我发财663311-王中王期期公开平特肖_特时代
  18. rabbitmq java 测试_RabbitMQ 简单测试
  19. 浅谈语音信号处理系列之二 语音信号处理的基础
  20. 如何更改自己电脑上的公网IP?

热门文章

  1. 批量 // 注释替换为 /*的注释
  2. python方式下自动登录51cto
  3. Windows2003 WINS 服务
  4. vue-cli3 按需加载loading,服务的方式调用
  5. 数学库及其应用math库与random库
  6. Impala 源码分析-FE
  7. 1249 Problem Q
  8. Codeforces Round #354 (Div. 2) A. Nicholas and Permutation
  9. 关于WEB标准的理解
  10. 想做Bezier动画,可惜弄出来这个差远了。