欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python實現(xiàn)中文文本關(guān)鍵詞抽取的三種方法

 更新時間:2024年01月24日 09:50:58   作者:南七澄江  
文本關(guān)鍵詞抽取,是對文本信息進(jìn)行高度凝練的一種有效手段,通過3-5個詞語準(zhǔn)確概括文本的主題,幫助讀者快速理解文本信息,本文分別采用TF-IDF方法、TextRank方法和Word2Vec詞聚類方法,利用Python語言進(jìn)行開發(fā),實現(xiàn)文本關(guān)鍵詞的抽取,需要的朋友可以參考下

文本關(guān)鍵詞抽取,是對文本信息進(jìn)行高度凝練的一種有效手段,通過3-5個詞語準(zhǔn)確概括文本的主題,幫助讀者快速理解文本信息。目前,用于文本關(guān)鍵詞提取的主要方法有四種:基于TF-IDF的關(guān)鍵詞抽取、基于TextRank的關(guān)鍵詞抽取、基于Word2Vec詞聚類的關(guān)鍵詞抽取,以及多種算法相融合的關(guān)鍵詞抽取。筆者在使用前三種算法進(jìn)行關(guān)鍵詞抽取的學(xué)習(xí)過程中,發(fā)現(xiàn)采用TF-IDF和TextRank方法進(jìn)行關(guān)鍵詞抽取在網(wǎng)上有很多的例子,代碼和步驟也比較簡單,但是采用Word2Vec詞聚類方法時網(wǎng)上的資料并未把過程和步驟表達(dá)的很清晰。因此,本文分別采用TF-IDF方法、TextRank方法和Word2Vec詞聚類方法實現(xiàn)對專利文本(同樣適用于其它類型文本)的關(guān)鍵詞抽取,通過理論與實踐相結(jié)合的方式,一步步了解、學(xué)習(xí)、實現(xiàn)中文文本關(guān)鍵詞抽取。

1 概述

一篇文檔的關(guān)鍵詞等同于最能表達(dá)文檔主旨的N個詞語,即對于文檔來說最重要的詞,因此,可以將文本關(guān)鍵詞抽取問題轉(zhuǎn)化為詞語重要性排序問題,選取排名前TopN個詞語作為文本關(guān)鍵詞。目前,主流的文本關(guān)鍵詞抽取方法主要有以下兩大類:

(1)基于統(tǒng)計的關(guān)鍵詞提取方法

該方法根據(jù)統(tǒng)計信息,如詞頻,來計算得到文檔中詞語的權(quán)重,按權(quán)重值排序提取關(guān)鍵詞。TF-IDF和TextRank均屬于此類方法,其中TF-IDF方法通過計算單文本詞頻(Term Frequency, TF)和逆文本頻率指數(shù)(Inverse Document Frequency, IDF)得到詞語權(quán)重;TextRank方法基于PageRank的思想,通過詞語共現(xiàn)窗口構(gòu)建共現(xiàn)網(wǎng)絡(luò),計算詞語得分。此類方法簡單易行,適用性較強(qiáng),然而未考慮詞序問題。

(2)基于機(jī)器學(xué)習(xí)的關(guān)鍵詞提取方法

該方法包括了SVM、樸素貝葉斯等有監(jiān)督學(xué)習(xí)方法,以及K-means、層次聚類等無監(jiān)督學(xué)習(xí)方法。在此類方法中,模型的好壞取決于特征提取,而深度學(xué)習(xí)正是特征提取的一種有效方式。由Google推出的Word2Vec詞向量模型,是自然語言領(lǐng)域中具有代表性的學(xué)習(xí)工具。它在訓(xùn)練語言模型的過程中將詞典映射到一個更抽象的向量空間中,每一個詞語通過高維向量表示,該向量空間中兩點之間的距離就對應(yīng)兩個詞語的相似程度。

基于以上研究,本文分別采用TF-IDF方法、TextRank方法和Word2Vec詞聚類方法,利用Python語言進(jìn)行開發(fā),實現(xiàn)文本關(guān)鍵詞的抽取。

2 開發(fā)環(huán)境準(zhǔn)備

2.1 Python環(huán)境

筆者使用的是anaconda環(huán)境下的Python 3.10.13。

2.2 第三方模塊

本實驗實現(xiàn)使用的主要模塊如下所示:

(1)Jieba

目前使用最為廣泛的中文分詞組件。

(2)Gensim

用于主題模型、文檔索引和大型語料相似度索引的python庫,主要用于自然語言處理(NLP)和信息檢索(IR)。 本實例中的維基中文語料處理和中文詞向量模型構(gòu)建需要用到該模塊。

(3)Pandas

用于高效處理大型數(shù)據(jù)集、執(zhí)行數(shù)據(jù)分析任務(wù)的python庫,是基于Numpy的工具包。安裝方法:pip install pandas。

(4)Numpy

用于存儲和處理大型矩陣的工具包。

(5)Scikit-learn

用于機(jī)器學(xué)習(xí)的python工具包,python模塊引用名字為sklearn,安裝前還需要Numpy和Scipy兩個Python庫。本實例中主要用到了該模塊中的feature_extraction、KMeans(k-means聚類算法)和PCA(pac降維算法)。

(6)Matplotlib

Matplotlib是一個python的圖形框架,用于繪制二維圖形。

3 數(shù)據(jù)準(zhǔn)備

3.1 樣本語料

文本將汽車行業(yè)的10篇專利作為樣本數(shù)據(jù)集,見文件“data/sample_data.csv”。文件中依順序包含編號(id)、標(biāo)題(title)和摘要(abstract)三個字段,其中標(biāo)題和摘要都要參與到關(guān)鍵詞的抽取。各位可根據(jù)自己的樣本數(shù)據(jù)進(jìn)行數(shù)據(jù)讀取相關(guān)代碼的調(diào)整。

3.2 停用詞詞典

本文使用中科院計算所中文自然語言處理開放平臺發(fā)布的中文停用詞表,包含了1208個停用詞。下載地址:http://www.hicode.cc/download/view-software-13784.html

另外,由于本實例的樣本是專利文本,詞匯專業(yè)性較高,需要人工新增停用詞,可直接在上述停用詞表中添加,一行為一個停用詞,見文件“data/stopWord.txt”。在本例中,筆者在文件最前面人工新增了“包括、相對、免受、用于、本發(fā)明、結(jié)合”這六個停用詞,用于示范,各位可根據(jù)實際情況自行刪減或新增停用詞。

4 基于TF-IDF的文本關(guān)鍵詞抽取方法

4.1 TF-IDF算法思想

詞頻(Term Frequency,TF)指某一給定詞語在當(dāng)前文件中出現(xiàn)的頻率。由于同一個詞語在長文件中可能比短文件有更高的詞頻,因此根據(jù)文件的長度,需要對給定詞語進(jìn)行歸一化,即用給定詞語的次數(shù)除以當(dāng)前文件的總詞數(shù)。

逆向文件頻率(Inverse Document Frequency,IDF)是一個詞語普遍重要性的度量。即如果一個詞語只在很少的文件中出現(xiàn),表示更能代表文件的主旨,它的權(quán)重也就越大;如果一個詞在大量文件中都出現(xiàn),表示不清楚代表什么內(nèi)容,它的權(quán)重就應(yīng)該小。

TF-IDF的主要思想是,如果某個詞語在一篇文章中出現(xiàn)的頻率高,并且在其他文章中較少出現(xiàn),則認(rèn)為該詞語能較好的代表當(dāng)前文章的含義。即一個詞語的重要性與它在文檔中出現(xiàn)的次數(shù)成正比,與它在語料庫中文檔出現(xiàn)的頻率成反比。

計算公式如下:

在這里插入圖片描述

4.2 TF-IDF文本關(guān)鍵詞抽取方法流程

由以上可知,TF-IDF是對文本所有候選關(guān)鍵詞進(jìn)行加權(quán)處理,根據(jù)權(quán)值對關(guān)鍵詞進(jìn)行排序。假設(shè)Dn為測試語料的大小,該算法的關(guān)鍵詞抽取步驟如下所示:

(1) 對于給定的文本D進(jìn)行分詞、詞性標(biāo)注和去除停用詞等數(shù)據(jù)預(yù)處理操作。本文采用jieba分詞,保留’n’,‘nz’,‘v’,‘vd’,‘vn’,‘l’,‘a’,'d’這幾個詞性的詞語(‘n’: 名詞,‘nz’: 其他專有名詞,‘v’: 動詞,‘vd’: 副動詞,‘vn’: 名動詞,‘l’: 習(xí)用語,‘a’: 形容詞,‘d’: 副詞),最終得到n個候選關(guān)鍵詞,即D=[t1,t2,…,tn] ;

(2) 計算詞語ti 在文本D中的詞頻;

(3) 計算詞語ti 在整個語料的IDF=log (Dn /(Dt +1)),Dt 為語料庫中詞語ti 出現(xiàn)的文檔個數(shù);

(4) 計算得到詞語ti 的TF-IDF=TF*IDF,并重復(fù)(2)—(4)得到所有候選關(guān)鍵詞的TF-IDF數(shù)值;

(5) 對候選關(guān)鍵詞計算結(jié)果進(jìn)行倒序排列,得到排名前TopN個詞匯作為文本關(guān)鍵詞。

4.3 代碼實現(xiàn)

Python第三方工具包Scikit-learn提供了TFIDF算法的相關(guān)函數(shù),本文主要用到了sklearn.feature_extraction.text下的TfidfTransformer和CountVectorizer函數(shù)。其中,CountVectorizer函數(shù)用來構(gòu)建語料庫的中的詞頻矩陣,TfidfTransformer函數(shù)用來計算詞語的tfidf權(quán)值。

注:TfidfTransformer()函數(shù)有一個參數(shù)smooth_idf,默認(rèn)值是True,若設(shè)置為False,則IDF的計算公式為idf=log(Dn /Dt ) + 1。

基于TF-IDF方法實現(xiàn)文本關(guān)鍵詞抽取的代碼執(zhí)行步驟如下:

(1)讀取樣本源文件sample_data.csv;

(2)獲取每行記錄的標(biāo)題和摘要字段,并拼接這兩個字段;

(3)加載自定義停用詞表stopWord.txt,并對拼接的文本進(jìn)行數(shù)據(jù)預(yù)處理操作,包括分詞、篩選出符合詞性的詞語、去停用詞,用空格分隔拼接成文本;

(4)遍歷文本記錄,將預(yù)處理完成的文本放入文檔集corpus中;

(5)使用CountVectorizer()函數(shù)得到詞頻矩陣,a[j][i]表示第j個詞在第i篇文檔中的詞頻;

(6)使用TfidfTransformer()函數(shù)計算每個詞的tf-idf權(quán)值;

(7)得到詞袋模型中的關(guān)鍵詞以及對應(yīng)的tf-idf矩陣;

(8)遍歷tf-idf矩陣,打印每篇文檔的詞匯以及對應(yīng)的權(quán)重;

(9)對每篇文檔,按照詞語權(quán)重值降序排列,選取排名前topN個詞最為文本關(guān)鍵詞,并寫入數(shù)據(jù)框中;

(10)將最終結(jié)果寫入文件keys_TFIDF.csv中。

源代碼如下:

# 采用TF-IDF方法提取文本關(guān)鍵詞
# http://scikit-learn.org/stable/modules/feature_extraction.html#tfidf-term-weighting
import sys,codecs
import pandas as pd
import numpy as np
import jieba.posseg
import jieba.analyse
from sklearn import feature_extraction
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
"""
       TF-IDF權(quán)重:
           1、CountVectorizer 構(gòu)建詞頻矩陣
           2、TfidfTransformer 構(gòu)建tfidf權(quán)值計算
           3、文本的關(guān)鍵字
           4、對應(yīng)的tfidf矩陣
"""
# 數(shù)據(jù)預(yù)處理操作:分詞,去停用詞,詞性篩選
def dataPrepos(text, stopkey):
    l = []
    pos = ['n', 'nz', 'v', 'vd', 'vn', 'l', 'a', 'd']  # 定義選取的詞性
    seg = jieba.posseg.cut(text)  # 分詞
    for i in seg:
        if i.word not in stopkey and i.flag in pos:  # 去停用詞 + 詞性篩選
            l.append(i.word)
    return l

# tf-idf獲取文本top10關(guān)鍵詞
#@profile
def getKeywords_tfidf(data,stopkey,topK):
    idList, titleList, abstractList = data['id'], data['title'], data['abstract']
    corpus = [] # 將所有文檔輸出到一個list中,一行就是一個文檔
    for index in range(len(idList)):
        text = '%s。%s' % (titleList[index], abstractList[index]) # 拼接標(biāo)題和摘要
        text = dataPrepos(text,stopkey) # 文本預(yù)處理
        text = " ".join(text) # 連接成字符串,空格分隔
        corpus.append(text)
    # 1、構(gòu)建詞頻矩陣,將文本中的詞語轉(zhuǎn)換成詞頻矩陣
    vectorizer = CountVectorizer()
    X = vectorizer.fit_transform(corpus) # 詞頻矩陣,a[i][j]:表示j詞在第i個文本中的詞頻
    # 2、統(tǒng)計每個詞的tf-idf權(quán)值
    transformer = TfidfTransformer()
    tfidf = transformer.fit_transform(X)
    # 3、獲取詞袋模型中的關(guān)鍵詞
    word = vectorizer.get_feature_names_out()
    # 4、獲取tf-idf矩陣,a[i][j]表示j詞在i篇文本中的tf-idf權(quán)重
    weight = tfidf.toarray()
    # 5、打印詞語權(quán)重
    ids, titles, keys = [], [], []
    for i in range(len(weight)):
        print("-------這里輸出第", i+1 , "篇文本的詞語tf-idf------")
        ids.append(idList[i])
        titles.append(titleList[i])
        df_word,df_weight = [],[] # 當(dāng)前文章的所有詞匯列表、詞匯對應(yīng)權(quán)重列表
        for j in range(len(word)):
            print (word[j],weight[i][j])
            df_word.append(word[j])
            df_weight.append(weight[i][j])
        df_word = pd.DataFrame(df_word,columns=['word'])
        df_weight = pd.DataFrame(df_weight,columns=['weight'])
        word_weight = pd.concat([df_word, df_weight], axis=1) # 拼接詞匯列表和權(quán)重列表
        word_weight = word_weight.sort_values(by="weight",ascending = False) # 按照權(quán)重值降序排列
        keyword = np.array(word_weight['word']) # 選擇詞匯列并轉(zhuǎn)成數(shù)組格式
        word_split = [keyword[x] for x in range(0,topK)] # 抽取前topK個詞匯作為關(guān)鍵詞
        word_split = " ".join(word_split)
        keys.append(word_split)
    result = pd.DataFrame({"id": ids, "title": titles, "key": keys},columns=['id','title','key'])
    return result

def main():
    # 讀取數(shù)據(jù)集
    dataFile = 'data/sample_data.csv'
    data = pd.read_csv(dataFile)
    # 停用詞表
    stopkey = [w.strip() for w in codecs.open('data/stopWord.txt', 'r', encoding='utf-8').readlines()]
    # tf-idf關(guān)鍵詞抽取
    result = getKeywords_tfidf(data,stopkey,10)
    result.to_csv("result/keys_TFIDF.csv",index=False)

if __name__ == '__main__':
    main()

最終運行結(jié)果如下圖所示。

在這里插入圖片描述

5 基于TextRank的文本關(guān)鍵詞抽取方法

5.1 PageRank算法思想

TextRank算法是基于PageRank算法的,PageRank算法是Google的創(chuàng)始人拉里·佩奇和謝爾蓋·布林于1998年在斯坦福大學(xué)讀研究生期間發(fā)明的,是用于根據(jù)網(wǎng)頁間相互的超鏈接來計算網(wǎng)頁重要性的技術(shù)。該算法借鑒了學(xué)術(shù)界評判學(xué)術(shù)論文重要性的方法,即查看論文的被引用次數(shù)?;谝陨舷敕?,PageRank算法的核心思想是,認(rèn)為網(wǎng)頁重要性由兩部分組成:

① 如果一個網(wǎng)頁被大量其他網(wǎng)頁鏈接到說明這個網(wǎng)頁比較重要,即被鏈接網(wǎng)頁的數(shù)量;

② 如果一個網(wǎng)頁被排名很高的網(wǎng)頁鏈接說明這個網(wǎng)頁比較重要,即被鏈接網(wǎng)頁的權(quán)重。

一般情況下,一個網(wǎng)頁的PageRank值(PR)計算公式如下所示:

在這里插入圖片描述

其中,PR(Pi)是第i個網(wǎng)頁的重要性排名即PR值;ɑ是阻尼系數(shù),一般設(shè)置為0.85;N是網(wǎng)頁總數(shù);Mpi 是所有對第i個網(wǎng)頁有出鏈的網(wǎng)頁集合;L(Pj)是第j 個網(wǎng)頁的出鏈數(shù)目。

初始時,假設(shè)所有網(wǎng)頁的排名都是1/N,根據(jù)上述公式計算出每個網(wǎng)頁的PR值,在不斷迭代趨于平穩(wěn)的時候,停止迭代運算,得到最終結(jié)果。一般來講,只要10次左右的迭代基本上就收斂了。

5.2 TextRank算法思想

TextRank算法是Mihalcea和Tarau于2004年在研究自動摘要提取過程中所提出來的,在PageRank算法的思路上做了改進(jìn)。該算法把文本拆分成詞匯作為網(wǎng)絡(luò)節(jié)點,組成詞匯網(wǎng)絡(luò)圖模型,將詞語間的相似關(guān)系看成是一種推薦或投票關(guān)系,使其可以計算每一個詞語的重要性。

基于TextRank的文本關(guān)鍵詞抽取是利用局部詞匯關(guān)系,即共現(xiàn)窗口,對候選關(guān)鍵詞進(jìn)行排序,該方法的步驟如下:

(1) 對于給定的文本D進(jìn)行分詞、詞性標(biāo)注和去除停用詞等數(shù)據(jù)預(yù)處理操作。本文采用結(jié)巴分詞,保留’n’,‘nz’,‘v’,‘vd’,‘vn’,‘l’,‘a’,'d’這幾個詞性的詞語,最終得到n個候選關(guān)鍵詞,即D=[t1,t2,…,tn] ;

(2) 構(gòu)建候選關(guān)鍵詞圖G=(V,E),其中V為節(jié)點集,由候選關(guān)鍵詞組成,并采用共現(xiàn)關(guān)系構(gòu)造任兩點之間的邊,兩個節(jié)點之間僅當(dāng)它們對應(yīng)的詞匯在長度為K的窗口中共現(xiàn)則存在邊,K表示窗口大小即最多共現(xiàn)K個詞匯;

(3) 根據(jù)公式迭代計算各節(jié)點的權(quán)重,直至收斂;

(4) 對節(jié)點權(quán)重進(jìn)行倒序排列,得到排名前TopN個詞匯作為文本關(guān)鍵詞。

說明:Jieba庫中包含jieba.analyse.textrank函數(shù)可直接實現(xiàn)TextRank算法,本文采用該函數(shù)進(jìn)行實驗。

5.3 代碼實現(xiàn)

基于TextRank方法實現(xiàn)文本關(guān)鍵詞抽取的代碼執(zhí)行步驟如下:

(1)讀取樣本源文件sample_data.csv;

(2)獲取每行記錄的標(biāo)題和摘要字段,并拼接這兩個字段;

(3)加載自定義停用詞表stopWord.txt;

(4)遍歷文本記錄,采用jieba.analyse.textrank函數(shù)篩選出指定詞性,以及topN個文本關(guān)鍵詞,并將結(jié)果存入數(shù)據(jù)框中;

(5)將最終結(jié)果寫入文件keys_TextRank.csv中。

源代碼如下:

# 采用TextRank方法提取文本關(guān)鍵詞
import sys
import pandas as pd
import jieba.analyse
"""
       TextRank權(quán)重:

            1、將待抽取關(guān)鍵詞的文本進(jìn)行分詞、去停用詞、篩選詞性
            2、以固定窗口大小(默認(rèn)為5,通過span屬性調(diào)整),詞之間的共現(xiàn)關(guān)系,構(gòu)建圖
            3、計算圖中節(jié)點的PageRank,注意是無向帶權(quán)圖
"""

# 處理標(biāo)題和摘要,提取關(guān)鍵詞
def getKeywords_textrank(data,topK):
    idList,titleList,abstractList = data['id'],data['title'],data['abstract']
    ids, titles, keys = [], [], []
    for index in range(len(idList)):
        text = '%s。%s' % (titleList[index], abstractList[index]) # 拼接標(biāo)題和摘要
        jieba.analyse.set_stop_words("data/stopWord.txt") # 加載自定義停用詞表
        print("\"",titleList[index],"\" ,  10 Keywords - TextRank :")
        keywords = jieba.analyse.textrank(text, topK=topK, allowPOS=('n','nz','v','vd','vn','l','a','d'))  # TextRank關(guān)鍵詞提取,詞性篩選
        word_split = " ".join(keywords)
        print(word_split)
        keys.append(word_split)
        ids.append(idList[index])
        titles.append(titleList[index])

    result = pd.DataFrame({"id": ids, "title": titles, "key": keys}, columns=['id', 'title', 'key'])
    return result

def main():
    dataFile = 'data/sample_data.csv'
    data = pd.read_csv(dataFile,encoding='utf-8')
    result = getKeywords_textrank(data,10)
    result.to_csv("result/keys_TextRank.csv",index=False,encoding='utf-8')

if __name__ == '__main__':
    main()

最終運行結(jié)果如下圖所示。

在這里插入圖片描述

6 基于Word2Vec詞聚類的文本關(guān)鍵詞抽取方法

6.1 Word2Vec詞向量表示

眾所周知,機(jī)器學(xué)習(xí)模型的輸入必須是數(shù)值型數(shù)據(jù),文本無法直接作為模型的輸入,需要首先將其轉(zhuǎn)化成數(shù)學(xué)形式?;赪ord2Vec詞聚類方法正是一種機(jī)器學(xué)習(xí)方法,需要將候選關(guān)鍵詞進(jìn)行向量化表示,因此要先構(gòu)建Word2Vec詞向量模型,從而抽取出候選關(guān)鍵詞的詞向量。

Word2Vec是當(dāng)時在Google任職的Mikolov等人于2013年發(fā)布的一款詞向量訓(xùn)練工具,一經(jīng)發(fā)布便在自然語言處理領(lǐng)域得到了廣泛的應(yīng)用。該工具利用淺層神經(jīng)網(wǎng)絡(luò)模型自動學(xué)習(xí)詞語在語料庫中的出現(xiàn)情況,把詞語嵌入到一個高維的空間中,通常在100-500維,在新的高維空間中詞語被表示為詞向量的形式。與傳統(tǒng)的文本表示方式相比,Word2Vec生成的詞向量表示,詞語之間的語義關(guān)系在高維空間中得到了較好的體現(xiàn),即語義相近的詞語在高維空間中的距離更近;同時,使用詞向量避免了詞語表示的“維度災(zāi)難”問題。

就實際操作而言,特征詞向量的抽取是基于已經(jīng)訓(xùn)練好的詞向量模型,詞向量模型的訓(xùn)練需要海量的語料才能達(dá)到較好的效果,而wiki中文語料是公認(rèn)的大型中文語料,本文擬從wiki中文語料生成的詞向量中抽取本文語料的特征詞向量。Wiki中文語料的Word2vec模型訓(xùn)練在文章“利用Python實現(xiàn)wiki中文語料的word2vec模型構(gòu)建”(https://github.com/gmh1627/Wiki_Zh_Word2vec_Python3) 中做了詳盡的描述,在此不贅述。即本文從文章最后得到的文件“wiki.zh.text.vector”中抽取候選關(guān)鍵詞的詞向量作為聚類模型的輸入。

另外,在閱讀資料的過程中發(fā)現(xiàn),有些十分專業(yè)或者生僻的詞語可能wiki中文語料中并未包含,為了提高語料的質(zhì)量,可新增實驗所需的樣本語料一起訓(xùn)練,筆者認(rèn)為這是一種十分可行的方式。本例中為了簡便并未采取這種方法,各位可參考此種方法根據(jù)自己的實際情況進(jìn)行調(diào)整。

6.2 K-means聚類算法

聚類算法旨在數(shù)據(jù)中發(fā)現(xiàn)數(shù)據(jù)對象之間的關(guān)系,將數(shù)據(jù)進(jìn)行分組,使得組內(nèi)的相似性盡可能的大,組件的相似性盡可能的小。

K-Means是一種常見的基于原型的聚類技術(shù),本文選擇該算法作為詞聚類的方法。其算法思想是:首先隨機(jī)選擇K個點作為初始質(zhì)心,K為用戶指定的所期望的簇的個數(shù),通過計算每個點到各個質(zhì)心的距離,將每個點指派到最近的質(zhì)心形成K個簇,然后根據(jù)指派到簇的點重新計算每個簇的質(zhì)心,重復(fù)指派和更新質(zhì)心的操作,直到簇不發(fā)生變化或達(dá)到最大的迭代次數(shù)則停止。

6.3 Word2Vec詞聚類文本關(guān)鍵詞抽取方法流程

Word2Vec詞聚類文本關(guān)鍵詞抽取方法的主要思路是對于用詞向量表示的文本詞語,通過K-Means算法對文章中的詞進(jìn)行聚類,選擇聚類中心作為文章的一個主要關(guān)鍵詞,計算其他詞與聚類中心的距離即相似度,選擇topN個距離聚類中心最近的詞作為文本關(guān)鍵詞,而這個詞間相似度可用Word2Vec生成的向量計算得到。

假設(shè)Dn為測試語料的大小,使用該方法進(jìn)行文本關(guān)鍵詞抽取的步驟如下所示:

(1) 對Wiki中文語料進(jìn)行Word2vec模型訓(xùn)練,參考文章“利用Python實現(xiàn)wiki中文語料的word2vec模型構(gòu)建”(https://github.com/gmh1627/Wiki_Zh_Word2vec_Python3) ,得到詞向量文件“wiki.zh.text.vector”;

(2) 對于給定的文本D進(jìn)行分詞、詞性標(biāo)注、去重和去除停用詞等數(shù)據(jù)預(yù)處理操作。本分采用結(jié)巴分詞,保留’n’,‘nz’,‘v’,‘vd’,‘vn’,‘l’,‘a’,'d’這幾個詞性的詞語,最終得到n個候選關(guān)鍵詞,即D=[t1,t2,…,tn] ;

(3) 遍歷候選關(guān)鍵詞,從詞向量文件中抽取候選關(guān)鍵詞的詞向量表示,即WV=[v1,v2,…,vm];

(4) 對候選關(guān)鍵詞進(jìn)行K-Means聚類,得到各個類別的聚類中心;

(5) 計算各類別下,組內(nèi)詞語與聚類中心的距離(歐幾里得距離),按聚類大小進(jìn)行升序排序;

(6) 對候選關(guān)鍵詞計算結(jié)果得到排名前TopN個詞匯作為文本關(guān)鍵詞。

步驟(4)中需要人為給定聚類的個數(shù),本文測試語料是汽車行業(yè)的專利文本,因此只需聚為1類,各位可根據(jù)自己的數(shù)據(jù)情況進(jìn)行調(diào)整;步驟(5)中計算各詞語與聚類中心的距離,常見的方法有歐式距離和曼哈頓距離,本文采用的是歐式距離,計算公式如下:

在這里插入圖片描述

6.4 代碼實現(xiàn)

Python第三方工具包Scikit-learn提供了K-Means聚類算法的相關(guān)函數(shù),本文用到了sklearn.cluster.KMeans()函數(shù)執(zhí)行K-Means算法,sklearn.decomposition.PCA()函數(shù)用于數(shù)據(jù)降維以便繪制圖形。

基于Word2Vec詞聚類方法實現(xiàn)文本關(guān)鍵詞抽取的代碼執(zhí)行步驟如下:

(1)讀取樣本源文件sample_data.csv;

(2)獲取每行記錄的標(biāo)題和摘要字段,并拼接這兩個字段;

(3)加載自定義停用詞表stopWord.txt,并對拼接的文本進(jìn)行數(shù)據(jù)預(yù)處理操作,包括分詞、篩選出符合詞性的詞語、去重、去停用詞,形成列表存儲;

(4)讀取詞向量模型文件’wiki.zh.text.vector’,從中抽取出所有候選關(guān)鍵詞的詞向量表示,存入文件中;

(5)讀取文本的詞向量表示文件,使用KMeans()函數(shù)得到聚類結(jié)果以及聚類中心的向量表示;

(6)采用歐式距離計算方法,計算得到每個詞語與聚類中心的距離;

(7)按照得到的距離升序排列,選取排名前topN個詞作為文本關(guān)鍵詞,并寫入數(shù)據(jù)框中;

(8)將最終結(jié)果寫入文件keys_word2vec.csv中。

源代碼1如下:

# 采用Word2Vec詞聚類方法抽取關(guān)鍵詞1——獲取文本詞向量表示
import warnings
warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim')  # 忽略警告
import sys, codecs
import pandas as pd
import numpy as np
import jieba
import jieba.posseg
import gensim

# 返回特征詞向量
def getWordVecs(wordList, model):
    name = []
    vecs = []
    for word in wordList:
        word = word.replace('\n', '')
        try:
            if word in model:  # 模型中存在該詞的向量表示
                name.append(word)
                vecs.append(model[word])
        except KeyError:
            continue
    a = pd.DataFrame(name, columns=['word'])
    b = pd.DataFrame(np.array(vecs, dtype='float'))
    return pd.concat([a, b], axis=1)

# 數(shù)據(jù)預(yù)處理操作:分詞,去停用詞,詞性篩選
def dataPrepos(text, stopkey):
    l = []
    pos = ['n', 'nz', 'v', 'vd', 'vn', 'l', 'a', 'd']  # 定義選取的詞性
    seg = jieba.posseg.cut(text)  # 分詞
    for i in seg:
        if i.word not in l and i.word not in stopkey and i.flag in pos:  # 去重 + 去停用詞 + 詞性篩選
            # print i.word
            l.append(i.word)
    return l

# 根據(jù)數(shù)據(jù)獲取候選關(guān)鍵詞詞向量
def buildAllWordsVecs(data, stopkey, model):
    idList, titleList, abstractList = data['id'], data['title'], data['abstract']
    for index in range(len(idList)):
        id = idList[index]
        title = titleList[index]
        abstract = abstractList[index]
        l_ti = dataPrepos(title, stopkey)  # 處理標(biāo)題
        l_ab = dataPrepos(abstract, stopkey)  # 處理摘要
        # 獲取候選關(guān)鍵詞的詞向量
        words = np.append(l_ti, l_ab)  # 拼接數(shù)組元素
        words = list(set(words))  # 數(shù)組元素去重,得到候選關(guān)鍵詞列表
        wordvecs = getWordVecs(words, model)  # 獲取候選關(guān)鍵詞的詞向量表示
        # 詞向量寫入csv文件,每個詞400維
        data_vecs = pd.DataFrame(wordvecs)
        data_vecs.to_csv('result/vecs/wordvecs_' + str(id) + '.csv', index=False)
        print("document ", id, " well done.")

def main():
    # 讀取數(shù)據(jù)集
    dataFile = 'data/sample_data.csv'
    data = pd.read_csv(dataFile)
    # 停用詞表
    stopkey = [w.strip() for w in codecs.open('data/stopWord.txt', 'r').readlines()]
    # 詞向量模型
    inp = 'wiki.zh.text.vector'
    model = gensim.models.KeyedVectors.load_word2vec_format(inp, binary=False)
    buildAllWordsVecs(data, stopkey, model)

if __name__ == '__main__':
    main()

源代碼2如下:

# 采用Word2Vec詞聚類方法抽取關(guān)鍵詞2——根據(jù)候選關(guān)鍵詞的詞向量進(jìn)行聚類分析
import sys,os
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import math
import os

# 對詞向量采用K-means聚類抽取TopK關(guān)鍵詞
def getkeywords_kmeans(data,topK):
    words = data["word"] # 詞匯
    vecs = data.iloc[:,1:] # 向量表示

    kmeans = KMeans(n_clusters=1,n_init=10,random_state=10).fit(vecs)
    labels = kmeans.labels_ #類別結(jié)果標(biāo)簽
    labels = pd.DataFrame(labels,columns=['label'])
    new_df = pd.concat([labels,vecs],axis=1)
    df_count_type = new_df.groupby('label').size() #各類別統(tǒng)計個數(shù)
    # print df_count_type
    vec_center = kmeans.cluster_centers_ #聚類中心

    # 計算距離(相似性) 采用歐幾里得距離(歐式距離)
    distances = []
    vec_words = np.array(vecs) # 候選關(guān)鍵詞向量,dataFrame轉(zhuǎn)array
    vec_center = vec_center[0] # 第一個類別聚類中心,本例只有一個類別
    length = len(vec_center) # 向量維度
    for index in range(len(vec_words)): # 候選關(guān)鍵詞個數(shù)
        cur_wordvec = vec_words[index] # 當(dāng)前詞語的詞向量
        dis = 0 # 向量距離
        for index2 in range(length):
            dis += (vec_center[index2]-cur_wordvec[index2])*(vec_center[index2]-cur_wordvec[index2])
        dis = math.sqrt(dis)
        distances.append(dis)
    distances = pd.DataFrame(distances,columns=['dis'])

    result = pd.concat([words, labels ,distances], axis=1) # 拼接詞語與其對應(yīng)中心點的距離
    result = result.sort_values(by="dis",ascending = True) # 按照距離大小進(jìn)行升序排序
    """
    # 將用于聚類的數(shù)據(jù)的特征維度降到2維
    pca = PCA(n_components=2)
    new_pca = pd.DataFrame(pca.fit_transform(new_df))
    print(new_pca)
    # 可視化
    d = new_pca[new_df['label'] == 0]
    plt.plot(d[0],d[1],'r.')
    d = new_pca[new_df['label'] == 1]
    plt.plot(d[0], d[1], 'go')
    d = new_pca[new_df['label'] == 2]
    plt.plot(d[0], d[1], 'b*')
    plt.gcf().savefig('kmeans.png')
    plt.show()
    """
    # 抽取排名前topK個詞語作為文本關(guān)鍵詞
    wordlist = np.array(result['word']) # 選擇詞匯列并轉(zhuǎn)成數(shù)組格式
    word_split = [wordlist[x] for x in range(0,topK)] # 抽取前topK個詞匯
    word_split = " ".join(word_split)
    return word_split

def main():
    # 讀取數(shù)據(jù)集
    dataFile = 'data/sample_data.csv'
    articleData = pd.read_csv(dataFile,encoding='utf-8')
    
    ids, titles, keys = [], [], []

    rootdir = "result/vecs" # 詞向量文件根目錄
    fileList = os.listdir(rootdir) #列出文件夾下所有的目錄與文件
    # 遍歷文件
    for i in range(len(fileList)):
        filename = fileList[i]
        path = os.path.join(rootdir,filename)
        if os.path.isfile(path):
            data = pd.read_csv(path, encoding='utf-8') # 讀取詞向量文件數(shù)據(jù)
            artile_keys = getkeywords_kmeans(data,10) # 聚類算法得到當(dāng)前文件的關(guān)鍵詞
            
            # 根據(jù)文件名獲得文章id以及標(biāo)題
            (shortname, extension) = os.path.splitext(filename) # 得到文件名和文件擴(kuò)展名
            t = shortname.split("_")
            article_id = int(t[len(t)-1]) # 獲得文章id
            artile_tit = articleData[articleData.id==article_id]['title'] # 獲得文章標(biāo)題
            artile_tit = list(artile_tit)[0] # series轉(zhuǎn)成字符串
            ids.append(article_id)
            titles.append(artile_tit)
            keys.append(artile_keys)
    # 所有結(jié)果寫入文件
    result = pd.DataFrame({"id": ids, "title": titles, "key": keys}, columns=['id', 'title', 'key'])
    result = result.sort_values(by="id",ascending=True) # 排序
    result.to_csv("result/keys_word2vec.csv", index=False,encoding='utf-8')

if __name__ == '__main__':
    main()

最終運行結(jié)果如下圖所示。

在這里插入圖片描述

7 結(jié)語

本文總結(jié)了三種常用的抽取文本關(guān)鍵詞的方法:TF-IDF、TextRank和Word2Vec詞向量聚類,并做了原理、流程以及代碼的詳細(xì)描述。因本文使用的測試語料較為特殊且數(shù)量較少,未做相應(yīng)的結(jié)果分析,根據(jù)觀察可以發(fā)現(xiàn),得到的十個文本關(guān)鍵詞都包含有文本的主旨信息,其中TF-IDF和TextRank方法的結(jié)果較好,Word2Vec詞向量聚類方法的效果不佳,這與文獻(xiàn)[8]中的結(jié)論是一致的。文獻(xiàn)[8]中提到,對單文檔直接應(yīng)用Word2Vec詞向量聚類方法時,選擇聚類中心作為文本的關(guān)鍵詞本身就是不準(zhǔn)確的,因此與其距離最近的N個詞語也不一定是關(guān)鍵詞,因此用這種方法得到的結(jié)果效果不佳;而TextRank方法是基于圖模型的排序算法,在單文檔關(guān)鍵詞抽取方面有較為穩(wěn)定的效果,因此較多的論文是在TextRank的方法上進(jìn)行改進(jìn)而提升關(guān)鍵詞抽取的準(zhǔn)確率。

另外,本文的實驗?zāi)康闹饕谟谥v解三種方法的思路和流程,實驗過程中的某些細(xì)節(jié)仍然可以改進(jìn)。例如Word2Vec模型訓(xùn)練的原始語料可加入相應(yīng)的專業(yè)性文本語料;標(biāo)題文本往往包含文檔的重要信息,可對標(biāo)題文本包含的詞語給予一定的初始權(quán)重;測試數(shù)據(jù)集可采集多個分類的長文本,與之對應(yīng)的聚類算法KMeans()函數(shù)中的n_clusters參數(shù)就應(yīng)當(dāng)設(shè)置成分類的個數(shù);根據(jù)文檔的分詞結(jié)果,去除掉所有文檔中都包含某一出現(xiàn)頻次超過指定閾值的詞語;等等。各位可根據(jù)自己的實際情況或者參考論文資料進(jìn)行參數(shù)的優(yōu)化以及細(xì)節(jié)的調(diào)整,歡迎給我留言或者私信討論,大家一起共同學(xué)習(xí)。

至此,利用Pyhon實現(xiàn)中文文本關(guān)鍵詞抽取的三種方法全部介紹完畢,測試數(shù)據(jù)、代碼和運行結(jié)果已上傳至本人的GitHub倉庫。項目文件為keyword_extraction,data文件夾中包含停用詞表stopWord.txt和測試集sample_data.csv,result文件夾包含三種方法的實驗結(jié)果和每篇文檔對應(yīng)的詞向量文件(vecs)。文中若存在不正確的地方,歡迎各位朋友批評指正!本文是在https://github.com/AimeeLee77/keyword_extraction 的基礎(chǔ)上加以修改的(原文用的是python 2.7),在此對原作者深表感謝!

以上就是Python實現(xiàn)中文文本關(guān)鍵詞抽取的三種方法的詳細(xì)內(nèi)容,更多關(guān)于Python關(guān)鍵詞抽取的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論