京公网安备 11010802034615号
经营许可证编号:京B2-20210330
数据聚类的简单应用
数据聚类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
在数字化商业环境中,数据已成为企业优化运营、抢占市场、规避风险的核心资产。但商业数据分析绝非“堆砌数据、生成报表”的简单 ...
2026-01-20定量报告的核心价值是传递数据洞察,但密密麻麻的表格、复杂的计算公式、晦涩的数值罗列,往往让读者望而却步,导致核心信息被淹 ...
2026-01-20在CDA(Certified Data Analyst)数据分析师的工作场景中,“精准分类与回归预测”是高频核心需求——比如预测用户是否流失、判 ...
2026-01-20在建筑工程造价工作中,清单汇总分类是核心环节之一,尤其是针对楼梯、楼梯间这类包含多个分项工程(如混凝土浇筑、钢筋制作、扶 ...
2026-01-19数据清洗是数据分析的“前置必修课”,其核心目标是剔除无效信息、修正错误数据,让原始数据具备准确性、一致性与可用性。在实际 ...
2026-01-19在CDA(Certified Data Analyst)数据分析师的日常工作中,常面临“无标签高维数据难以归类、群体规律模糊”的痛点——比如海量 ...
2026-01-19在数据仓库与数据分析体系中,维度表与事实表是构建结构化数据模型的核心组件,二者如同“骨架”与“血肉”,协同支撑起各类业务 ...
2026-01-16在游戏行业“存量竞争”的当下,玩家留存率直接决定游戏的生命周期与商业价值。一款游戏即便拥有出色的画面与玩法,若无法精准识 ...
2026-01-16为配合CDA考试中心的 2025 版 CDA Level III 认证新大纲落地,CDA 网校正式推出新大纲更新后的第一套官方模拟题。该模拟题严格遵 ...
2026-01-16在数据驱动决策的时代,数据分析已成为企业运营、产品优化、业务增长的核心工具。但实际工作中,很多数据分析项目看似流程完整, ...
2026-01-15在CDA(Certified Data Analyst)数据分析师的日常工作中,“高维数据处理”是高频痛点——比如用户画像包含“浏览次数、停留时 ...
2026-01-15在教育测量与评价领域,百分制考试成绩的分布规律是评估教学效果、优化命题设计的核心依据,而正态分布则是其中最具代表性的分布 ...
2026-01-15在用户从“接触产品”到“完成核心目标”的全链路中,流失是必然存在的——电商用户可能“浏览商品却未下单”,APP新用户可能“ ...
2026-01-14在产品增长的核心指标体系中,次日留存率是当之无愧的“入门级关键指标”——它直接反映用户对产品的首次体验反馈,是判断产品是 ...
2026-01-14在CDA(Certified Data Analyst)数据分析师的业务实操中,“分类预测”是高频核心需求——比如“预测用户是否会购买商品”“判 ...
2026-01-14在数字化时代,用户的每一次操作——无论是电商平台的“浏览-加购-下单”、APP的“登录-点击-留存”,还是金融产品的“注册-实名 ...
2026-01-13在数据驱动决策的时代,“数据质量决定分析价值”已成为行业共识。数据库、日志系统、第三方平台等渠道采集的原始数据,往往存在 ...
2026-01-13在CDA(Certified Data Analyst)数据分析师的核心能力体系中,“通过数据建立模型、实现预测与归因”是进阶关键——比如“预测 ...
2026-01-13在企业数字化转型过程中,业务模型与数据模型是两大核心支撑体系:业务模型承载“业务应该如何运转”的逻辑,数据模型解决“数据 ...
2026-01-12当前手游市场进入存量竞争时代,“拉新难、留存更难”成为行业普遍痛点。对于手游产品而言,用户留存率不仅直接决定产品的生命周 ...
2026-01-12