“物以类聚,人以群分”,聚类是一种日常生活中常见的现象。所谓类,其实就是相似元素的结合。那么问题来了:如何判断元素之间是否相似?我们常常说,相似就是相近,即需要有合理的距离的度量方法来决定是否相似。而如果元素本身的属性非常多,从不同的属性去看元素之间的相似性,可能有不同的结果。
聚类分析属于分类学,以前人们往往是依赖经验和专业知识来实现分类。聚类分析有多种算法,可以作为其他分析算法的预处理。挑战在于高维空间中的稀疏数据,可能存在不平衡、高度偏斜的数据情况。
在常见的六大聚类算法_从未完美过的博客-CSDN博客_聚类算法上列出了六大常见聚类算法。
1. Kmeans
使用的是欧拉距离。其基本思想是初始的时候随机定K个簇中心,然后计算各个点到中心的距离,将点分到距离最短的簇。然后再取该簇所有点坐标的平均值作为簇新的质心,也就是新的簇心,再一次计算各个点到中心的距离,进行分簇。这样一直迭代,直到簇心的移动距离小于某个给定的值,也就是簇心的变动小于提前给定的标准。
优点:计算快。 缺点:要提前设定K,也就是类别数。
# -*- coding:utf-8 -*- import numpy as np from matplotlib import pyplot class K_Means(object): # k是分组数;tolerance‘中心点误差’;max_iter是迭代次数 def __init__(self, k=2, tolerance=0.0001, max_iter=300): self.k_ = k self.tolerance_ = tolerance self.max_iter_ = max_iter def fit(self, data): self.centers_ = {} for i in range(self.k_): self.centers_[i] = data[i] for i in range(self.max_iter_): self.clf_ = {} for i in range(self.k_): self.clf_[i] = [] # print("质点:",self.centers_) for feature in data: # distances = [np.linalg.norm(feature-self.centers[center]) for center in self.centers] distances = [] for center in self.centers_: # 欧拉距离 # np.sqrt(np.sum((features-self.centers_[center])**2)) distances.append(np.linalg.norm(feature - self.centers_[center])) classification = distances.index(min(distances)) self.clf_[classification].append(feature) # print("分组情况:",self.clf_) prev_centers = dict(self.centers_) for c in self.clf_: self.centers_[c] = np.average(self.clf_[c], axis=0) # '中心点'是否在误差范围 optimized = True for center in self.centers_: org_centers = prev_centers[center] cur_centers = self.centers_[center] if np.sum((cur_centers - org_centers) / org_centers * 100.0) > self.tolerance_: optimized = False if optimized: break def predict(self, p_data): distances = [np.linalg.norm(p_data - self.centers_[center]) for center in self.centers_] index = distances.index(min(distances)) return index
相关的链接:聚类算法_百度百科