【python資料探勘課程】二十四.KMeans文字聚類分析互動百科語料
這是《Python資料探勘課程》系列文章,也是我上課內容及書籍中的一個案例。本文主要講述文字聚類相關知識,包括中文分詞、資料清洗、特徵提取、TF-IDF、KMeans聚類等步驟。
本篇文章為基礎性文章,希望對你有所幫助,提供些思路,也是自己教學的內容。如果文章中存在錯誤或不足之處,還請海涵。同時,推薦大家閱讀我以前的文章瞭解其他知識。
前文參考:
【Python資料探勘課程】一.安裝Python及爬蟲入門介紹
【Python資料探勘課程】二.Kmeans聚類資料分析及Anaconda介紹
【Python資料探勘課程】三.Kmeans聚類程式碼實現、作業及優化
【Python資料探勘課程】四.決策樹DTC資料分析及鳶尾資料集分析
【Python資料探勘課程】五.線性迴歸知識及預測糖尿病例項
【Python資料探勘課程】六.Numpy、Pandas和Matplotlib包基礎知識
【Python資料探勘課程】七.PCA降維操作及subplot子圖繪製
【Python資料探勘課程】八.關聯規則挖掘及Apriori實現購物推薦
【Python資料探勘課程】九.迴歸模型LinearRegression簡單分析氧化物資料
【python資料探勘課程】十.Pandas、Matplotlib、PCA繪圖實用程式碼補充
【python資料探勘課程】十一.Pandas、Matplotlib結合SQL語句視覺化分析
【python資料探勘課程】十二.Pandas、Matplotlib結合SQL語句對比圖分析
【python資料探勘課程】十三.WordCloud詞雲配置過程及詞頻分析
【python資料探勘課程】十四.Scipy呼叫curve_fit實現曲線擬合
【python資料探勘課程】十五.Matplotlib呼叫imshow()函式繪製熱圖
【python資料探勘課程】十六.邏輯迴歸LogisticRegression分析鳶尾花資料
【python資料探勘課程】十七.社交網路Networkx庫分析人物關係(初識篇)
【python資料探勘課程】十八.線性迴歸及多項式迴歸分析四個案例分享
【python資料探勘課程】十九.鳶尾花資料集視覺化、線性迴歸、決策樹花樣分析
【python資料探勘課程】二十.KNN最近鄰分類演算法分析詳解及平衡秤TXT資料集讀取
【python資料探勘課程】二十一.樸素貝葉斯分類器詳解及中文文字輿情分析
【python資料探勘課程】二十二.Basemap地圖包安裝入門及基礎知識講解
【python資料探勘課程】二十三.時間序列金融資料預測及Pandas庫詳解
這篇文章程式碼和實驗分析為主,不進行詳細講解,詳見:
[python] 基於k-means和tfidf的文字聚類程式碼簡單實現
[python] Kmeans文字聚類演算法+PAC降維+Matplotlib顯示聚類影象
PSS:最近參加CSDN2018年部落格評選,希望您能投出寶貴的一票。我是59號,Eastmount,楊秀璋。投票地址:https://bss.csdn.net/m/topic/blog_star2018/index
五年來寫了314篇部落格,12個專欄,是真的熱愛分享,熱愛CSDN這個平臺,也想幫助更多的人,專欄包括Python、資料探勘、網路爬蟲、影象處理、C#、Android等。現在也當了兩年老師,更是覺得有義務教好每一個學生,讓貴州學子好好寫點程式碼,學點技術,"師者,傳到授業解惑也",提前祝大家新年快樂。2019我們攜手共進,為愛而生。
一. Python文字抓取
爬蟲主要通過Python+Selenium+Phantomjs實現,爬取互動百科旅遊景點資訊,其中爬取百度百科程式碼如下。
參考前文:[Python爬蟲] Selenium獲取百度百科旅遊景點的InfoBox訊息盒
爬取的資料集如下圖所示,互動百科的每類主題各100篇網頁文字,涉及人物明星、旅遊景區、動物、世界國家四個主題。執行結果如下圖所示:
實現原理:
我們首先分析互動百科搜尋詞條的一些規則,比如搜尋人物“貴州”,對應的超鏈為“http://www.baike.com/wiki/貴州”,對應頁面如圖9.16所示,從圖中可以看到,頂部的超連結URL、詞條為“貴州”、第一段為“貴州”的摘要資訊、“右邊為對應的圖片等資訊。
同理,搜尋程式語言“Python”,對應的超連結為“http://www.baike.com/wiki/Python”,可以得出一個簡單的規則,即“http://www.baike.com/wiki/詞條”可以搜尋對應的知識,如程式語言“Java”對應的“http://www.baike.com/wiki/Java&prd=button_doc_entry”,這裡定義了搜尋方式,它是通過點選按鈕“進入詞條”進行搜尋的,省略“prd=button_doc_entry”引數同樣可以得到相同的結果。
然後,需要分佈獲取這十門語言的摘要資訊。在瀏覽器中選中摘要部分,右鍵滑鼠點選“審查元素”返回結果如圖9.18所示,可以在底部看到摘要部分對應的HTML原始碼。
"Python" 詞條摘要部分對應的HTML核心程式碼如下所示:
<div class="summary" name="anchor" id="anchor">
<p>Python(英語發音:/ˈpaɪθən/),是一種物件導向、解釋型計算機程式設計語言,由Guido van Rossum於1989年發明...</p>
<span><a action="editsummaryhref" href="javascript:void(0);"
onclick="editSummary();return false;">
編輯摘要
</a></span>
</div>
呼叫Selenium的find_element_by_xpath("//summary[@class='summary']/p")函式,可以獲取摘要段落資訊,核心程式碼如下。
driver = webdriver.Firefox()
url = "http://www.baike.com/wiki/" + name
driver.get(url)
elem = driver.find_element_by_xpath("//div[@class='summary']/p")
print elem.text
這段程式碼的基本步驟是:
1.首先呼叫webdriver.Firefox()驅動,開啟火狐瀏覽器。
2.分析網頁超連結,並呼叫driver.get(url)函式訪問。
3.分析網頁DOM樹結構,呼叫driver.find_element_by_xpath()進行分析。
4.輸出結果,部分網站的內容需要儲存至本地,並且需要過濾掉不需要的內容等。
下面是完整的程式碼及詳細講解,參考自己的書籍《Python網路資料爬取及分析從入門到精通(爬取篇)》。
# coding=utf-8
# test09_03.py
import os
import codecs
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
#獲取摘要資訊
def getAbstract(name):
try:
#新建資料夾及檔案
basePathDirectory = "Hudong_Coding"
if not os.path.exists(basePathDirectory):
os.makedirs(basePathDirectory)
baiduFile = os.path.join(basePathDirectory,"HudongSpider.txt")
#檔案不存在新建,存在則追加寫入
if not os.path.exists(baiduFile):
info = codecs.open(baiduFile,'w','utf-8')
else:
info = codecs.open(baiduFile,'a','utf-8')
url = "http://www.baike.com/wiki/" + name
print url
driver.get(url)
elem = driver.find_element_by_xpath("//div[@class='summary']/p")
print elem.text
info.writelines(elem.text+'\r\n')
except Exception,e:
print "Error: ",e
finally:
print '\n'
info.write('\r\n')
#主函式
def main():
languages = ["JavaScript", "Java", "Python", "Ruby", "PHP",
"C++", "CSS", "C#", "C", "GO"]
print u'開始爬取'
for lg in languages:
print lg
getAbstract(lg)
print u'結束爬取'
if __name__ == '__main__':
main()
輸出如下圖所示,將資料集 換成對應的景區即可。
二. 資料預處理
由於爬取的資料集都是分佈於四個主題資料夾中,每個檔案中共100個,所以需要將這四個主題的文字合併成一個txt檔案,其程式碼如下:
# coding=utf-8
import re
import os
import sys
import codecs
import shutil
def merge_file():
path = "BaiduSpiderSpots\\"
resName = "BaiduSpider_Result.txt"
if os.path.exists(resName):
os.remove(resName)
result = codecs.open(resName, 'w', 'utf-8')
num = 1
while num <= 100:
name = "%04d" % num
fileName = path + str(name) + ".txt"
source = open(fileName, 'r')
line = source.readline()
line = line.strip('\n')
line = line.strip('\r')
while line!="":
line = unicode(line, "utf-8")
line = line.replace('\n',' ')
line = line.replace('\r',' ')
result.write(line+ ' ')
line = source.readline()
else:
print 'End file: ' + str(num)
result.write('\r\n')
source.close()
num = num + 1
else:
print 'End All'
result.close()
if __name__ == '__main__':
merge_file()
合併後的結果如下圖所示,生成的HudongSpider_Result.txt共400個,1-100為動物、101-200為景區、201-300位人物、301-400為國家,每一行表示所爬取的一個網頁文字。
三. 中文分詞
中文分詞主要使用的是Python+Jieba分詞工具,程式碼如下:
#encoding=utf-8
import sys
import re
import codecs
import os
import shutil
import jieba
import jieba.analyse
#匯入自定義詞典
#jieba.load_userdict("dict_baidu.txt")
#Read file and cut
def read_file_cut():
fileName = "HudongSpider_Result.txt"
source = open(fileName, 'r')
resName = "Stop_HudongSpider_Result.txt"
result = codecs.open(resName, 'w', 'utf-8')
line = source.readline()
while line!="":
line = unicode(line, "utf-8")
seglist = jieba.cut(line,cut_all=False) #精確模式
output = ' '.join(list(seglist)) #空格拼接
#print output
result.write(output)
line = source.readline()
else:
source.close()
result.close()
print 'End All'
#Run function
if __name__ == '__main__':
read_file_cut()sc
輸出結果如下圖所示,採用空格連線,同時可以匯入詞典進行分詞。分詞之後,也可以進行停用詞過濾、特殊符號去除等資料清洗,這裡不再介紹,詳見前文。
四. KMeans聚類分析
需要將文件相似度問題轉換為數學向量矩陣問題,可以通過向量空間模型來儲存每個文件的詞頻和權重,特徵抽取完後,因為每個詞語對實體的貢獻度不同,所以需要對這些詞語賦予不同的權重。計算詞項在向量中的權重方法——TF-IDF。
相關介紹:
它表示TF(詞頻)和IDF(倒文件頻率)的乘積:
其中TF表示某個關鍵詞出現的頻率,IDF為所有文件的數目除以包含該詞語的文件數目的對數值。
|D|表示所有文件的數目,|w∈d|表示包含詞語w的文件數目。
最後TF-IDF計算權重越大表示該詞條對這個文字的重要性越大,它的目的是去除一些"的、了、等"出現頻率較高的常用詞。
參考前文:Python簡單實現基於VSM的餘弦相似度計算
基於VSM的命名實體識別、歧義消解和指代消解
下面是使用scikit-learn工具呼叫CountVectorizer()和TfidfTransformer()函式計算TF-IDF值,同時呼叫sklearn.cluster中的KMeans演算法進行文字聚類。
完整程式碼:
# coding=utf-8
import time
import re
import os
import sys
import codecs
import shutil
import numpy as np
import matplotlib
import scipy
import matplotlib.pyplot as plt
from sklearn import feature_extraction
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import HashingVectorizer
if __name__ == "__main__":
#########################################################################
# 第一步 計算TFIDF
#文件預料 空格連線
corpus = []
#讀取預料 一行預料為一個文件
for line in open('Stop_HudongSpider_Result.txt', 'r').readlines():
#print line
corpus.append(line.strip())
#print corpus
#參考: http://blog.csdn.net/abcjennifer/article/details/23615947
#vectorizer = HashingVectorizer(n_features = 4000)
#將文字中的詞語轉換為詞頻矩陣 矩陣元素a[i][j] 表示j詞在i類文字下的詞頻
vectorizer = CountVectorizer()
#該類會統計每個詞語的tf-idf權值
transformer = TfidfTransformer()
#第一個fit_transform是計算tf-idf 第二個fit_transform是將文字轉為詞頻矩陣
tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))
#獲取詞袋模型中的所有詞語
word = vectorizer.get_feature_names()
#將tf-idf矩陣抽取出來,元素w[i][j]表示j詞在i類文字中的tf-idf權重
weight = tfidf.toarray()
#列印特徵向量文字內容
print 'Features length: ' + str(len(word))
resName = "BHTfidf_Result.txt"
result = codecs.open(resName, 'w', 'utf-8')
for j in range(len(word)):
result.write(word[j] + ' ')
result.write('\r\n\r\n')
#列印每類文字的tf-idf詞語權重,第一個for遍歷所有文字,第二個for便利某一類文字下的詞語權重
for i in range(len(weight)):
#print u"-------這裡輸出第", i, u"類文字的詞語tf-idf權重------"
for j in range(len(word)):
#print weight[i][j],
result.write(str(weight[i][j]) + ' ')
result.write('\r\n\r\n')
result.close()
########################################################################
# 第二步 聚類Kmeans
print 'Start Kmeans:'
from sklearn.cluster import KMeans
clf = KMeans(n_clusters=4) #景區 動物 人物 國家
s = clf.fit(weight)
print s
'''
print 'Start MiniBatchKmeans:'
from sklearn.cluster import MiniBatchKMeans
clf = MiniBatchKMeans(n_clusters=20)
s = clf.fit(weight)
print s
'''
#中心點
print(clf.cluster_centers_)
#每個樣本所屬的簇
label = [] #儲存400個類標
print(clf.labels_)
i = 1
while i <= len(clf.labels_):
print clf.labels_[i-1]
label.append(clf.labels_[i-1])
i = i + 1
#用來評估簇的個數是否合適,距離越小說明簇分的越好,選取臨界點的簇個數 958.137281791
print(clf.inertia_)
y_pred = clf.labels_
########################################################################
# 第三步 圖形輸出 降維
from sklearn.decomposition import PCA
pca = PCA(n_components=2) #輸出兩維
newData = pca.fit_transform(weight) #載入N維
print newData
x = [n[0] for n in newData]
y = [n[1] for n in newData]
x1, y1 = [], []
x2, y2 = [], []
x3, y3 = [], []
x4, y4 = [], []
#分佈獲取類標為0、1、2、3的資料 賦值給(x1,y1) (x2,y2) (x3,y3) (x4,y4)
i = 0
while i < len(newData):
if y_pred[i]==0:
x1.append(newData[i][0])
y1.append(newData[i][1])
elif y_pred[i]==1:
x2.append(newData[i][0])
y2.append(newData[i][1])
elif y_pred[i]==2:
x3.append(newData[i][0])
y3.append(newData[i][1])
elif y_pred[i]==3:
x4.append(newData[i][0])
y4.append(newData[i][1])
i = i + 1
#四種顏色 紅 綠 藍,marker='x'表示型別,o表示圓點 *表示星型 x表示點
plot1, = plt.plot(x1, y1, 'or', marker="o", markersize=10)
plot2, = plt.plot(x2, y2, 'og', marker="o", markersize=10)
plot3, = plt.plot(x3, y3, 'ob', marker="o", markersize=10)
plot4, = plt.plot(x4, y4, 'oy', marker="o", markersize=10)
#plt.title("K-Means Text Clustering") #繪製標題
plt.legend((plot1, plot2, plot3, plot4), ('A', 'B', 'C', 'D'), fontsize=10)
#四種顏色 紅 綠 藍 黑
#plt.scatter(x1, x2, c=clf.labels_, s=100)
plt.show()
輸出結果如下所示,將400個網頁文字聚整合4類(類標0~3),每一類表示人物、景區、國家、動物。
[3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 0 2 2 2 2 2 2 2 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 2 2 2 0 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
同時繪製相關圖形如下所示,注意散點圖類標的繪製。
五. 結果評價
這裡我想結合文字聚類簡單敘述下最常用的評估方法:
正確率 Precision = 正確識別的個體總數 / 識別出的個體總數
召回率 Recall = 正確識別的個體總數 / 測試集中存在的個體總數
F值 F-measure = 正確率 * 召回率 * 2 / (正確率 + 召回率)
由於"clf.labels_"會返回聚類每個樣本所屬的簇,比如400行資料,就會返回400個label值。同時,clf = KMeans(n_clusters=4)設定了類簇為4,故每個值對應在0、1、2、3中的一個,統計結果如下:
動物:99識別正確、共識別100個
國家:97識別正確、共識別97個
人物:98識別正確、共識別98個
景區:99識別正確、共識別105個
其中以景區為例,識別出的label3數目為105,同時正確識別出的個體數=99,總共測試樣本共100個,故:
準確率=99/105=0.9429
召回率=99/100=0.9900
F值=(2*0.9429*0.9900)/(0.9429+0.9900)=0.9659
最終輸出結果如下所示:
同時可以計算巨集平均聚類準確率(Macro-Prec)和巨集平均召回率(Macro-Rec)。
希望基礎性文章對您有所幫助,如果文章中有錯誤或不足之處還請海涵。
最後推薦作者的最新出版書籍:
本書主要包括上下兩冊:
《Python網路資料爬取及分析從入門到精通(爬取篇)》
《Python網路資料爬取及分析從入門到精通(分析篇)》
(By:Eastmount 2018-07-06 深夜8點 http://blog.csdn.net/eastmount/ )
相關文章
- kmeans實現文字聚類聚類
- 資料探勘-層次聚類聚類
- 資料探勘之 層次聚類聚類
- 【python資料探勘課程】二十七.基於SVM分類器的紅酒資料分析Python
- 【python資料探勘課程】二十五.Matplotlib繪製帶主題及聚類類標的散點圖Python聚類
- 【python資料探勘課程】十六.邏輯迴歸LogisticRegression分析鳶尾花資料Python邏輯迴歸
- 【python資料探勘課程】十一.Pandas、Matplotlib結合SQL語句視覺化分析PythonSQL視覺化
- 【python資料探勘課程】十二.Pandas、Matplotlib結合SQL語句對比圖分析PythonSQL
- 【python資料探勘課程】十三.WordCloud詞雲配置過程及詞頻分析PythonCloud
- 【python資料探勘課程】二十一.樸素貝葉斯分類器詳解及中文文字輿情分析Python
- Python資料探勘與分析速成班-CSDN公開課-專題視訊課程Python
- 【Python資料探勘課程】九.迴歸模型LinearRegression簡單分析氧化物資料Python模型
- 資料處理 聚類分析聚類
- mahout之聚類演算法——KMeans分析聚類演算法
- 【python資料探勘課程】二十.KNN最近鄰分類演算法分析詳解及平衡秤TXT資料集讀取PythonKNN演算法
- 《資料分析與資料探勘》--天津大學公開課
- 【python資料探勘課程】二十六.基於SnowNLP的豆瓣評論情感分析Python
- 萌新向Python資料分析及資料探勘 前言Python
- 【python資料探勘課程】十七.社交網路Networkx庫分析人物關係(初識篇)Python
- 重磅 | 資料探勘之父韓家煒:文字語料庫的資料探勘(附視訊+PPT下載)
- Python資料分析之糗事百科Python
- 【python資料探勘課程】十九.鳶尾花資料集視覺化、線性迴歸、決策樹花樣分析Python視覺化
- 資料探勘方向分析
- 資料探勘的資料分析方法
- 資料探勘聚類之k-medoids演算法實現聚類演算法
- 【Python資料探勘課程】六.Numpy、Pandas和Matplotlib包基礎知識Python
- 【python資料探勘課程】十五.Matplotlib呼叫imshow()函式繪製熱圖Python函式
- 【Python資料探勘課程】七.PCA降維操作及subplot子圖繪製PythonPCA
- 【python資料探勘課程】十八.線性迴歸及多項式迴歸分析四個案例分享Python
- Kmeans如何初始化聚類中心聚類
- 【python資料探勘課程】十四.Scipy呼叫curve_fit實現曲線擬合Python
- Python有哪些資料探勘工具?五大類Python
- 資料探勘之KMeans演算法應用與簡單理解演算法
- 大資料、資料分析、資料探勘的差別大資料
- 【python資料探勘課程】二十三.時間序列金融資料預測及Pandas庫詳解Python
- 102、聚類Kmeans演算法聚類演算法
- 呼叫WEKA包進行kmeans聚類(java)聚類Java
- 資料分析與挖掘 - R語言:K-means聚類演算法R語言聚類演算法