結合 TextRank 與 TF-IDF 更精準的提取文章關鍵詞

我們往往需要從大量的文字中迅速提取出核心關鍵詞,以便快速把握文章主旨。如果要做資訊流分發、基於內容的推薦演算法,這也是其中很重要的步驟,一般用於文章特徵。

傳統的 TF-IDF 方法雖然廣泛使用,但有時候它並不能完全準確地反映出文章的關鍵內容。實際上,TextRank、PositionRank 等任意演算法都很難保證不遺漏重要的關鍵詞。為了提高關鍵詞提取的準確性,我們可以採用結合多種演算法的方式來提取關鍵詞。我在產品中使用了 TextRank 演算法和 TF-IDF 的方法來結合,實測效果不錯。

不同的庫實現的關鍵詞提取,結果往往不同,因為其實現細節有優劣之分。這裡我使用的是 pke_zhtextrank4zh 庫,透過 Python 程式碼實現這一過程。

在介紹程式碼實現之前,我們先簡單回顧一下 TF-IDF 和 TextRank 的基本概念。

TF-IDF

TF-IDF(詞頻-逆文件頻率)是一種用於資訊檢索與文字挖掘的常用加權技術。它透過計算詞語的頻率(TF)和其在文件集中的分佈(IDF)來評估一個詞語對於一個檔案集或一個語料庫中的其中一份檔案的重要程度。TF-IDF 值越大,這個詞在文字中的重要性越高。

你可以在這篇文章檢視具體的計算方法和公式。

TextRank

TextRank 是一種基於圖的排序演算法,透過將文字分割成多個單詞,並將這些單詞作為圖中的節點,透過節點之間的相互影響,計算每個節點的重要性。在關鍵詞提取的場景中,TextRank 可以幫助我們找出文字中的高權重關鍵詞。

接下來,我們將詳細講解如何使用程式碼實現更精準的關鍵詞提取。

  1. 文字預處理:首先,我們將文字轉換為小寫,並使用正則表示式移除所有的數字,這是為了確保後續處理的文字是純粹的文字資料。

  2. 關鍵詞提取:我們使用 TfIdf_m.extract 方法和 tr4w.analyze 方法分別提取 TF-IDF 和 TextRank 的結果。

  3. 關鍵詞合併與向量生成:將兩種方法提取的關鍵詞合併,併為每個關鍵詞生成相應的 TF-IDF 和 TextRank 向量。

  4. 資料歸一化:為了使不同的指標具有可比性,我們使用 MinMaxScaler 對資料進行歸一化處理。

  5. 混合向量計算:將歸一化後的 TF-IDF 向量和 TextRank 向量按照一定的比例混合,從而得到一個綜合考慮兩者的混合向量。

  6. 關鍵詞排序:根據混合向量的值對關鍵詞進行排序,並選出排名前20的關鍵詞作為最終的關鍵詞。

完整程式碼如下:

from pke_zh import TextRank, TfIdf, PositionRank, Yake, KeyBert
import codecs
from timeit import default_timer as timer
from sklearn.preprocessing import MinMaxScaler
from textrank4zh import TextRank4Keyword
import numpy as np
import re

TfIdf_m = TfIdf()
tr4w = TextRank4Keyword()

def extract_keywords_mixed(text):
    # 轉換為小寫
    text = text.lower()
    # 使用正則移除所有純數字,包括整數和小數
    text = re.sub(r'\b\d+(\.\d+)?\b', '', text)

    # 獲取初始 tf-idf 和 textrank 資料
    tfidf = TfIdf_m.extract(text, n_best=30)
    tr4w.analyze(text=text, lower=True, window=2)

    textrank = []
    for item in tr4w.get_keywords(30, word_min_len=1):
        textrank.append((item.word, item.weight))
    
    # 合併關鍵詞清單
    allKeywords = []
    for word, weight in tfidf:
        allKeywords.append(word)
    for word, weight in textrank:
        if word not in allKeywords:
            allKeywords.append(word)

    # 根據合併的關鍵詞清單重新生成 tfidf 和 textrank 向量,對原始不存在的資料使用 0 填充
    tfidf_vector = []
    textrank_vector = []
    for word in allKeywords:
        tfidf_vector.append([weight for w, weight in tfidf if w == word][0] if word in [w for w, weight in tfidf] else 0)
        textrank_vector.append([weight for w, weight in textrank if w == word][0] if word in [w for w, weight in textrank] else 0)
    
    # 資料歸一化
    scaler = MinMaxScaler()
    tfidf_vector = np.array(tfidf_vector).reshape(-1, 1)
    tfidf_vector = scaler.fit_transform(tfidf_vector)
    textrank_vector = np.array(textrank_vector).reshape(-1, 1)
    textrank_vector = scaler.fit_transform(textrank_vector)

    # 混合向量
    mixed_vector = (tfidf_vector * 3 + textrank_vector * 2) / 5

    # 加入關鍵詞名稱
    mixed_keywords = []
    for i, word in enumerate(allKeywords):
        mixed_keywords.append((word, mixed_vector[i][0]))
    
    # 獲取前 top 個關鍵詞
    top = 20
    mixed_keywords = sorted(mixed_keywords, key=lambda x: x[1], reverse=True)
    mixed_keywords = mixed_keywords[:top]
    print(mixed_keywords)

    return mixed_keywords

透過結合 TF-IDF 和 TextRank 演算法,我們可以更全面地考慮詞語的重要性和文字結構,從而提高關鍵詞提取的準確性。以上程式碼實現了一個基於這兩種技術的混合關鍵詞提取方法,有助於我們在實際應用中抽取出更加精準的關鍵資訊。

当前页阅读量为: