
数据聚类的简单应用
数据聚类data clustering:用来寻找紧密相关的事物,并将其可视化的方法。
1. 聚类时常被用于数据量很大(data-intensive)的应用中。
2. 聚类是无监督学习(unsupervised learning)的一个例子。无监督学习算法并不利用带有正确答案的样本数据进行“训练”,它们的目的是要在一组数据中找寻某种结构,而这些数据本身并不是我们要找的答案。
3. 聚类的结果不会告诉零售商每位顾客可能会买什么,也不会预测新来的顾客适合哪种时尚,聚类算法的目标是采集数据,然后从中找出不同的数组。
例如:可以通过聚类来对博客用户进行分类
这个说法的假设前提是:我们有众多的博客用户,但这些用户并没有显著的特征标签,在这种情况下,如何有效的对这些用户进行分类。这时候聚类就派上用场了。
基本过程:
1. 构建一个博客订阅源列表
2. 利用订阅源列表建立一个单词列表,将其实际用于针对每个博客的单词计数。
3. 我们利用上述单词列表和博客列表来建立一个文本文件,其中包含一个大的矩阵,记录者针对每个博客的所有单词的统计情况。(例如:可以用列对应单词,用行对应博客),一个可用的代码如下:
[python] view plain copy
import feedparser
import re
# Returns title and dictionary of word counts for an RSS feed
def getwordcounts(url):
# Parse the feed
d=feedparser.parse(url)
wc={}
# Loop over all the entries
for e in d.entries:
if 'summary' in e: summary=e.summary
else: summary=e.description
# Extract a list of words
words=getwords(e.title+' '+summary)
for word in words:
wc.setdefault(word,0)
wc[word]+=1
return d.feed.title,wc
def getwords(html):
# Remove all the HTML tags
txt=re.compile(r'<[^>]+>').sub('',html)
# Split words by all non-alpha characters
words=re.compile(r'[^A-Z^a-z]+').split(txt)
# Convert to lowercase
return [word.lower() for word in words if word!='']
4. 当然这里有很多可以减少需要统计的单词量的技巧,有些常用的习惯性用于可以从这些列表中删除掉。具体的构建过程这里省略不谈,感兴趣的可以参考相关书籍。
5. 进行聚类:这里有两种可用的方法
分级聚类:
分级聚类通过连续不断地将最为相似的群组两两合并,直到只剩一个群组为止,来构造出一个群组的层级结构。其过程可以参考下图:
图:分级聚类的过程
分级聚类基本算法如下:(这里省略了一些细节函数,如加载文件,计算皮尔逊相似度等)
[python] view plain copy
def hcluster(rows,distance=pearson):
distances={}
currentclustid=-1
# Clusters are initially just the rows
clust=[bicluster(rows[i],id=i) for i in range(len(rows))]
while len(clust)>1:
lowestpair=(0,1)
closest=distance(clust[0].vec,clust[1].vec)
# loop through every pair looking for the smallest distance
for i in range(len(clust)):
for j in range(i+1,len(clust)):
# distances is the cache of distance calculations
if (clust[i].id,clust[j].id) not in distances:
distances[(clust[i].id,clust[j].id)]=distance(clust[i].vec,clust[j].vec)
d=distances[(clust[i].id,clust[j].id)]
if d<closest:
closest=d
lowestpair=(i,j)
# calculate the average of the two clusters
mergevec=[
(clust[lowestpair[0]].vec[i]+clust[lowestpair[1]].vec[i])/2.0
for i in range(len(clust[0].vec))]
# create the new cluster
newcluster=bicluster(mergevec,left=clust[lowestpair[0]],
right=clust[lowestpair[1]],
distance=closest,id=currentclustid)
# cluster ids that weren't in the original set are negative
currentclustid-=1
del clust[lowestpair[1]]
del clust[lowestpair[0]]
clust.append(newcluster)
return clust[0]
待分级聚类完成后,我们可以采用一种图形化的方式来展现所得的结果,这种图被称为树状图(dendrogram),如下图所示。例如:我们针对博客数据进行聚类,以构造博客的层级结构,如果构造成功,我们将实现按主题对博客进行分组。
树状图的绘制,可以使用一个Python包:Python Imaging Library(PIL)
借助PIL,我们可以非常轻松地生成带有文本和线条的图形。
[python] view plain copy
from PIL import Image,ImageDraw<span style="font-family:Arial, Helvetica, sans-serif;background-color:rgb(255,255,255);"> </span>
首先,必须利用一个函数来返回给定聚类的总体高度。
此外,还必须知道节点的总体误差。萧条的长度会根据每个节点的误差进行相应的调整,所以我们需要根据总的误差值生成一个缩放因子scaling factor.
对于绘制的图形,线条越长就越表明,合并在一起的两个聚类差别很大,线条越短,则表示两个聚类的相似度很高。
K-均值聚类:
分级聚类的结果为我们返回了一棵形象直观的树。但存在两个缺点:
1. 没有额外投入的情况下,树形视图是不会真正将数据拆分成不同组的
2. 算法的计算量非常大,大数据集情况下,速度很慢
K-均值聚类:
预先告诉速算法希望生成的聚类数量,然后算法会根据数据的结构状况来确定聚类的大小。
算法首先会随机确定K个中心位置,然后将各个数据项分配给最临近的中心点。待分配完成之后,聚类中心就会移到分配给该聚类的所有节点的平均位置处,然后整个分配过程重新开始。这一过程会一直重复下去,知道分配过程不再产生变化为止。
代码如下:
[python] view plain copy
import random
def kcluster(rows,distance=pearson,k=4):
# Determine the minimum and maximum values for each point
ranges=[(min([row[i] for row in rows]),max([row[i] for row in rows]))
for i in range(len(rows[0]))]
# Create k randomly placed centroids
clusters=[[random.random()*(ranges[i][1]-ranges[i][0])+ranges[i][0]
for i in range(len(rows[0]))] for j in range(k)]
lastmatches=None
for t in range(100):
print 'Iteration %d' % t
bestmatches=[[] for i in range(k)]
# Find which centroid is the closest for each row
for j in range(len(rows)):
row=rows[j]
bestmatch=0
for i in range(k):
d=distance(clusters[i],row)
if d<distance(clusters[bestmatch],row): bestmatch=i
bestmatches[bestmatch].append(j)
# If the results are the same as last time, this is complete
if bestmatches==lastmatches: break
lastmatches=bestmatches
# Move the centroids to the average of their members
for i in range(k):
avgs=[0.0]*len(rows[0])
if len(bestmatches[i])>0:
for rowid in bestmatches[i]:
for m in range(len(rows[rowid])):
avgs[m]+=rows[rowid][m]
for j in range(len(avgs)):
avgs[j]/=len(bestmatches[i])
clusters[i]=avgs
return bestmatches
其过程如下图所示:
图:K-均值聚类
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
用 Power BI 制作地图热力图:基于经纬度数据的实践指南 在数据可视化领域,地图热力图凭借直观呈现地理数据分布密度的优势,成 ...
2025-07-24解析 insert into select 是否会锁表:原理、场景与应对策略 在数据库操作中,insert into select 是一种常用的批量数据插入语句 ...
2025-07-24CDA 数据分析师的工作范围解析 在数字化时代的浪潮下,数据已成为企业发展的核心资产之一。CDA(Certified Data Analyst)数据分 ...
2025-07-24从 CDA LEVEL II 考试题型看 Python 数据分析要点 在数据科学领域蓬勃发展的当下,CDA(Certified Data Analyst)认证成为众多从 ...
2025-07-23用 Python 开启数据分析之旅:从基础到实践的完整指南 在数据驱动决策的时代,数据分析已成为各行业不可或缺的核心能力。而 Pyt ...
2025-07-23鸢尾花判别分析:机器学习中的经典实践案例 在机器学习的世界里,有一个经典的数据集如同引路明灯,为无数初学者打开了模式识别 ...
2025-07-23解析 response.text 与 response.content 的核心区别 在网络数据请求与处理的场景中,开发者经常需要从服务器返回的响应中提取数 ...
2025-07-22解析神经网络中 Softmax 函数的核心作用 在神经网络的发展历程中,激活函数扮演着至关重要的角色,它们为网络赋予了非线性能力, ...
2025-07-22CDA数据分析师证书考取全攻略 一、了解 CDA 数据分析师认证 CDA 数据分析师认证是一套科学化、专业化、国际化的人才考核标准, ...
2025-07-22左偏态分布转正态分布:方法、原理与实践 左偏态分布转正态分布:方法、原理与实践 在统计分析、数据建模和科学研究中,正态分 ...
2025-07-22你是不是也经常刷到别人涨粉百万、带货千万,心里痒痒的,想着“我也试试”,结果三个月过去,粉丝不到1000,播放量惨不忍睹? ...
2025-07-21我是陈辉,一个创业十多年的企业主,前半段人生和“文字”紧紧绑在一起。从广告公司文案到品牌策划,再到自己开策划机构,我靠 ...
2025-07-21CDA 数据分析师的职业生涯规划:从入门到卓越的成长之路 在数字经济蓬勃发展的当下,数据已成为企业核心竞争力的重要来源,而 CD ...
2025-07-21MySQL执行计划中rows的计算逻辑:从原理到实践 MySQL 执行计划中 rows 的计算逻辑:从原理到实践 在 MySQL 数据库的查询优化中 ...
2025-07-21在AI渗透率超85%的2025年,企业生存之战就是数据之战,CDA认证已成为决定企业存续的生死线!据麦肯锡全球研究院数据显示,AI驱 ...
2025-07-2035岁焦虑像一把高悬的利刃,裁员潮、晋升无望、技能过时……当职场中年危机与数字化浪潮正面交锋,你是否发现: 简历投了10 ...
2025-07-20CDA 数据分析师报考条件详解与准备指南 在数据驱动决策的时代浪潮下,CDA 数据分析师认证愈发受到瞩目,成为众多有志投身数 ...
2025-07-18刚入职场或是在职场正面临岗位替代、技能更新、人机协作等焦虑的打工人,想要找到一条破解职场焦虑和升职瓶颈的系统化学习提升 ...
2025-07-182025被称为“AI元年”,而AI,与数据密不可分。网易公司创始人丁磊在《AI思维:从数据中创造价值的炼金术 ...
2025-07-18CDA 数据分析师:数据时代的价值挖掘者 在大数据席卷全球的今天,数据已成为企业核心竞争力的重要组成部分。从海量数据中提取有 ...
2025-07-18