文本聚类算法之一趟聚类(One-pass Cluster)算法的python实现
来源:互联网 发布:mes软件系统架构 编辑:程序博客网 时间:2024/06/05 10:09
一、算法简介
一趟聚类算法是由蒋盛益教授提出的无监督聚类算法,该算法具有高效、简单的特点。数据集只需要遍历一遍即可完成聚类。算法对超球状分布的数据有良好的识别,对凸型数据分布识别较差。一趟聚类可以在大规模数据,或者二次聚类中,或者聚类与其他算法结合的情况下,发挥其高效、简单的特点;
算法流程:
1. 初始时从数据集读入一个新的对象
2. 以这个对象构建一个新的簇
3. 若达到数据集末尾,则转6,否则读入一个新的对象;计算它与每个已有簇之间的距离,并选择与它距离最小的簇。
4. 若最小距离超过给定的阈值r,转2
5. 否则将对象并入该簇,并更新簇心,转3
6. 结束
在本算法中,采用的是欧式距离公式计算节点与簇心之间的距离
欧式距离公式:
二、实验
实验数据集:
中国天气的数据集,包括中国各个城市每年的最低和最高温以及该城市的x,y坐标。
实验数据:
https://raw.githubusercontent.com/Hareric/ClusterTool/master/Other/c2.txt
python代码:
# coding=utf-8import numpy as npfrom math import sqrtimport timeimport matplotlib.pylab as pl# 定义一个簇单元class ClusterUnit: def __init__(self): self.node_list = [] # 该簇存在的节点列表 self.node_num = 0 # 该簇节点数 self.centroid = None # 该簇质心 def add_node(self, node, node_vec): """ 为本簇添加指定节点,并更新簇心 node_vec:该节点的特征向量 node:节点 return:null """ self.node_list.append(node) try: self.centroid = (self.node_num * self.centroid + node_vec) / (self.node_num + 1) # 更新簇心 except TypeError: self.centroid = np.array(node_vec) * 1 # 初始化质心 self.node_num += 1 # 节点数加1 def remove_node(self, node): # 移除本簇指定节点 try: self.node_list.remove(node) self.node_num -= 1 except ValueError: raise ValueError("%s not in this cluster" % node) # 该簇本身就不存在该节点,移除失败 def move_node(self, node, another_cluster): # 将本簇中的其中一个节点移至另一个簇 self.remove_node(node=node) another_cluster.add_node(node=node)# cluster_unit = ClusterUnit()# cluster_unit.add_node(1, [1, 1, 2])# cluster_unit.add_node(5, [2, 1, 2])# cluster_unit.add_node(3, [3, 1, 2])# print cluster_unit.centroiddef euclidian_distance(vec_a, vec_b): # 计算向量a与向量b的欧式距离 diff = vec_a - vec_b return sqrt(np.dot(diff, diff)) # dot计算矩阵内积class OnePassCluster: def __init__(self, t, vector_list): # t:一趟聚类的阈值 self.threshold = t # 一趟聚类的阈值 self.vectors = np.array(vector_list) self.cluster_list = [] # 聚类后簇的列表 t1 = time.time() self.clustering() t2 = time.time() self.cluster_num = len(self.cluster_list) # 聚类完成后 簇的个数 self.spend_time = t2 - t1 # 聚类花费的时间 def clustering(self): self.cluster_list.append(ClusterUnit()) # 初始新建一个簇 self.cluster_list[0].add_node(0, self.vectors[0]) # 将读入的第一个节点归于该簇 for index in range(len(self.vectors))[1:]: min_distance = euclidian_distance(vec_a=self.vectors[0], vec_b=self.cluster_list[0].centroid) # 与簇的质心的最小距离 min_cluster_index = 0 # 最小距离的簇的索引 for cluster_index, cluster in enumerate(self.cluster_list[1:]): # enumerate会将数组或列表组成一个索引序列 # 寻找距离最小的簇,记录下距离和对应的簇的索引 distance = euclidian_distance(vec_a=self.vectors[index], vec_b=cluster.centroid) if distance < min_distance: min_distance = distance min_cluster_index = cluster_index + 1 if min_distance < self.threshold: # 最小距离小于阈值,则归于该簇 self.cluster_list[min_cluster_index].add_node(index, self.vectors[index]) else: # 否则新建一个簇 new_cluster = ClusterUnit() new_cluster.add_node(index, self.vectors[index]) self.cluster_list.append(new_cluster) del new_cluster def print_result(self, label_dict=None): # 打印出聚类结果 # label_dict:节点对应的标签字典 print "******* one-pass cluster result ***********" for index, cluster in enumerate(self.cluster_list): print "cluster:%s" % index # 簇的序号 print cluster.node_list # 该簇的节点列表 if label_dict is not None: print " ".join([label_dict[n] for n in cluster.node_list]) # 若有提供标签字典,则输出该簇的标签 print "node num: %s" % cluster.node_num print "-------------" print "the number of nodes %s" % len(self.vectors) print "the number of cluster %s" % self.cluster_num print "spend time %.9fs" % (self.spend_time / 1000)# 读取测试集temperature_all_city = np.loadtxt('c2.txt', delimiter=",", usecols=(3, 4)) # 读取聚类特征xy = np.loadtxt('c2.txt', delimiter=",", usecols=(8, 9)) # 读取各地经纬度f = open('c2.txt', 'r')lines = f.readlines()zone_dict = [i.split(',')[1] for i in lines] # 读取地区并转化为字典f.close()# 构建一趟聚类器clustering = OnePassCluster(vector_list=temperature_all_city, t=9)clustering.print_result(label_dict=zone_dict)# 将聚类结果导出图fig, ax = pl.subplots()fig = zone_dictc_map = pl.get_cmap('jet', clustering.cluster_num)c = 0for cluster in clustering.cluster_list: for node in cluster.node_list: ax.scatter(xy[node][0], xy[node][1], c=c, s=30, cmap=c_map, vmin=0, vmax=clustering.cluster_num) c += 1pl.show()
实验结果:
1 0
- 文本聚类算法之一趟聚类(One-pass Cluster)算法的python实现
- 一趟聚类(One-pass Cluster)及python实现
- 文本聚类算法之K-means算法的python实现
- streaming kmean cluster 聚类算法实现和分析
- 聚类算法学习----之----sklearn.cluster.KMeans
- 聚类算法学习----之----sklearn.cluster.DBSCAN
- 文本挖掘之聚类算法之CLARANS(基于随机选择的聚类算法)
- 一趟聚类
- 大数据算法课程笔记1:寻找中值算法之随机选取,中值的中值,One Pass算法
- 文本聚类算法Java实现
- 基于Single-pass的文本话题聚类
- 层次聚类算法的python实现
- 聚类之均值聚类(k-means)算法的python实现
- 聚类之均值聚类(k-means)算法的python实现
- 文本挖掘之文本聚类算法之PAM(k-中心点)
- 基于EM算法的文本聚类
- Python sklearn K-means算法及文本聚类实践
- 基于文本向量空间模型的文本聚类算法
- HDU 1010 Tempter of the Bone(DFS+奇偶剪枝)
- 电脑建立win7下wifi热点的问题解决
- Windows下Anaconda的安装和简单使用
- didRegisterForRemoteNotificationsWithDeviceToken不调用
- Window和WindowManager
- 文本聚类算法之一趟聚类(One-pass Cluster)算法的python实现
- 【iOS开发】iPad横屏打开系统相册崩溃,解决方案
- 了解 sdhash
- bower简明入门教程
- IntelliJ IDEA 设置Terminal 窗口字体大小
- Embedded System StartUp Procedure In detail (cc)
- jvm系列五:使用JMAP dump及分析dump文件
- 如何获取经纬度之间两点间真实距离(适用于GoogleMap,BaiduMap,Amap等)
- AndroidStudio配置gradle,让App自动签名