接触机器学习时间不长,也一直有兴趣研究这方面的算法。最近在学习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='(.*?)'
content=re.compile(pat,re.S).findall(data)
pat1='(.*?) '
title=re.compile(pat1,re.S).findall(data)
content_data=content[0].replace('
','').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()#获取词袋模型中的所有词
结果展示:
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部分也只是简单的调用,后续还需要进行更深入的学习。非科班出身,代码也是业余时间的个人爱好,文章中的一些问题也欢迎各位大佬指出,也希望能结识喜欢机器学习的小伙伴,多交流,一起学习,一起成长!