手写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提出的一种基本分类与回归方法.它的工作原理是:存在一个 ...
随机推荐
- BZOJ 3626 [LNOI2014]LCA 树剖+(离线+线段树 // 在线+主席树)
BZOJ 4012 [HNOI2015]开店 的弱化版,离线了,而且没有边权(长度). 两种做法 1 树剖+离线+线段树 这道题求的是一个点zzz与[l,r][l,r][l,r]内所有点的lcalca ...
- [BZOJ 1095] [ZJOI2007]Hide 捉迷藏——线段树+括号序列(强..)
神做法-%dalao,写的超详细 konjac的博客. 如果觉得上面链接的代码不够优秀好看,欢迎回来看本蒟蒻代码- CODE WITH ANNOTATION 代码中−6-6−6表示左括号'[',用−9 ...
- 浅析flex 布局
Flex基本概念: 容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis).主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end: ...
- C# 数组转字符串显示
, , , , , , , }; arry[] = (] | ); string result = String.Join("", arry); Console.WriteLine ...
- perl 纯变量(Scalar) 转载
转载http://blog.chinaunix.net/uid-20639775-id-154591.html Perl有三种变量: 纯变量(Scalar Varible) 数组(Array) 关联数 ...
- js中声明函数的区别
在JS中有两种定义函数的方式, 1是var aaa=function(){...} 2是function aaa(){...} var 方式定义的函数,不能先调用函数,后声明,只能先声明函数,然后调用 ...
- [Centos7]Centos7安装
Centos7安装 安装wget yum -y install wget 更换镜像源 # 备份本地yum源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum. ...
- noi.ac #534 猫
题目链接:戳我 [问题描述] 有n座山,m只猫和p个工作人员.山从左往右编号为1∼n,山i和i−1之间的距离是di米. 有一天,猫都到山上去玩了:第i只猫会到山hi去,并一直玩到时间ti,之后就在那座 ...
- python获取某路径下某扩展名的所有文件名和文件个数
# -*- coding: utf-8 -*- # @Time : 19-1-10 下午10:02 # @Author : Felix Wang import os def get_file_coun ...
- Jmeter -- 循环控制器和线程并发(关注执行顺序)
测试计划中包含两个线程组,分别设置如下: 线程组1:线程数为2,循环次数为4 线程组2:线程数为4 执行顺序 监听器View Results in Table(用表格查看结果)中,ThreadName ...