之前写的入门级介绍,有点久远有些ref找不着了
文章目录
简介
- 根据在数据中发现的描述对象及其关系的信息,将数据对象分组。
- 对大量未知标注的数据集,按数据的内在相似性将数据集划分为多个类别,使类别内的数据相似度极大而类别间的数据相似度极小。
目标
- 组内的对象相互之间是相似的,不同组中的对象是不同的。
作用
-
易于理解
?生物学:界门纲目科属种
?信息检索:搜索引擎返回结果分类
?商业:对客户进行分类
-
更加实用
?降维:样本数的降维、特征数的降维
?发现最近邻:减少计算量
类型
| 分类 | 解释 |
|---|---|
| 层次的 v s vs vs 划分的 |
层次的: 嵌套的,树状,可在不同层次上得到不同数目的类别。 划分的: 非嵌套的。每个样本恰在一个子集中。 |
| 互斥的 v s vs vs 重叠的 v s vs vs 模糊的 |
互斥的: 每个样本仅在一个类中。 重叠的: 一个样本可同时属于多个类。 模糊的: 每个样本以0(绝对不属于)和1(绝对属于)之间的权值属于每个类。 |
| 完全的 v s vs vs 部分的 |
完全的: 每个样本至少属于一个类。 部分的: 部分样本不属于任何一个类,如噪声、离群点等。 |
聚类vs分类
import random
import matplotlib.pyplot as plt
import pandas as pd
from sklearn import datasets
from pandas import DataFrame
# 造数据
# 圈圈
noisy_circles=datasets.make_circles(n_samples=1000,factor=.5,noise=.05)
circle = DataFrame()
circle['x1'] = noisy_circles[0][:,0]
circle['x2'] = noisy_circles[0][:,1]
circle['label'] = noisy_circles[1]
# 堆堆
def random_sample(num, mean, st):
'''
num:个数
mean:均值
st:标准差
'''
sample = []
i = 0
while i < num:
sample.append(random.gauss(mean, st))
i += 1
return sample
num = 300
sample_0 = pd.DataFrame({
'x1':random_sample(num, 4, 0.5), 'x2': random_sample(num, 4, 0.5), 'y': [0 for i in range(num)]})
sample_1 = pd.DataFrame({
'x1':random_sample(num, 2, 0.5), 'x2': random_sample(num, 2, 0.5), 'y': [1 for i in range(num)]})
sample = pd.concat([sample_0, sample_1])
# 聚类vs分类
plt.figure(figsize=(16,8))
plt.subplot(1,2,1)
plt.scatter(sample_0['x1'], sample_0['x2'], marker = 'o', c = 'k')
plt.scatter(sample_1['x1'], sample_1['x2'], marker = 'o', c = 'k')
plt.title('聚类(无监督)', fontsize =25)
plt.subplot(1,2,2)
plt.scatter(sample_0['x1'], sample_0['x2'], marker = 'o', c = 'b')
plt.scatter(sample_1['x1'], sample_1['x2'], marker = 'o', c = 'r')
plt.title('分类(有监督)', fontsize =25)
plt.show()

K-means
[K-means] 伪代码
#####################################
- 选择 k k k个点作为初始质心。
- repeat
- 将每个点指派到最近的质心,形成 k k k个簇。
- 重新计算每个簇的质心。
- until 质心不发生变化。
#####################################
[K-means] 过程详解
ref: GitHub: snippet-code
# 修改
data = sample
repeat = 20
# ================开始================
# 导入数据
points = [[data.iloc[i].x1, data.iloc[i].x2] for i in range(len(data))]
# 初始质心
currentCenter1 = [data.x1.min() + (data.x1.max()-data.x1.min())*random.random(), data.x1.min() + (data.x2.max()-data.x2.min())*random.random()]
currentCenter2 = [data.x1.min() + (data.x1.max()-data.x1.min())*random.random(), data.x1.min() + (data.x2.max()-data.x2.min())*random.random()]
# 记录每次迭代后每个簇的质心的更新轨迹
center1 = [currentCenter1]; center2 = [currentCenter2]
# 丢点图
plt.figure(figsize=(18,18))
ax = plt.subplot(3,3, 1)
change_ax(ax)
plt.title('step 0', fontsize = 15)
plt.plot([eachpoint[0] for eachpoint in points], [eachpoint[1] for eachpoint in points], '.', color='grey')
plt.scatter([eachcenter[0] for eachcenter in center1], [eachcenter[1] for eachcenter in center1], marker='x', c='b', s=100)
plt.scatter([eachcenter[0] for eachcenter in center2], [eachcenter[1] for eachcenter in center2], marker='x', c='g', s=100)
# 两个簇
group1 = []; group2 = []
for runtime in range(repeat):
group1 = []; group2 = []
for eachpoint in points:
# 计算每个点到质心的距离
distance1 = pow(abs(eachpoint[0]-currentCenter1[0]),2) + pow(abs(eachpoint[1]-currentCenter1[1]),2)
distance2 = pow(abs(eachpoint[0]-currentCenter2[0]),2) + pow(abs(eachpoint[1]-currentCenter2[1]),2)
# 将该点指派到离它最近的质心所在的簇
mindis = min(distance1,distance2)
if(mindis == distance1):
group1.append(eachpoint)
else:
group2.append(eachpoint)
if runtime < 5 or runtime > (repeat - 4):
# 只可视化前五次最后三次
if runtime < 5:
ax = plt.subplot(3,3, runtime+2)
change_ax(ax)
plt.title('step %d'%(runtime+1), fontsize = 15)
else:
ax = plt.subplot(3,3, 10-repeat+runtime)
change_ax(ax)
plt.title('step %d'%(runtime+1), fontsize = 15)

最低0.47元/天 解锁文章
911

被折叠的 条评论
为什么被折叠?



