`

分级聚类算法(集体智慧编程)

阅读更多

分级聚类是通过连续不断地将最为相似的群组两两合并,来构造出一个群组的层级结构。其中的每个群组都是从单一元素开始的。如图所示:

元素的相似程序是通过它们的相对位置来体现的,距离越近越相似。两两合并,直到合并最后两个群组。

 

聚类是无监督学习的一个例子。与神经网络或决策树不同,无监督学习算法不是利用带有正确答案的样本数据进行“训练”。它们的目的是要在一组数据中找寻某种结构,而这些数据本身不是我们要找的答案。聚类算法的目标是采集数据,然后从中找出不同的群组。

 

下面我就利用分级聚类算法对iteye和csdn的博客进行分类。

 

1.准备数据。利用feedparser解析博客rss订阅源,利用jieba中文拆词获取关键词及其出现次数。

2.合并数据。利用皮尔逊相关度算法计算数据的相似度,两两合并相似度最小的数组,直到只剩下一个数级为止。

3.绘制树状图。利用PIL将合并后的数据做成图片,以此清晰地展现数据结构。

 

下面开始第一步:

安装feedparser.

feedparser是一个python库,可以用以分析RSS和Atom的订阅源。下载地址https://code.google.com/p/feedparser/downloads/list。解压后在feedparser目录下命令行输入python setup.py install。

下面去寻找一些iteye和csdn博客的订阅源。下面是我随便找的10个,写入到feedlist.txt中。

 

http://blog.csdn.net/xxg2810/rss/list
http://lobert.iteye.com/rss
http://blog.csdn.net/lfsf802/rss/list
http://blog.csdn.net/david_lv/rss/list
http://blog.csdn.net/m13666368773/rss/list
http://blog.csdn.net/shulianghan/rss/list
http://blog.csdn.net/withiter/rss/list
http://blog.csdn.net/lfsf802/rss/list
http://blog.csdn.net/pan_tian/rss/list
http://blog.csdn.net/beijiguangyong/rss/list

 

 

因为我们在天朝,所以用的当然是中文,因此需要一个分词库,这里我使用jieba(开始使用的是mmseg-cpp,但在实际运行中会出现卡死的现象)。

下载地址:https://github.com/fxsjy/jieba,解压后将文件夹直接放到python默认库地址即可。

准备工作完毕,开始mark了。

 

#encoding=utf-8           #注意编码
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import feedparser
import re
import jieba

# 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)
  algor = jieba.cut(txt,cut_all=True) 

  # Split words by all non-alpha characters
  # words=re.compile(r'[^A-Z^a-z]+').split(txt)

  # Convert to lowercase
  return [tok.lower() for tok in algor if tok!='']
  # return [word.lower() for word in words if word!='']
  

apcount={}
wordcounts={}
feedlist=[line for line in file('feedlist.txt')]
for feedurl in feedlist:
  try:
    title,wc=getwordcounts(feedurl)
    wordcounts[title]=wc
    for word,count in wc.items():
      apcount.setdefault(word,0)
      if count>1:
        apcount[word]+=1
  except:
    print 'Failed to parse feed %s' % feedurl

wordlist=[]
for w,bc in apcount.items():
  frac=float(bc)/len(feedlist)
  if frac>0.1 and frac<0.5:       //因为像“我”这样的单词几乎到处都是,而像“PYTHON”这样的单词则有可能只出现在个别博客中,所以通过只选择介于某个百分比范围内的单词,我们可以减少需要考查的单词总量。我们这里将1/10为下界,5/10为上界。
    wordlist.append(w)

out=file('blogdata1.txt','w')
out.write('Blog')
for word in wordlist: out.write('\t%s' % word.strip())
out.write('\n')
for blog,wc in wordcounts.items():
  out.write(blog)
  for word in wordlist:
    if word in wc: out.write('\t%d' % wc[word])
    else: out.write('\t0')
  out.write('\n')

 程序运行后数据保存到文件中,我这里跑了40s,如无意外,出现的是一个表格。其中的每一列对应一个单词,每一行对应一个博客。表格的数字就是单词出现在博客中的次数。



由于宽度原因,因此只截取部分数据。

到此,数据准备完毕。

 

 

第二步:mark

 

def readfile(filename):
  lines=[line for line in file(filename)]
  
  # First line is the column titles
  colnames=lines[0].strip().split('\t')[1:]
  rownames=[]
  data=[]
  for line in lines[1:]:
    p=line.strip().split('\t')
    # First column in each row is the rowname
    rownames.append(p[0])
    # The data for this row is the remainder of the row
    data.append([float(x) for x in p[1:]])
  return rownames,colnames,data


from math import sqrt

def pearson(v1,v2):
  # Simple sums
  sum1=sum(v1)
  sum2=sum(v2)
  
  # Sums of the squares
  sum1Sq=sum([pow(v,2) for v in v1])
  sum2Sq=sum([pow(v,2) for v in v2])  
  
  # Sum of the products
  pSum=sum([v1[i]*v2[i] for i in range(len(v1))])
  
  # Calculate r (Pearson score)
  num=pSum-(sum1*sum2/len(v1))
  den=sqrt((sum1Sq-pow(sum1,2)/len(v1))*(sum2Sq-pow(sum2,2)/len(v1)))
  if den==0: return 0

  return 1.0-num/den

class bicluster:
  def __init__(self,vec,left=None,right=None,distance=0.0,id=None):
    self.left=left
    self.right=right
    self.vec=vec
    self.id=id
    self.distance=distance

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)

    # 计算两个聚类的平均值
    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)

    # 不在原始集合中的聚类,其id为负数
    currentclustid-=1
    del clust[lowestpair[1]]
    del clust[lowestpair[0]]
    clust.append(newcluster)

  return clust[0]

 

 

第三步;借助树状图,我们可以更加理解聚类

安装PIL,由于我安装了python(x,y),里面已经包含了PIL,因此无需安装。

 

from PIL import Image,ImageDraw,ImageFont
#计算聚类总体的高度
def getheight(clust):
  # Is this an endpoint? Then the height is just 1
  if clust.left==None and clust.right==None: return 1

  # Otherwise the height is the same of the heights of
  # each branch
  return getheight(clust.left)+getheight(clust.right)
#计算误差
def getdepth(clust):
  # The distance of an endpoint is 0.0
  if clust.left==None and clust.right==None: return 0

  #一个枝节点的距离等于左右两侧分支中距离较大者加上该枝节点自身的距离
  return max(getdepth(clust.left),getdepth(clust.right))+clust.distance

#画图
def drawdendrogram(clust,labels,jpeg='clusters.jpg'):
  # height and width
  h=getheight(clust)*30
  w=1200
  depth=getdepth(clust)

  # width is fixed, so scale distances accordingly
  scaling=float(w-350)/depth

  # Create a new image with a white background
  img=Image.new('RGB',(w,h),(255,255,255))
  draw=ImageDraw.Draw(img)

  draw.line((0,h/2,10,h/2),fill=(255,0,0))    

  # Draw the first node
  drawnode(draw,clust,10,(h/2),scaling,labels)
  img.save(jpeg,'JPEG')

def drawnode(draw,clust,x,y,scaling,labels):
  if clust.id<0:
    h1=getheight(clust.left)*20
    h2=getheight(clust.right)*20
    top=y-(h1+h2)/2
    bottom=y+(h1+h2)/2
    # Line length
    ll=clust.distance*scaling
    # Vertical line from this cluster to children    
    draw.line((x,top+h1/2,x,bottom-h2/2),fill=(255,0,0))    
    
    # Horizontal line to left item
    draw.line((x,top+h1/2,x+ll,top+h1/2),fill=(255,0,0))    

    # Horizontal line to right item
    draw.line((x,bottom-h2/2,x+ll,bottom-h2/2),fill=(255,0,0))        

    # Call the function to draw the left and right nodes    
    drawnode(draw,clust.left,x+ll,top+h1/2,scaling,labels)
    drawnode(draw,clust.right,x+ll,bottom-h2/2,scaling,labels)
  else:   
    font = ImageFont.truetype('simsun.ttc',24)
    # If this is an endpoint, draw the item label
    draw.text((x+5,y-7),unicode(labels[clust.id],'utf-8'),(0,0,0),font=font)

 

 

最后我们写个test跑下

 

#encoding=utf-8
import clusters #里面包含了第二,三步的代码
blognames,words,data = clusters.readfile('blogdata1.txt')
clust = clusters.hcluster(data)
clusters.printclust(clust,labels=blognames)
clusters.drawdendrogram(clust,blognames,jpeg='blogclust.jpg')

 

 

生成图片:

 由图可见,我(知知为知知)与特种兵-AK47紧密性最高。 


 

2
4
分享到:
评论

相关推荐

    分级聚类算法

    在这个案例中,我们看到的是使用VC++6.0编程环境实现的分级聚类算法。VC++6.0是微软公司开发的一款经典集成开发环境,主要用于编写Windows平台上的C++程序。虽然目前已有更新版本的Visual Studio,但VC++6.0因其轻量...

    浅析集体智慧的实用性--读《集体智慧编程》有感

    分级聚类算法同样在数据分组和分析中发挥着重要作用。它通过逐步合并最相似的群组,形成层次结构,尤其适合处理复杂的分类问题。尽管它的计算量相对较大,但分级聚类在某些特定场景下的应用仍然具有不可替代的优势。...

    基于云计算与非负矩阵分解的数据分级聚类.pdf

    首先,文档的标题和描述清晰指出了研究的焦点:基于云计算和非负矩阵分解实现了一种新的数据分级聚类算法。这里的“云计算”指的是利用互联网上可扩展的资源进行数据处理的一种计算方式,而“非负矩阵分解”是一种...

    集体智慧编程中文版

    前言 第1章 集体智慧导言 什么是集体智慧 什么是机器学习 机器学习的局限 真实生活中的例子 学习型算法的其他用途 第2章 提供推荐 协作型过滤 搜集偏好 寻找相近的用户 推荐物品 匹配商品 构建一个基于del.icio.us...

    集体智慧编程.[美]西格兰(带详细书签) PDF 下载

    《集体智慧编程》由美国计算机专家西格兰编著,以机器学习与计算统计为主题背景,专门讲述如何挖掘和分析Web上的数据和资源,如何分析用户体验、市场营销、个人品味等诸多信息,并得出有用的结论,通过复杂的算法来...

    统计专题地图分级数据处理模型设计.pdf

    本文提出了一种可扩充的统计专题地图分级数据处理模型,支持七种常用的分级方法,包括分位数分类、最优分割分类、逐步聚类分类等。模型设计不仅包含了确定分级数,还涵盖了确定分级界线的方法,并通过实际案例展示了...

    90.MATLAB编程 神经网络GUI的实现——基于GUI的神经网络拟合、模式识别、聚类.zip

    ### 团队长期从事下列领域算法的研究和改进: ### 1 智能优化算法及应用 **1.1 改进智能优化算法方面(单目标和多目标)** **1.2 生产调度方面** 1.2.1 装配线调度研究 1.2.2 车间调度研究 1.2.3 生产线平衡...

    费希尔算法的Matlab语言实现.pdf

    特别是对于那些具有自然排序的数据集,有序聚类算法尤其有用。费希尔算法作为有序聚类的一种方法,能够处理具有特定顺序的数据,并确保找到最优的分类结果。然而,费希尔算法的计算复杂度较高,特别是在处理大量数据...

    TP-Miner:基于生物启发计算的警用流动人口分析系统 (2006年)

    该系统综合运用了前沿的生物启发计算技术——基于多层染色体基因表达式编程算法、重叠基因表达进化算法、基于概念相似度神经网络分类模型和层次距离计算的聚类算法搭建了一个警用流动人口的分析平台。同时根据实际...

    DTmain.rar_matlab例程_matlab_

    3. **选择聚类算法**:MATLAB内置了多种聚类算法,比如`kmeans`,`linkage`等,根据问题的需求选择合适的算法。 4. **执行聚类**:调用选择的聚类函数,传入预处理后的数据和预设的参数,如聚类数目。 5. **动态...

    数学建模-考虑时空效率的任务匹配定价模型与算法.pdf

    本研究通过综合运用FCM聚类、中心梯度定价、时空效率定价以及多阶段轮盘赌算法等多种数学建模与算法设计方法,有效改善了“拍照赚钱”APP平台的任务定价机制,提高了任务完成率。未来的研究可以进一步探索更复杂的...

    基于MATLAB的水果分级系统适用圆形水果如苹果橘子柚子柿子等统计水果图片的面积圆形度和色泽带设计文档价.zip

    综上所述,这个基于MATLAB的水果分级系统展示了如何结合图像处理技术、特征提取方法和MATLAB编程来解决实际问题,对于学习和研究计算机视觉在农业自动化领域的应用具有一定的参考价值。同时,作为毕业设计项目,它也...

    Spark on Yarn模式的电信大数据处理平台.pdf

    分级聚类算法作为案例被用于分析SY-TPP平台的编程步骤,此算法能够处理大规模数据集,并且能够从海量数据中抽取有用信息,有助于电信运营商更好地理解用户行为,从而为用户提供更加个性化的服务。实验结果表明,该...

    machine-learning-code.zip

    消费者分级可能利用聚类算法,如K-means或DBSCAN,将客户根据消费习惯、购买行为等因素划分到不同群体。学生干预项目可能运用监督学习,如支持向量机或梯度提升机,来预测哪些学生需要额外的关注和支持,以便及时...

    毕业设计matlab做的一个水果分拣系统带有人机交互界面源码.zip

    通过设定阈值或使用聚类算法,系统可以区分不同等级的水果。此外,还可以使用机器学习方法,如支持向量机(SVM)或神经网络,训练模型以识别不同种类或品质的水果。 人机交互界面(GUI)的设计是该项目的另一大亮点...

    2017国赛国家一等奖B题优秀论文4.pdf数学建模

    文章运用 FCM 聚类方法和多阶段轮盘赌算法,解决了不同任务和会员分布条件下的任务定价问题。 首先,文章将平台数据导入 MapInfo Pro15.0 软件,观察得出平台定价以城市中心区为重心,以距离大小向周围辐射梯度递增...

    nmf的matlab代码-hierarchical-nmf-python:分级Rank2nmf的python代码

    通过比较两种语言的实现,还可以深入了解不同编程环境下的算法优化策略和效率差异。 总之,这个项目提供的代码资源可以帮助用户理解和实现层次结构的非负矩阵分解,特别是在Python和MATLAB环境中,这对于数据科学家...

    全球基础信息-矢量数据源码.zip

    源码可能包含地图符号化、颜色分级、标签放置等算法,用于创建美观且信息丰富的地图。 8. 查询与分析:源码可能包含空间查询(如最近邻搜索、缓冲区分析)和空间统计分析(如聚类、密度分析)的实现。 9. 编程语言...

    心脏危险事件问题数学建模

    4. **K-means聚类**:K-means算法被用来对心律失常数据进行聚类,将心律失常情况分为3类,有助于理解数据的内在结构和分布。 5. **模型评估**:通过计算分类模型的性能度量指标,如准确率、召回率、F1分数等,确定...

    主成分回归代码matlab及例子-Machine-learning-fundamentals:在Octave/MATLAB中应用于机器学习的最

    每次编程工作都需要我填写每个算法的核心功能,其余代码属于(安德鲁·伍(Andrew Ng)-Coursera-斯坦福大学(Stanford University))。 已实现了有监督和无监督学习算法的典型示例(请参见摘要)。 每个实施方案均...

Global site tag (gtag.js) - Google Analytics