在大数据领域这个聚类算法真是起到了十分重要的作用,只有通过有效地聚类才能得到非常直观的结果。

有一个实验要求对比两种大数据聚类算法的性能,具体的代码也不是由我实现的,我只是改了一部分,主要还是博客大佬们的代码,我这里借用了一下~~
具体的实验报告和python源码文件在最后位置,提供百度云下载,本文使用的是K-means算法和层次聚类算法AGNES,原理介绍和实验结果详见百度云提供的报告等

如今大数据的时代,大量的可以获得的数据被保存,用来分析以获得有用的信息,然而数据纷繁杂乱,需要研究者对齐进行一定的划分,将相似的数据放在一起进行分析,这就是所谓的聚类。

聚类就是按照某个特定标准(如距离准则,即数据点之间的距离)把一个数据集分割成不同的类或簇,使得同一个簇内的数据对象的相似性尽可能大,同时不在同一个簇中的数据对象的差异性也尽可能地大,常用的基本的距离计算方式就是欧氏距离。我们可以具体地理解为,聚类后同一类的数据尽可能聚集到一起,不同类数据尽量分离。聚类技术正在蓬勃发展,应用到的领域包括数据挖掘、统计学、机器学习、空间数据库技术、生物学以及市场营销等。各种聚类方法也被不断提出和改进,而不同的方法适合于不同类型的数据,因此对各种聚类方法、聚类效果的比较是一个值得研究的问题。

目前,有大量的聚类算法。而对于具体应用,聚类算法的选择取决于数据的类型、聚类的目的。如果聚类分析被用作描述或探查的工具,可以对同样的数据尝试多种算法,以发现数据可能揭示的结果。主要的聚类算法可以划分为如下几类:划分方法、层次方法、基于密度的方法、基于网格的方法以及基于模型的方法。

K-means聚类算法

K-means是划分方法中较经典的聚类算法之一。由于该算法的效率高,所以在对大规模数据进行聚类时被广泛应用。目前,许多算法均围绕着该算法进行扩展和改进。K-means算法目标是,以k为参数,把n个对象分成k个簇,使簇内具有较高的相似度,而簇间的相似度较低。
K-means算法的处理过程如下:首先,随机地 选择k个对象,每个对象初始地代表了一个簇的平均值或中心;对剩余的每个对象,根据其与各簇中心的距离,将它赋给最近的簇;然后重新计算每个簇的平均值。 这个过程不断重复,直到准则函数收敛。
通常,采用平方误差准则。平方误差准则采用的是数据库中所有对象的平方误差的总和,与是空间中的点和每个簇的的平均值有关[9]。目标是使生成的簇尽可能紧凑独立,使用的距离度量是欧几里得距离,当然也可以用其他距离度量。K-means聚类算法的算法流程如下:
输入:包含n个对象的数据库和簇的数目k;
输出:k个簇,使平方误差准则最小。
步骤:
(1) 任意选择k个对象作为初始的簇中心;
(2) repeat;
(3) 根据簇中对象的平均值,将每个对象(重新)赋予最类似的簇;
(4) 更新簇的平均值,即计算每个簇中对象的平均值;
(5) until不再发生变化。
优点:简单直接(体现在逻辑思路以及实现难度上),易于理解,在低维数据集上有不错的效果(简单的算法不见得就不能得到优秀的效果)。
缺点:对于高维数据(如成百上千维,现实中还不止这么多),其计算速度十分慢,主要是慢在计算距离上(参考欧几里得距离,当然并行化处理是可以的,这是算法实现层面的问题),它的另外一个缺点就是它需要我们设定希望得到的聚类数k,若我们对于数据没有很好的理解,那么设置k值就成了一种估计性的工作,并且会对实验结果造成很大的偏差。

层次聚类算法

根据层次分解的顺序是自底向上的还是自上向下的,层次聚类算法分为凝聚的层次聚类算法和分裂的层次聚类算法。
凝聚型层次聚类的策略是先将每个对象作为一个簇,然后合并这些原子簇为越来越大的簇,直到所有对象都在一个簇中,或者某个终结条件被满足。绝大多数层次聚类属于凝聚型层次聚类,它们只是在簇间相似度的定义上有所不同。四种广泛采用的簇间距离度量方法为:最小距离,最大距离,平均值距离,平均距离。
这里以最小距离的凝聚层次聚类算法流程为例:
(1) 将每个对象看作一类,计算两两之间的最小距离;
(2) 将距离最小的两个类合并成一个新类;
(3) 重新计算新类与所有类之间的距离;
(4) 重复(2)、(3),直到所有类最后合并成一类。
优点:

  1. 距离和规则的相似度容易定义,限制少;
  2. 不需要预先制定聚类数;
  3. 可以发现类的层次关系(在一些特定领域如生物有很大作用);
    缺点:
  4. 计算复杂度太高(考虑并行化);
  5. 奇异值也能产生很大影响;
  6. 算法很可能聚类成链状(一层包含着一层);
  7. 算法不需要预定聚类数,但是我们选择哪个层次的聚类作为我们需要的聚类效果,这需要我们按照实际客观情况以及经验来完成,毕竟就凝聚聚类来说,从最底层的每个个体作为一个个体,到最顶层所有个体合并为一个个体,其中的聚类结果可能有许许多多种。当然针对这个问题也有许多解决方案,其中一个常用的就是凝聚到某个程度其聚类之间的距离都大于某个阈值k,就停止凝聚。

具体代码

在实验中,本人先是下载的点集,然后为了测试效率写了一个简单的产生大量点的脚本,具体的实现代码如下(来自网络 进行了小小的更改),注意需要的库文件,没有的安装一下,还有路径也需要改:
AGNES

#-*- coding:utf-8 -*-
import math
import pylab as pl
import codecs
import re
import datetimepl.rcParams['axes.unicode_minus'] = False
# 为了显示汉字坐标的#计算欧式距离,a,b代表两个元组
def calcudistance(a, b):return math.sqrt(math.pow(a[0]-b[0], 2)+math.pow(a[1]-b[1], 2))# 求出最小距离
def dist_min(Ci, Cj):return min(calcudistance(i, j) for i in Ci for j in Cj)# 求出最大距离
def dist_max(Ci, Cj):return max(calcudistance(i, j) for i in Ci for j in Cj)#求出平均距离
def dist_avg(Ci, Cj):return sum(calcudistance(i, j) for i in Ci for j in Cj)/(len(Ci)*len(Cj))#找到距离最小的下标
def find_Min(M):min = 1000x = 0; y = 0for i in range(len(M)):for j in range(len(M[i])):if i != j and M[i][j] < min:min = M[i][j];x = i; y = jreturn (x, y, min)#算法核心
def AGNES(dataset, dist, k):#初始化C和MC = [];M = []for i in dataset:Ci = []Ci.append(i)C.append(Ci)for i in C:Mi = []for j in C:Mi.append(dist(i, j))M.append(Mi)q = len(dataset)#合并更新while q > k:x, y, min = find_Min(M)C[x].extend(C[y])C.remove(C[y])M = []for i in C:Mi = []for j in C:Mi.append(dist(i, j))M.append(Mi)q -= 1return C# 画出结果图
def drawfig(C):colValue = ['r', 'y', 'g', 'b', 'c', 'k', 'm']  # 颜色数组for i in range(len(C)):coo_X = []    # x坐标coo_Y = []    # y坐标for j in range(len(C[i])):coo_X.append(C[i][j][0])coo_Y.append(C[i][j][1])pl.scatter(coo_X, coo_Y, marker='o', color=colValue[i%len(colValue)], label=i)pl.legend(loc='upper right')pl.title("聚类结果图")pl.savefig(savepath + '2.png')pl.show()def draworigian(dataset):x_list = list()y_list = list()for i in range(len(dataSet)):temp = dataSet[i]x_list.append(temp[0])y_list.append(temp[1])pl.scatter(x_list, y_list, marker='o', color="b")pl.legend(loc='upper right')pl.title("数据原始分布")pl.savefig(savepath + '1.png')pl.show()def loadtxt(Filepath):# 读取文本 保存为二维点集inDate = codecs.open(Filepath, 'r', 'utf-8').readlines()dataSet = list()for line in inDate:  # 段落的处理line = line.strip()strList = re.split('[ ]+', line)numList = list()for item in strList:num = float(item)numList.append(num)# print numListdataSet.append(numList)return dataSet  # dataSet = [[], [], [], ...]savepath='D:/学习/研1/模式识别/AGNES/'
Filepath = "D:/学习/研1/模式识别/testSet.txt"  # 数据集文件
dataSet = loadtxt(Filepath)  # 载入数据集
draworigian(dataSet)start = datetime.datetime.now()
result = AGNES(dataSet, dist_avg, 4)
end = datetime.datetime.now()
timeused = end - start
print(timeused)drawfig(result)# 100   1.203133, 01.140652, 1.156260, 1.203152, 1.453138
# 200点 9.359476, 09.367193, 09.312600, 09.325362, 09.356845
# 500点 147.946446, 147:351248, 147.153595,147.946446, 145.493638# 500 无需 145.429797 146.016936  147.240645  146.563253 147.534587

k-MEANS

# -*- coding: UTF-8 -*-
import numpy
import random
import codecs
import re
import matplotlib.pyplot as plt
import datetime
plt.rcParams['axes.unicode_minus'] = False  # 显示负号# 计算欧式距离,a,b代表两个向量
def calcudistance(a,b):return numpy.sqrt(numpy.sum(numpy.square(a - b)))# 初始化k个质心,数据集中随机选择
def initcentroids(dataSet, k):return random.sample(dataSet, k)  # 从dataSet中随机获取k个数据项返回def mindistance(dataSet, centroidList):# 对每个属于dataSet的item,计算item与centroidList中k个质心的欧式距离,找出距离最小的,# 并将item加入相应的簇类中clusterDict = dict()  # 用dict来保存簇类结果for item in dataSet:vec1 = numpy.array(item)  # 转换成array形式flag = 0  # 簇分类标记,记录与相应簇距离最近的那个簇minDis = float("inf")  # 初始化为最大值for i in range(len(centroidList)):vec2 = numpy.array(centroidList[i])distance = calcudistance(vec1, vec2)  # 计算相应的欧式距离if distance < minDis:minDis = distanceflag = i  # 循环结束时,flag保存的是与当前item距离最近的那个簇标记if flag not in clusterDict.keys():  # 簇标记不存在,进行初始化clusterDict[flag] = list()# print flag, itemclusterDict[flag].append(item)  # 加入相应的类别中return clusterDict  # 返回新的聚类结果def getCentroids(clusterDict):# 得到k个质心centroidList = list()for key in clusterDict.keys():centroid = numpy.mean(numpy.array(clusterDict[key]), axis=0)  # 计算每列的均值,即找到质心# print key, centroidcentroidList.append(centroid)return numpy.array(centroidList).tolist()def getVar(clusterDict, centroidList):# 计算簇集合间的均方误差# 将簇类中各个向量与质心的距离进行累加求和sum = 0.0for key in clusterDict.keys():vec1 = numpy.array(centroidList[key])distance = 0.0for item in clusterDict[key]:vec2 = numpy.array(item)distance += calcudistance(vec1, vec2)sum += distancereturn sum# 画出结果他图
def drawfig(centroidList, clusterDict):# 展示聚类结果global imgcountimgcount += 1colorMark = ['or', 'ob', 'og', 'ok', 'oy', 'ow']  # 不同簇类的标记 'or' --> 'o'代表圆,'r'代表red,'b':bluecentroidMark = ['dr', 'db', 'dg', 'dk', 'dy', 'dw']  # 质心标记 同上'd'代表棱形for key in clusterDict.keys():plt.plot(centroidList[key][0], centroidList[key][1], centroidMark[key], markersize=12)  # 画质心点for item in clusterDict[key]:plt.plot(item[0], item[1], colorMark[key])  # 画簇类下的点plt.title("聚类分布图")plt.savefig(savepath + str(imgcount) + '.png')plt.show()# 关键部分
def k_means(dataset,kindnum):centroidList = initcentroids(dataSet, 4)  # 初始化质心,设置k=4clusterDict = mindistance(dataSet, centroidList)  # 第一次聚类迭代newVar = getVar(clusterDict, centroidList)  # 获得均方误差值,通过新旧均方误差来获得迭代终止条件oldVar = -0.0001  # 旧均方误差值初始化为-1print("----- 第1次迭代 -----")print('k个均值向量: ')print(centroidList)print('平均均方误差: %d' % (newVar))# drawfig(centroidList, clusterDict)  # 展示聚类结果k = 2while abs(newVar - oldVar) >= 0.0001:  # 当连续两次聚类结果小于0.0001时,迭代结束centroidList = getCentroids(clusterDict)  # 获得新的质心clusterDict = mindistance(dataSet, centroidList)  # 新的聚类结果oldVar = newVarnewVar = getVar(clusterDict, centroidList)print('----- 第%d次迭代 -----\n簇类' %(k))print('k个均值向量: ')print(centroidList)print('平均均方误差: %d' %(newVar))k += 1  # 迭代次数return (centroidList,clusterDict)def loadtxt(Filepath):# 读取文本 保存为二维点集inDate = codecs.open(Filepath, 'r', 'utf-8').readlines()dataSet = list()for line in inDate:line = line.strip()strList = re.split('[ ]+', line)  # 去除多余的空格# print strList[0], strList[1]numList = list()for item in strList:num = float(item)numList.append(num)# print numListdataSet.append(numList)return dataSet  # dataSet = [[], [], [], ...]savepath = 'D:/学习/研1/模式识别/K-means/'
imgcount = 0
Filepath = "D:/学习/研1/模式识别/testSet.txt"  # 数据集文件
dataSet = loadtxt(Filepath)  # 载入数据集start = datetime.datetime.now()
centroidList, clusterDict = k_means(dataSet, 4)
end = datetime.datetime.now()
timeused = end - start
print(timeused)drawfig(centroidList, clusterDict)  # 展示聚类结果# 100   0.031245, 0.015623, 0.031249, 0.015609, 0.015624
# 200点 0.031232, 0.031253, 0.046892, 0.031234, 0.046875
# 500点 0.156265, 0.093733, 0.078108,0.062499, 0.187502
# 10000 2.000017# 无顺序 500 00.218750 00.547491 00.421866 00.281266 00.281266

最后这是是一个产生点集的脚本,分两种,一个是无序的随机,另一个是大概扎堆的,一个是为了检测效率,一个是为了测试效果。

import numpy as np
import copychoosetype = 2  # 1 表示有序点 其他表示随机点
data = [[3.5, -3.5], [3.5, 3.5], [-3.5, 3.5], [-3.5, -3.5]]  # 四类点的中心
totalnum =500    #产生点的个数
file_path = "D:\学习\研1\模式识别\\testSet2.txt"  # 保存路径fopen = open(file_path, 'w')  # 追加的方式读写打开for i in range(totalnum):if choosetype == 1:datatemp = copy.deepcopy(data)choose = datatemp[i % 4]n1 = 2*np.random.random(1) - 1n2 = 2*np.random.random(1) - 1choose[0] = choose[0] + n1choose[1] = choose[1] + n2fopen.writelines(str(round(choose[0][0], 6)) + "   " + str(round(choose[1][0], 6)) + "\n")else:n1 = 4 * np.random.random(1) - 2n2 = 4 * np.random.random(1) - 2fopen.writelines(str(round(n1[0], 6)) + "   " + str(round(n2[0], 6)) + "\n")
fopen.close()

实验结果

k-means测试结果,该算法有效


AGNES的结果,算法有效

为了比较性能,对大量的点进行实验,表格如下:

具体的算法原理和实验分析见报告内容,最后面提供百度云源码和报告的连接

心得体会

大数据可以说是现在研究十分火热的一个课题,在众多的研究室和科技公司等都是属于一个较为核心的项目。尤其是在当今网络迅速发展的时代,信息就意味着资源,如果能掌握信息就能把握机会。作为大数据分析的关键环节,聚类为分析者提供了效果超凡的数据预处理,使得我们可以发现在数据之下隐藏的逻辑关系与形势。

在众多的聚类算法之中,我们对两个基本的算法K-means和AGNES进行了了解和学习,并实用python语言来实现和对比两者的效果。结果表明,从大数据量的运算来讲,K-means快很多,但AGNES对数据的适用性更高。

在模式识别课程上,学习到了很多有关的人工智能和大数据分析等的知识,可以说获益匪浅。经过动手做实验,更加加深了我对聚类方法的理解,有助于以后更加深入的学习。首先,我要感谢老师耐心细致的授课,对基本概念的讲解十分简明易懂,采用的方式也让人容易理解。其次,感谢我的组员同学们对我实验期间的帮助,共同进步,共同提高。

下载地址:
链接: https://pan.baidu.com/s/1r0MXJSKO5uKq4hWa5IL0Dw 密码: 6sd3

大数据聚类算法性能比较及实验报告相关推荐

  1. 【学习机器学习】实验——聚类算法性能度量

    聚类算法性能度量 前言 一.实验目的 二.实验内容 1.变量a,b,c,d 2.Jaccard系数 3.闵可夫斯基距离 4.avg,diam,dmin,dcen,DB指数 4.1 avg(C) 4.2 ...

  2. 大数据智能算法及测评技术(二)

    3.分类算法及其测评 3.1 分类算法介绍 分类算法需要事先定义好类别,并对训练样本进行人工标记.分类算法通过有标记的训练样本,学习得到分类器,该分类器可对新样本自动分类,分类的流程下图所示.分类算法 ...

  3. 大数据常用算法及场景

    大数据常用算法及场景 大数据的挖掘是从海量.不完全的.有噪声的.模糊的.随机的大型数据库中发现隐含在其中有价值的.潜在有用的信息和知识的过程,也是一种决策支持过程.其主要基于人工智能,机器学习,模式学 ...

  4. 大数据新算法在个人信用风险评估模型中使用效果的评估

    风控系统资料 https://www.jianshu.com/p/db2aece905a7 基于大数据和机器学习的Web异常参数检测系统Demo实现 https://www.freebuf.com/a ...

  5. 人工智能快速发展的核心要素,大数据、算法和超级计算的介绍

    人工智能涉及的学科非常多.比如说计算机科学.脑科学.哲学.心理学.语言学等.学术界目前还没有统一的人工智能定义,不同研究方向的专家对人工智能的理解不一样,定义也有所侧重.目前比较通俗的定义是:人工智能 ...

  6. 大数据算法python_闲谈大数据和算法

    0x00 前言 本篇总结一下自己对大数据算法认知的过程.正文包含两部分:自己对算法的认知过程和对大数据算法的理解. 写这篇博客的原因有很多,总的来讲有下面几点: 自己在算法的路上一直懵懵懂懂,现在刚刚 ...

  7. 未来3大趋势:人工智能 产业互联网 大数据与算法

    https://www.toutiao.com/a6663751400771551747/ 2019-03-02 19:19:25 过去几十年是互联网飞速发展的时代,从90年代的网页互联网到新千年的P ...

  8. 大数据基础系列 5:Hadoop 实验——熟悉常用的 HDFS 目录操作和文件操作

    文章目录 前言 一.实验目的 二.实验平台 三.实验内容和要求 3.1.HDFS 目录操作 3.1.1.创建用户目录 3.1.2.显示 HDFS 中与当前用户对应的目录内容 3.1.3.列出 HDFS ...

  9. 机器学习及大数据经典算法笔记汇总

    机器学习及大数据经典算法笔记汇总 一.总结 二.机器学习及大数据算法 机器学习及大数据经典算法笔记汇总 一.总结 前面的博文,介绍了很多TensorFlow 以及 DeepLeaning 的算法.这里 ...

最新文章

  1. 人工智能为什么用python_使用python实现人工智能的优势
  2. 新的开始,连菜鸟都算不上的程序媛
  3. 第一人称视角的一种解决方案
  4. 论文浅尝 | 端到端神经视觉问答之上的显式推理
  5. 四级口语计算机对话,四级英语口语对话常用的句子
  6. winform最小化至托盘、右下角弹框提示
  7. 向量函数具有固定模的充要条件
  8. 【入门】QSS基础入门笔记
  9. 用友打印问题合集 一【各模块】
  10. 使用wamp3.0.6安装LimeSurvey时报“参数默认值只能为NULL”错误的解决办法
  11. CUDA11.0+cudnn8.0.5下载安装 2021-04-30
  12. python爬虫中遇到“\xb5”、“xa0”等字符时报错编码错误的处理方式
  13. 渣渣渣变渣渣系列(1)
  14. nc文件在ncl中取代nan值为缺省值
  15. 坯子库无法一键安装插件没用_坯子插件库:安装与使用
  16. pacman的常用命令
  17. 人工智障入门-没有灵魂的功夫茶
  18. tp-link wr 841n 300m 局域网限速的研究
  19. EBS系统的启动及关闭
  20. 杏雨梨云USB维护系统又升级了!——杏雨梨云USB维护系统2019端午版

热门文章

  1. Linux系统下查询PCI-e设备带宽速率
  2. 白嫖!10GB免流海外BackBlaze对象存储
  3. arduino nano 简单实现蓝牙模块与手机进行通信
  4. 计算机休眠usb充电,笔记本电脑在睡眠模式或盖子关闭时如何继续从USB端口充电设备 | MOS86...
  5. 电子商业承兑汇票到期怎么兑现
  6. Machine Learning Stanford (week 1)
  7. 如何区分单核与多核cpu及理解并行与并发
  8. 车载GPS导航错误原因解析
  9. OneNote 2016无法登陆
  10. 《乐高EV3机器人搭建与编程》——2.6 传感器