python中文文本切詞Kmeans聚類_第1頁
python中文文本切詞Kmeans聚類_第2頁
python中文文本切詞Kmeans聚類_第3頁
python中文文本切詞Kmeans聚類_第4頁
python中文文本切詞Kmeans聚類_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第python中文文本切詞Kmeans聚類目錄簡介一、切詞二、去除停用詞三、構(gòu)建詞袋空間VSM(vectorspacemodel)四、將單詞出現(xiàn)的次數(shù)轉(zhuǎn)化為權(quán)值(TF-IDF)五、用K-means算法進行聚類六、總結(jié)

簡介

查看百度搜索中文文本聚類我失望的發(fā)現(xiàn),網(wǎng)上竟然沒有一個完整的關(guān)于Python實現(xiàn)的中文文本聚類(乃至搜索關(guān)鍵詞python中文文本聚類也是如此),網(wǎng)上大部分是關(guān)于文本聚類的Kmeans聚類的原理,Java實現(xiàn),R語言實現(xiàn),甚至都有一個C++的實現(xiàn)。

正好我寫的一些文章,我沒能很好的分類,我想能不能通過聚類的方法將一些相似的文章進行聚類,然后我再看每個聚類大概的主題是什么,給每個聚類一個標簽,這樣也是完成了分類。

中文文本聚類主要有一下幾個步驟,下面將分別詳細介紹:

切詞去除停用詞構(gòu)建詞袋空間VSM(vectorspacemodel)TF-IDF構(gòu)建詞權(quán)重使用K-means算法

一、切詞

這里中文切詞使用的是結(jié)巴切詞。github項目主頁上有結(jié)巴切詞的詳細安裝方式,以及示例說明,這里不再詳述,一般情況下,可以使用如下方式安裝。

#pipinstalljieba

或者

#easy_installjieba

二、去除停用詞

結(jié)巴分詞雖然有去除停用詞的功能,但是好像只是給jieba.analyse組建使用的,并不給jieba.cut使用,所以這里我們還是要自己構(gòu)建停用詞文件,以及去除停用詞。常見的中文停用詞有:

1.中文停用詞表(比較全面,有1208個停用詞)

2.最全中文停用詞表整理(1893個)

實現(xiàn)代碼如下(代碼比較水):

defread_from_file(file_name):

withopen(file_name,"r")asfp:

words=fp.read()

returnwords

defstop_words(stop_word_file):

words=read_from_file(stop_word_file)

result=jieba.cut(words)

new_words=[]

forrinresult:

new_words.append(r)

returnset(new_words)

defdel_stop_words(words,stop_words_set):

#words是已經(jīng)切詞但是沒有去除停用詞的文檔。

#返回的會是去除停用詞后的文檔

result=jieba.cut(words)

new_words=[]

forrinresult:

ifrnotinstop_words_set:

new_words.append(r)

returnnew_words

三、構(gòu)建詞袋空間VSM(vectorspacemodel)

接下來是構(gòu)建詞袋空間,我們的步驟如下

將所有文檔讀入到程序中,再將每個文檔切詞。

去除每個文檔中的停用詞。

統(tǒng)計所有文檔的詞集合(sk-learn有相關(guān)函數(shù),但是我知道能對中文也使用)。

對每個文檔,都將構(gòu)建一個向量,向量的值是詞語在本文檔中出現(xiàn)的次數(shù)。

舉個例子,假設(shè)有兩個文本,

1.我愛上海,我愛中國

2.中國偉大,上海漂亮

那么切詞之后就有一下詞語:我,愛,上海,中國,偉大,漂亮,,(逗號也可能被切詞)。

再假設(shè)停用詞是我,,那么去除停用詞后,剩余的詞語就是

愛,上海,中國,偉大,漂亮

然后我們對文檔1和文檔2構(gòu)建向量,那么向量將如下:

文本愛上海中國偉大漂亮

文檔121100

文檔201111

代碼如下:

defget_all_vector(file_path,stop_words_set):

names=[os.path.join(file_path,f)forfinos.listdir(file_path)]

posts=[open(name).read()fornameinnames]

docs=[]

word_set=set()

forpostinposts:

doc=del_stop_words(post,stop_words_set)

docs.append(doc)

word_set|=set(doc)

#printlen(doc),len(word_set)

word_set=list(word_set)

docs_vsm=[]

#forwordinword_set[:30]:

#printword.encode("utf-8"),

fordocindocs:

temp_vector=[]

forwordinword_set:

temp_vector.append(doc.count(word)*1.0)

#printtemp_vector[-30:-1]

docs_vsm.append(temp_vector)

docs_matrix=np.array(docs_vsm)

在python中表示可能如下[[2,1,1,0,0],[0,1,1,1,]],我們盡可能將其放入到numpy的array或者matrix中方便下面TF-IDF的計算。

四、將單詞出現(xiàn)的次數(shù)轉(zhuǎn)化為權(quán)值(TF-IDF)

換句話說,我們的vsm保存的本來已經(jīng)是向量的形式,我們?yōu)槭裁催€需要TF-IDF的形式呢?我認為這就是為了將單詞出現(xiàn)的次數(shù)轉(zhuǎn)化為權(quán)值。

關(guān)于TF-IDF的介紹可以參考網(wǎng)上的文章:

1.基本文本聚類方法

2.TF-IDF百度百科

3.TF-IDF維基百科英文版(需要FQ)

這里需要注意的是關(guān)于TF(termfrequency)的計算,關(guān)于IDF(Inversedocumentfrequency)的計算,我看公式基本上都是一樣的:

逆向文件頻率(inversedocumentfrequency,IDF)是一個詞語普遍重要性的度量。某一特定詞語的IDF,可以由總文件數(shù)目除以包含該詞語之文件的數(shù)目,再將得到的商取對數(shù)得到:本公式用編輯,推薦一個令人驚嘆的網(wǎng)站:Detexify

其中

:語料庫中的文件總數(shù)

:包含詞語的文件數(shù)目(即的文件數(shù)目)如果該詞語不在語料庫中,就會導(dǎo)致分母為零,因此一般情況下使用作為分母。

然而百度百科以及網(wǎng)上大部分關(guān)于TF的介紹其實是有問題的,TF-IDF百度百科中說詞頻(termfrequency,TF)指的是某一個給定的詞語在該文件中出現(xiàn)的頻率,那么很明顯這個計算公式就為:

然而這種計算方式常常會導(dǎo)致TF過小,其實TF-IDF并不是只有一種計算方式,而是多種,這個時候就體現(xiàn)出維基百科的威力了,具體的關(guān)于TF-IDF的介紹還是要參照維基百科。

如果不熟悉numpy,可以參考numpy官方文檔

column_sum=[float(len(np.nonzero(docs_matrix[:,i])[0]))foriinrange(docs_matrix.shape[1])]

column_sum=np.array(column_sum)

column_sum=docs_matrix.shape[0]/column_sum

idf=np.log(column_sum)

idf=np.diag(idf)

#請仔細想想,根絕IDF的定義,計算詞的IDF并不依賴于某個文檔,所以我們提前計算好。

#注意一下計算都是矩陣運算,不是單個變量的運算。

fordoc_vindocs_matrix:

ifdoc_v.sum()==0:

doc_v=doc_v/1

else:

doc_v=doc_v/(doc_v.sum())

tfidf=np.dot(docs_matrix,idf)

returnnames,tfidf

現(xiàn)在我們擁有的矩陣的性質(zhì)如下,

列是所有文檔總共的詞的集合。

每行代表一個文檔。

每行是一個向量,向量的每個值是這個詞的權(quán)值。

五、用K-means算法進行聚類

到這個時候,我們可以使用kmeans算法進行聚類,對kmeans算法來說,它看到已經(jīng)不是文本了,只是矩陣而已,所以我們用的也是通用的kmeans算法就可以了。

關(guān)于kmeans的介紹可以見于如下的文章:

1.基本Kmeans算法介紹及其實現(xiàn)

2.K-means百度百科

3.淺談Kmeans聚類

所不同的是,在大部分的文本聚類中,人們通常用余弦距離(很好的介紹文章)而不是歐氏距離進行計算,難道是因為稀疏矩陣的原因,我并不太明白。

下面的代碼來自《機器學(xué)習實戰(zhàn)》第十章的代碼:

defgen_sim(A,B):

num=float(np.dot(A,B.T))

denum=np.linalg.norm(A)*np.linalg.norm(B)

ifdenum==0:

denum=1

cosn=num/denum

sim=0.5+0.5*cosn

returnsim

defrandCent(dataSet,k):

n=shape(dataSet)[1]

centroids=mat(zeros((k,n)))#createcentroidmat

forjinrange(n):#createrandomclustercenters,withinboundsofeachdimension

minJ=min(dataSet[:,j])

rangeJ=float(max(dataSet[:,j])-minJ)

centroids[:,j]=mat(minJ+rangeJ*random.rand(k,1))

returncentroids

defkMeans(dataSet,k,distMeas=gen_sim,createCent=randCent):

m=shape(dataSet)[0]

clusterAssment=mat(zeros((m,2)))#createmattoassigndatapoints

#toacentroid,alsoholdsSEofeachpoint

centroids=createCent(dataSet,k)

clusterChanged=True

counter=0

whilecounter=50:

counter+=1

clusterChanged=False

foriinrange(m):#foreachdatapointassignittotheclosestcentroid

minDist=inf;

minIndex=-1

forjinrange(k):

distJI=distMeas(centroids[j,:],dataSet[i,:])

ifdistJIminDist:

minDist=distJI;

minIndex=j

ifclusterAssment[i,0]!=minIndex:

clusterChanged=True

clusterAssment[i,:]=minIndex,minDist**2

#printcentroids

forcentinrange(k):#recalculatecentroids

ptsInClust=dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]#getallthepointinthiscluster

centroids[cent,:]=mean(ptsInClust,axis=0)#assigncentroidtomean

returncentroids,clusterAssment

六、總結(jié)

基本上到這里為止,一個可用的中文文本聚類工具已經(jīng)完

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論