本章对上一章中的思想加以扩展,并引入数据聚类的概念,这是一种用以寻找紧密相关的事、人或观点,并将其可视化的方法。
监督学习和无监督学习
监督学习法:利用样本的输入和期望输出来学习如何预测的技术。包括神经网络、决策树、向量支持机,以及贝叶斯过滤。
无监督学习算法不是带有正确答案进行训练,目的是在一组数据中找寻某种结构,而这些数据本身不是我们所需要的答案。聚类算法的目标是采集数据,然后从中找出不同的分组。其他无监督学习的例子还包括非负矩阵因式分解和自组织映射。
单词向量
对博客用户进行分类
在第一个数据集中,被用来聚类的是排名在前120位的一系列博客,为了对博客进行聚类,我们需要的是一组指定的词汇在每个博客订阅源中出现的次数。
根据单词出现的频率对博客进行聚类,或许可以帮助我们分析出是否存在这样一类博客用户,这些人经常撰写相似的主题。
对订阅源中的单词进行计数
RSS订阅源是一个包含博客及其所有文章条目信息的简单的XML文档。为了给每个博客中的单词进行计数,首先第一就是解析这些订阅源。我们利用universal feed parser,从RSS订阅源中得到标题、链接和文章条目了。
下一步,我们编写从订阅源中提取所有单词的函数,新建一个名为generatefeedvector.py的文件,并加入以下代码:
import feedparser
import re
#返回一个含订阅源的标题和包含单词个数情况的字典
def getwordcounts(url):
#解析订阅源
d=feedparser.parse(url)
wc={
}#用来存储在文章中出现的单词和次数
for e in d.entries:
if 'summary' in e: summary=e.summary
else: summary=e.description
#提取一个单词列表
#传入的是XML文件
words=getwords(e.title+''+summary)#摘要
for word in words:
wc.setdefault(word,0)
wc[word]+=1
return d.feed.title,wc
def getwords(html):
#去除所有html标记
txt=re.compile(r'<[^>]+>').sub('',html)
#利用所有非字母字符拆分出单词
words=re.compile(r'[^A-Z^a-z]+').split(txt)
#转化成小写形式
return [word.lower() for word in words if word!='']
为了开始下一步的工作,我们需要一个订阅源列表。我们从此处下载到列表(http://kiwitobes.com/clusters/feedlist.txt)这是一个普通的文本文件,每一行对应一个url。
generatefeedvector.py文件中的主体代码循环遍历 订阅源并生成数据集。
wordcounts={
}#key:文章标题;value:单词以及单词数
apcount={
}#为出现这些单词的博客数目
#feedurl表示遍历该文本文件的每一行,是个url文件
feedlist=[line for line in file('feedlist.txt')]
for feedurl in feedlist:
title,wc=getwordcounts(feedurl)
#每个博客对应的字典
wordcounts[title]=wc
for word,count in wc.items():
apcount.setdefault(word,0)
if count>1: #表示博客中有该单词
apcount[word]+=1
把上述代码添加到generatefeedvector.py文件中。接下来,我们对单词进行筛选,减少要考察的单词的总量。
#只是添加所需要的单词
wordlist=[]
#apcount的key为单词;value为该单词出现的博客数目
for w,bc in apcount.items():
frac=float(bc)/len(feedlist)
if frac>0.1 and frac<0.5: wordlist.append(w)
最后,我们对上述单词列表和博客列表来建立一个文本文件,包含一个大的矩阵,记录针对每个博客的所有单词的统计情况。
out=file('blogdata.txt','w')
out.write('