Python基於Kmeans演算法實現文字聚類的簡單練習
阿新 • • 發佈:2019-01-06
接觸機器學習時間不長,也一直有興趣研究這方面的演算法。最近在學習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()#獲取詞袋模型中的所有詞
結果展示:
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部分也只是簡單的呼叫,後續還需要進行更深入的學習。非科班出身,程式碼也是業餘時間的個人愛好,文章中的一些問題也歡迎各位大佬指出,也希望能結識喜歡機器學習的小夥伴,多交流,一起學習,一起成長!