Python基于Kmeans算法实现文本聚类的简单练习

接触机器学习时间不长,也一直有兴趣研究这方面的算法。最近在学习Kmeans算法,但由于工作的原因无法接触到相关的项目实战。为了理清思路、熟悉代码,在参照了几篇机器学习大神的博文后,做了一个简单的Kmeans算法的简单练习。作为一枚机器学习的门外汉,对于文中的一些错误和不足,还望您多多包涵,也欢迎您的批评和建议(第一次发博客,有点语无伦次,见谅哈)。

先说一下我的大致思路:

1、利用爬虫进行文本数据的爬取。本文爬取了豆瓣电影TOP250榜单内的电影剧情简介作为聚类文本。

2、利用jieba分词对文本进行预处理(文本分词、停用词过滤、语料库的建立等)。

3、利用scikit-learn计算词语的tfidf并建立VSM。

4、利用Kmeans进行文本聚类。

5、结果展示。

话不多说,直接进入正题吧。

一、文本数据的爬取

先上代码:

# -*- coding: utf-8 -*-
import urllib.request
import re
from lxml import etree
urllib.request.urlcleanup()
import urllib.error
import time
'''豆瓣设置了反扒机制,通过设置代理并将爬虫伪装成浏览器,以及在出现错误时设置延时后发现能狗成功'''
def use_proxy(proxy_ip,url):
	try:
		req=urllib.request.Request(url)
		req.add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0')
		proxy=urllib.request.ProxyHandler({'http':proxy_ip})
		opener=urllib.request.build_opener(proxy,urllib.request.HTTPHandler)
		urllib.request.install_opener(opener)
		data=urllib.request.urlopen(req).read().decode('utf-8','ignore')
		return data
	except urllib.error.URLError as e:
		if hasattr(e,'code'):
			print(e.code)
		if hasattr(e,'reason'):
			print(e.reason)
		time.sleep(10) #出现异常延时10s
	except Exception as e:
		print('exception:'+str(e))
		time.sleep(1)
'''爬取榜单上电影的链接'''
for i in range(0,225,25):
    url='https://movie.douban.com/top250?start='+str(i)
    proxy_ip='127.0.0.1:8888'
    data=use_proxy(proxy_ip,url)
    response = etree.HTML(data)
    link = response.xpath('//div[@class="pic"]/a/@href')
    '''在爬取过程中发现豆瓣上有4部电影的链接无法打开,将其剔除'''
        unlink=['https://movie.douban.com/subject/5912992/',
            'https://movie.douban.com/subject/1292000/',
            'https://movie.douban.com/subject/1300299/',
            'https://movie.douban.com/subject/1417598/']
    for j in range(0,len(link)):
        thisurl=link[j]
        if thisurl in unlink:
                continue
        '''爬取剧情简介文本,并写入本地文件'''
        data=use_proxy(proxy_ip,thisurl)
        pat='<span property="v:summary".*?>(.*?)</span>'
        content=re.compile(pat,re.S).findall(data)
        pat1='<title>(.*?)</title>'
        title=re.compile(pat1,re.S).findall(data)
        content_data=content[0].replace('<br />','').strip().replace('\n','').replace(' ','')
        filename='D:/Python_work/Data Mining/db250/'+title[0].strip()+'.txt'
        with open(filename,'w',encoding='utf-8') as fh:
            fh.write(content_data)

爬取结果:


二、文本预处理

文本预处理主要利用jieba分词进行中文分词,根据停用词的语料库进行停用词的过滤以及特殊字符的处理,建立语料库。

本文停用词库的建立参考博文:点击打开链接

代码如下:

# -*- coding: utf-8 -*-
from os import listdir
import jieba
from sklearn import feature_extraction  
from sklearn.feature_extraction.text import TfidfTransformer  
from sklearn.feature_extraction.text import CountVectorizer  
all_file=listdir('D:/Python_work/Data Mining/db250') #获取文件夹中所有文件名
labels=[] #用以存储电影名称
corpus=[] #空语料库
'''停用词的过滤'''
typetxt=open('D:/Python_work/Data Mining/文本相似度计算/停用词.txt') 
texts=['\u3000','\n',' '] #爬取的文本中未处理的特殊字符
'''停用词库的建立'''
for word in typetxt:
    word=word.strip()
    texts.append(word)
'''语料库的建立'''
for i in range(0,len(all_file)):
    filename=all_file[i]
    filelabel=filename.split('.')[0]
    labels.append(filelabel) #电影名称列表
    file_add='D:/Python_work/Data Mining/db250/'+ filename
    doc=open(file_add,encoding='utf-8').read()
    data=jieba.cut(doc) #文本分词
    data_adj=''
    delete_word=[]
    for item in data:
        if item not in texts: #停用词过滤
            data_adj+=item+' '
        else:
            delete_word.append(item)        
    corpus.append(data_adj) #语料库建立完成

结果展示(corpus):

三、计算词语的tfidf值,此部分代码主要参考大神博文:点击打开链接

代码:

vectorizer=CountVectorizer()#该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频  
transformer=TfidfTransformer()#该类会统计每个词语的tf-idf权值
tfidf=transformer.fit_transform(vectorizer.fit_transform(corpus))#第一个fit_transform是计算tf-idf,第二个fit_transform是将文本转为词频矩阵
weight=tfidf.toarray()#将tf-idf矩阵抽取出来,元素a[i][j]表示j词在i类文本中的tf-idf权重 
word=vectorizer.get_feature_names()#获取词袋模型中的所有词

结果展示:

word: weight:


weight为 246×9293矩阵,每一行代表一个文本,列为总次数,每一行对应的值为相关文本词语的TFIDF值

四、Kmeans聚类的实现

from sklearn.cluster import KMeans
mykms=KMeans(n_clusters=10)
y=mykms.fit_predict(weight)
for i in range(0,10):
    label_i=[]
    for j in range(0,len(y)):
        if y[j]==i:
            label_i.append(labels[j])
    print('label_'+str(i)+':'+str(label_i))

结果如下:

五、刚学机器学习不久,此篇文章纯粹是作练习用,结果没有什么价值,此外对于Kmeans部分也只是简单的调用,后续还需要进行更深入的学习。非科班出身,代码也是业余时间的个人爱好,文章中的一些问题也欢迎各位大佬指出,也希望能结识喜欢机器学习的小伙伴,多交流,一起学习,一起成长!

  • 33
    点赞
  • 217
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值