常用聚类算法
聚类算法是机器学习中非常重要的算法,聚类是将大量数据以相似度为基础形成若干类,使得类内之间的数据最为相似,各类之间的数据相似度差别尽可能大。聚类分析就是以相似性为基础,对数据集进行聚类划分,属于无监督学习。聚类分析可以直接比较各事物之间的性质,将性质相近的归为一类,将性质差别较大的归入不同的类。
聚类具有广泛的应用领域,对于网络流量的监控和数据挖掘,可以实现舆情分析,获知出现的前所未有的热点事件。在商业上,市场消费数据的聚类,可以使企业相关人员获知新的消费趋势和市场需求。而在城市规划领域,对于市政交通或者人口分布的聚类,可以帮助市政规划人员更好地进行城市分区和道路建设。
K均值聚类
特性
- 未标记的数据集聚类成不同的组
- 迭代移动簇中心和簇成员
- 簇内相似度高,簇间相似度低
- 局部最优,并非全局最优
步骤:
- 随机选择K个聚类中心
- 寻找每个数据点{x}距离最近的中心点,将两者关联,最后所有与同一中心点关联的点都聚成一类。
- 确定每组关联的中心点,并计算其均值。
- 反复操作2~3步,当中心点不发生变化时停止操作。
实现
# %%
import numpy as np
import pandas as pd
from numpy import *
# %%
def kmeans(data, k):
n, dim = data.shape
result = np.mat(np.zeros((n, 2))) # 存储每个点所属的中心点以及到中心点的距离
clusterstop = True
center = zeros((k, dim)) # 初始化质心点存储器
for i in range(k): # 随机选择k个质心点的位置
index = int(random.uniform(0, n))
center[i, :] = data[index, :]
while clusterstop:
clusterstop = False
for i in range(n): # 遍历点
dmin = 10000.0
Imin = 0
for j in range(k): # 计算当前点到某个质心点的距离,将其分配到距离最小的质心
distance = sqrt(sum(pow((center[j, :] - data[i, :]), 2)))
if distance < dmin: # 如果距离小于阈值,则将阈值降低,并记录最小距离点的索引
dmin = distance
Imin = j
if result[i, 0] != Imin: # 如果该点不属于该点群,则仍然继续参与下一轮聚类
clusterstop = True
result[i, :] = Imin, dim ** 2
# 更新各个质心的坐标
for j in range(k):
pointsInCluster = data[nonzero(result[:, 0].A == j)[0]]
center[j, :] = mean(pointsInCluster, axis=0)
return center, result
# %%
from sklearn.datasets import load_iris
from sklearn.utils import shuffle
iris = load_iris()
X = iris.data
y = iris.target
names = iris.feature_names
X = X[0:100]
y = y[0:100]
data_x = pd.DataFrame(X, columns=['f1', 'f2', 'f3', 'f4'])
data_y = pd.DataFrame(y, columns=['label'])
data = pd.concat([data_x, data_y], axis=1)
data
# %%
centers, results = kmeans(X, 3)
centers, results
# %%
cluster_result = []
idx = 0
from tqdm import tqdm, trange
pbar = tqdm(total=len(data))
for index, row in data.iterrows():
row['center_index'] = results.__array__()[idx][0]
row['distance'] = results.__array__()[idx][1]
# row['center_loc'] = centers[row['center_index']]
cluster_result.append(row)
idx += 1
pbar.update()
cluster_result = pd.DataFrame(cluster_result)
# %%
import seaborn as sns
import matplotlib.pyplot as plt
sns.scatterplot(x=cluster_result['f1'], y=cluster_result['f2'], hue=cluster_result['label'])
# plt.show()
sns.scatterplot(x=cluster_result['f1'], y=cluster_result['f2'], hue=cluster_result['center_index'])
plt.show()
缺陷
- 需要事先确定K值
如何改进
K-Harmonic Means(K调和均值)
- 根据簇均值将数据分为K个簇
- 通过目标函数和中心移动公式对簇成员和簇中心移动
- 算法迭代至不再有点移动为止
其评价函数为所有点到所有中心的均方距离的调和平均值函数,平均值定义为 H A = P ∑ i = 1 P 1 a i H A=\frac{P}{\sum_{i=1}^{P} \frac{1}{a_{i}}} HA=∑i=1Pai1P
然后将过于集中的中心点,移动到数据附近没有中心点的区域上,这种算法降低了对初始点选取的依赖,提高了算法的鲁棒性