聚类原理
聚类是非监督学习里面最经典的算法了。其主要应用于市场营销的客户分层。聚类不仅很有效,而且其算法原理异常的简单。所谓聚类就是把各个属性最接近的那些样本点归为一类。而判断最近的方法一般和推荐算法的相似性一样,要么用距离法要么要相关系数法。
层次聚类
层次聚类是聚类算法的一种,其特点是不对聚类数目做任何假设。首先先找到所有样本点中最相近的两个点作为一类,并以这两个点的中心作为新的样本点的位置此时全样本n只剩下n-1类,再重新计算最近的两类再合并成一个新的类。如此迭代直到最后只剩下一个类。
具体代码和流程
这里主要对文章进行聚类,找到具有相似风格的文章。具体步骤为:
- 把文章分词,计算每个词的频次
- 然后把那些只在极个别的文章出现或者在每篇文章都出现的单词去掉,只留下一部分词。
- 以单词为变量,文章为行标整理出数据框的格式。
- 用层次聚类的算法进行聚类
数据准备
先定义一个简单爬虫,获取每篇文章所在的urls
def getUrls(start_Url):
html = requests.get(start_Url)
selector = etree.HTML(html.text)
article={}
content_field = selector.xpath('//*[@id="container"]/div[3]/div[1]/div[1]/div')
for each in content_field:
url=each.xpath('div/div[2]/h1/a/@href')
title=each.xpath('div/div[2]/h1/a/text()')
if title:
article[title[0]]=url[0]
return article
然后获取文章,再进行分词统计每篇文章单词的频次
def wordsCounts(url):
html=requests.get(url)
wordcounts={}
wordlist=getWordList(html.text)
for word in wordlist:
wordcounts.setdefault(word,0)
wordcounts[word]+=1
return wordcounts
def getWordList(html):
pattern1=re.compile(r'<[^>]+>')
text=pattern1.sub('',html)
pattern2=re.compile(r'[^A-Z^a-z]+')
words=pattern2.split(text)
return [word.lower() for word in words if word!='']
挑选一部分整体出现频次不多不少的单词
def select_words(datasets):
word_in_art={}
wordlist=[]
for title in datasets:
for word,count in datasets[title].items():
if count>1:
word_in_art.setdefault(word,0)
word_in_art[word]+=1
for word in word_in_art:
fac=word_in_art[word]/len(datasets)
if fac>0.1 and fac<0.5:
wordlist.append(word)
return wordlist
然后把数据写入一个txt文件,以备经常调用
def write_datas(wordlist,datasets,subject):
out=file("economy articles.txt",'w')
out.write(subject)
for wd in wordlist:
out.write("\t%s" %wd)
out.write('\n')
for title,wc in datasets.items():
char=''
for i in title.split():
char+=i[0].upper()
out.write(char)
for word in wordlist:
if word in wc:
out.write('\t%d' %wc[word])
else:out.write('\t0')
out.write('\n')