手写k-means算法
作为聚类的代表算法,k-means本属于NP难问题,通过迭代优化的方式,可以求解出近似解。
伪代码如下:

1,算法部分
距离采用欧氏距离。参数默认值随意选的。
import numpy as np
def k_means(x,k=4,epochs=500,delta=1e-3):
# 随机选取k个样本点作为中心
indices=np.random.randint(0,len(x),size=k)
centers=x[indices]
# 保存分类结果
results=[]
for i in range(k):
results.append([])
step=1
flag=True
while flag:
if step>epochs:
return centers,results
else:
# 合适的位置清空
for i in range(k):
results[i]=[]
# 将所有样本划分到离它最近的中心簇
for i in range(len(x)):
current=x[i]
min_dis=np.inf
tmp=0
for j in range(k):
distance=dis(current,centers[j])
if distance<min_dis:
min_dis=distance
tmp=j
results[tmp].append(current)
# 更新中心
for i in range(k):
old_center=centers[i]
new_center=np.array(results[i]).mean(axis=0)
# 如果新,旧中心不等,更新
# if not (old_center==new_center).all():
if dis(old_center,new_center)>delta:
centers[i]=new_center
flag=False
if flag:
break
# 需要更新flag重设为True
else:
flag=True
step+=1
return centers,results def dis(x,y):
return np.sqrt(np.sum(np.power(x-y,2)))
2,验证
我随机出了一些平面上的点,然后对其分类。
x=np.random.randint(0,50,size=100)
y=np.random.randint(0,50,size=100)
z=np.array(list(zip(x,y))) import matplotlib.pyplot as plt
%matplotlib inline plt.plot(x,y,'ro')
首先看看未分类之前的,当然也是跟分类后的分布是一样的。

然后看看分类后的结果:
centers,results=k_means(z) color=['ko','go','bo','yo']
for i in range(len(results)):
result=results[i]
plt.plot([res[0] for res in result],[res[1] for res in result],color[i])
plt.plot([res[0] for res in centers],[res[1] for res in centers],'ro')
plt.show()

可以看出,4个分类还是挺合理的。
再增加k=5试试,多执行几次看看。
centers,results=k_means(z,k=5) color=['ko','go','bo','yo','co']
for i in range(len(results)):
result=results[i]
plt.plot([res[0] for res in result],[res[1] for res in result],color[i])
plt.plot([res[0] for res in centers],[res[1] for res in centers],'ro')
plt.show()



可以看出,此算法对初值很敏感。
_^v^_
手写k-means算法的更多相关文章
- SpringCloud-Ribbon负载均衡机制、手写轮询算法
Ribbon 内置的负载均衡规则 在 com.netflix.loadbalancer 包下有一个接口 IRule,它可以根据特定的算法从服务列表中选取一个要访问的服务,默认使用的是「轮询机制」 Ro ...
- 面试题目:手写一个LRU算法实现
一.常见的内存淘汰算法 FIFO 先进先出 在这种淘汰算法中,先进⼊缓存的会先被淘汰 命中率很低 LRU Least recently used,最近最少使⽤get 根据数据的历史访问记录来进⾏淘汰 ...
- KNN 与 K - Means 算法比较
KNN K-Means 1.分类算法 聚类算法 2.监督学习 非监督学习 3.数据类型:喂给它的数据集是带label的数据,已经是完全正确的数据 喂给它的数据集是无label的数据,是杂乱无章的,经过 ...
- HashMap+双向链表手写LRU缓存算法/页面置换算法
import java.util.Hashtable; class DLinkedList { String key; //键 int value; //值 DLinkedList pre; //双向 ...
- 搞定redis面试--Redis的过期策略?手写一个LRU?
1 面试题 Redis的过期策略都有哪些?内存淘汰机制都有哪些?手写一下LRU代码实现? 2 考点分析 1)我往redis里写的数据怎么没了? 我们生产环境的redis怎么经常会丢掉一些数据?写进去了 ...
- 4.redis 的过期策略都有哪些?内存淘汰机制都有哪些?手写一下 LRU 代码实现?
作者:中华石杉 面试题 redis 的过期策略都有哪些?内存淘汰机制都有哪些?手写一下 LRU 代码实现? 面试官心理分析 如果你连这个问题都不知道,上来就懵了,回答不出来,那线上你写代码的时候,想当 ...
- OpenCV手写数字字符识别(基于k近邻算法)
摘要 本程序主要参照论文,<基于OpenCV的脱机手写字符识别技术>实现了,对于手写阿拉伯数字的识别工作.识别工作分为三大步骤:预处理,特征提取,分类识别.预处理过程主要找到图像的ROI部 ...
- k最邻近算法——使用kNN进行手写识别
上篇文章中提到了使用pillow对手写文字进行预处理,本文介绍如何使用kNN算法对文字进行识别. 基本概念 k最邻近算法(k-Nearest Neighbor, KNN),是机器学习分类算法中最简单的 ...
- 一看就懂的K近邻算法(KNN),K-D树,并实现手写数字识别!
1. 什么是KNN 1.1 KNN的通俗解释 何谓K近邻算法,即K-Nearest Neighbor algorithm,简称KNN算法,单从名字来猜想,可以简单粗暴的认为是:K个最近的邻居,当K=1 ...
- KNN (K近邻算法) - 识别手写数字
KNN项目实战——手写数字识别 1. 介绍 k近邻法(k-nearest neighbor, k-NN)是1967年由Cover T和Hart P提出的一种基本分类与回归方法.它的工作原理是:存在一个 ...
随机推荐
- 【学习备份】ajax添加小例子
实现目的:保存模板编号.模板名称到数据库 1.js引用 <script src="../../../../../../../js/jquery-1.10.2.min.js"& ...
- git回退错误的提交
提交代码导致冲突,执行merge后,冲掉其他人的提交.需要reset,并新建分支进行恢复 解决方法: 1.找到最后一次提交到master分支的版本号,即[merge前的版本号] 2.会退到某个版本号 ...
- nginx信号
ps aux | grep nginx #查看nginx进程,要查看nginx的pid,就得使用这个命令查看*********************nginx信号****************** ...
- poi 1017 Packets 贪心+模拟
Packets Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 48349 Accepted: 16392 Descrip ...
- Spring——bean的五种作用域和生命周期
一.Bean的作用域 1.当一个bean的作用域为Singleton,那么Spring IoC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回 ...
- Python基础之Python解释器
当我们在编写Python代码时,我们得到的是一个包含Python代码的,以.py为扩展名的文本文件.要运行代码,就需要Python解释器去执行.py文件. 由于整个Python语言从规范到解释器都是开 ...
- SpringMVC接收请求参数和页面传参
接收请求参数: 1,使用HttpServletRequest获取 @RequestMapping("/login.do") public String login(HttpServ ...
- canvas基础知识点(一)
给canvas设置宽高: canvas标签的宽高默认是300*150,是一个行内块元素 可以在canvas标签上通过width,height来设置 可以在js中给dom对象设置: mycanvas.w ...
- python3笔记二十四:Mysql数据库操作命令
一:学习内容 Mysql操作命令:启动服务.停止服务.连接数据库.退出数据库.查看版本.显示当前时间.远程连接 数据库操作命令:创建数据库.删除数据库.切换数据库.查看当前选择的数据库 表操作命令:查 ...
- Cortex-M3 在C中上报入栈的寄存器和各fault状态寄存器
因为在标准C语音中是不能获取SP指针的.因而,如果想通过C代码来获取入栈的寄存器值,需要配合一小段汇编代码来获取当前的SP值,然后再把这个SP值以参数形式传送给C代码,最后以指针的形式把栈中的各寄存器 ...