基於業務場景進行關鍵詞提取以及Python實現


背景:

1.抽取不全

https://lemon.baidu.com/a?id=169074&flowSrcId=12004  

黃金微雕瘦臉永久嗎?做完三個月就開始反彈了   →  'tags': '微雕_1,瘦臉_1'     黃金微雕沒有抽取出來

2.抽取詞過於寬泛

https://lemon.baidu.com/a?id=26502&flowSrcId=12004

'tags': '迪麗熱巴雙眼皮_1,整形_1,割雙眼皮_1,雙眼皮_1'  →    整形這個詞比較寬泛,不能召回真實的結果

3. 標簽粒度較粗,不能較好體現文章的主題

 

關鍵詞提取流程:

1.LAC進行分詞

可以通過加載詞表進而可以將詞更好的分開。具體的應用可以參考:https://github.com/baidu/lac/tree/master/python

代碼如下:

from LAC import LAC
import jieba

MARK_2_name = {"n": u"普通名詞", "f": u"方位名詞", "s": u"處所名詞", "t": u"時間",
"nr": u"人名", "ns": u"地名", "nt": u"機構名", "nw": u"作品名",
"nz": u"其他專名", "v": u"普通動詞", "vd": u"動副詞", "vn": u"名動詞",
"a": u"形容詞", "ad": u"副形詞", "an": u"名形詞", "d": u"副詞",
"m": u"數量詞", u"q": u"量詞", "r": u"代詞", "p": u"介詞",
"c": u"連詞", "u": u"助詞", "xc": u"其他虛詞", "w": u"標點符號",
"PER": u"人名", "LOC": u"地名", "ORG": u"機構名", "TIME": u"時間"}
lac = LAC()

HAS_MEANING = set([u"人名", u"地名", u"機構名"])
NO_MEANING = set([u"數量詞", u"量詞", u"代詞", u"介詞", u"連詞", u"助詞", u"其他虛詞", u"標點符號", u"副詞"])

def read(path):
r = []
with open(path) as f:
lines = f.readlines()
for line in lines:
line = line.strip('\n')
r.append(line)
return r

def test_lac(text):
path = '/home/work/limingqi01/limingqi01/extract_tag/yimei.words.txt'
s = read(path)
lac.load_customization(path, sep=None)
res = lac.run(text)
for i, j in zip(res[0], res[1]):
if i in s:
print(i)

其中百度的LAC分詞方式,要比jieba分詞更好用的多,可以針對具體領域的詞進行人為干預,非常適合應用場景。

2.詞表擴充:

    (1)通過尋找詞的同義詞或者近義詞的方式:

               import synonyms

               print(synonyms.nearby('隆鼻'))

    (2)通過query擴展的方式:調用其接口進行query擴充詞表

    (3)通過query改寫的方式:調用其接口進行query擴充詞表

 

3.圖文標簽:

參考鏈接:https://zhuanlan.zhihu.com/p/87128357

參考鏈接:https://mp.weixin.qq.com/s/CEPBXaJfrIO1w0yX7YdZZA

 

4.關鍵詞提取方法:

(1)TextRank:

 TextRank算法是由網頁重要性排序算法PageRank算法遷移而來:PageRank算法根據萬維網上頁面之間的鏈接關系計算每個頁面的重要性;TextRank算法將詞視為“萬維網上的節點”,根據詞之間的共現關系計算每個詞的重要性,並將PageRank中的有向邊變為無向邊。TextRank算法是由PageRank算法改進而來的,二者的思想有相同之處,區別在於:PageRank算法根據網頁之間的鏈接關系構造網絡,而TextRank算法根據詞之間的共現關系構造網絡;PageRank算法構造的網絡中的邊是有向無權邊,而TextRank算法構造的網絡中的邊是無向有權邊.

(2)tf-idf:

是自然語言處理中的一個簡單的模型。tf代表term frequency,也就是詞頻,而idf代表着inverse document frequency,叫做逆文檔頻率,這兩個屬性都是屬於單詞的屬性。概括來說,tf-idf模型是用來給文檔中的每個詞根據重要程度計算一個得分,這個得分就是tf-idf。

代碼實現:

import jieba.analyse
#准備語料
corpus = "《知否知否應是綠肥紅瘦》是由東陽正午陽光影視有限公司出品,侯鴻亮擔任制片人," \
"張開宙執導,曾璐、吳桐編劇,趙麗穎、馮紹峰領銜主演,朱一龍、施詩、張佳寧、曹翠芬、" \
"劉鈞、劉琳、高露、王仁君、李依曉、王鶴潤、張曉謙、李洪濤主演,王一楠、" \
"陳瑾特別出演的古代社會家庭題材電視劇"

#textrank
keywords_textrank = jieba.analyse.textrank(corpus)
print(keywords_textrank)

#tf-idf
keywords_tfidf = jieba.analyse.extract_tags(corpus)
print(keywords_tfidf)

 

參數設置:

sentence:待提取關鍵詞的語料

topK: 提取多少個關鍵詞,默認為20個

withWeight: 若為True,返回值形式為(word, weight)。若為False,返回的只有words,默認為False

allowPOS: 允許哪些詞性作為關鍵詞,默認的詞性為’ns’, ‘n’, ‘vn’, ‘v’

withFlag: 若為True,返回值形式為(word, pos)。若為False,返回的只有words,默認為False。其中pos為詞性。

 

優缺點:上面兩種算法還是需要結合具體的應用場景進行比較,算法的結果可能會不盡人意,需要建立完善的詞表,需要進行多個算法結果的評估,

才能給出更有應用價值的標簽,標簽是非常基礎的工作,基礎工作做到極致,在推薦和搜索中才能起到很好的作用。

 

5.內容tag的具體應用:

例子:

Title:做雙眼皮老了會怎樣?

Content:很多人認為年輕的時候【割雙眼皮】,會隨着年齡的增【長臉】型的變化影響雙眼皮的形狀。有的愛美者在做完雙眼皮多年后,

會發現自己的雙眼皮好像消失了,其實是變成了內雙。很多求美者擔心老了以后雙眼皮會出現后遺症,做的雙眼皮是否成功,術后會

很快顯現出來,只要術中醫生技術過關,這些問題都可以避免。人老以后都會出現下垂的狀況。

 


 

        在上面這個問答中,標紅的和【】括起來的都是醫美詞,【】括起來的不僅僅是醫美詞,同時也是標簽詞。而我們的任務就是

給例如上面的這個物料打上標簽(例如【割雙眼皮】、【長臉】),並排除置信度不高的標簽(例如【長臉】)。

        一個簡單的打標簽方式是將醫美詞典加入分詞器(jieba, lac等等)然后對物料進行分詞,遍歷找出其中的標簽,並以詞頻作為

其權重。但這樣有問題,因為物料講的是割雙眼皮的事,但標簽【割雙眼皮】和【長臉】將有相同的權重(詞頻一樣)。因此需要對

這樣的打標簽方式進行改進。

(1)基於相關詞增強的標簽抽取

         1.1 保守的增強策略

        所謂保守的增強策略指的是:即只有當標簽詞能匹配上時才用其相關詞增強該標簽詞。

        針對上面的問題,我們提出了基於相關詞增強的標簽打法。我們可以通過在大量物料上訓練詞向量,並通過詞向量相似度找出

每個標簽詞的相關詞。然后利用相關詞增強標簽詞。

例如【割雙眼皮】的相關詞為:

                                       

而【長臉】的相關詞是:

                                     

這樣一來,只要標簽詞的相關詞在物料中,那么我們就可以用其相關詞來增強它的權重。

Title:做雙眼皮老了會怎樣?

Content:

        很多人認為年輕的時候【割雙眼皮】,會隨着年齡的增【長臉】型的變化影響雙眼皮的形狀。有的愛美者在做完雙眼皮多年后,

會發現自己的雙眼皮好像消失了,其實是變成了內雙。很多求美者擔心老了以后雙眼皮會出現后遺症,做的雙眼皮是否成功,術后會

很快顯現出來,只要術中醫生技術過關,這些問題都可以避免。人老以后都會出現下垂的狀況。


 

其中做雙眼皮, 雙眼皮, 做完雙眼皮都是標簽詞【割雙眼皮】的相關詞。而【長臉】在本文中並無相關詞,因此,我們更傾向於把

割雙眼皮】作為其標簽。我們設計了一個用相關詞增強標簽詞的權重計算公式。如下:

                               

其中, k是標簽詞。 freq(·)是詞頻函數,即返回一個詞的詞頻。 n是所有該文本中出現的k的相關詞個數。pi表示k的第i個相關詞

Sim(·) 為cos相似度函數。

        1.2 激進的增強策略

              所謂激進的增強策略指的是:即無論標簽詞能否匹配上,都用已經匹配上的相關詞召回並增強標簽詞。

             這需要我們構建從相關詞到標簽詞的映射。這很容易。略~

            此時,我們只需找出物料中的相關詞,然后用它召回標簽詞,假如多個相關詞召回同一個標簽詞(權重為),那么該標簽詞

的權重就是這幾個召回的標簽詞權重之和。值得注意的是在這樣的策略下,能大幅度提高標簽覆蓋率,但也導致打的標簽過泛。

         1.3 詞向量訓練

        我們在多達400W+的物料上訓練了不下10個詞向量模型,包括Fasttext, Skip-Gram, Cbow模型。其中Fasttext表現較好,且

能較好處理OOB的情況,故選用。最終參數設置為:

(詞向量維度:100, 迭代次數:20, 窗口大小:5,最小詞長:1, 最大詞長:6, 詞最小出現次數:5)

 

(2)基於推薦的標簽抽取

        我們可以將打標簽這個任務抽象為標簽推薦,對於一個物料(醫美內容),我們可以找出其中的醫美詞。我們的目的是為

物料打上標簽,然而,並非所有醫美詞都是標簽詞。我們可以根據物料中包含的醫美詞,給物料『推薦』相應的標簽詞,這就

將打標簽任務轉換成了推薦任務。我們需要優化的就是如何給物料推薦最符合的標簽詞。

       2.1 用協同過濾法抽取標簽

一種簡單的基於推薦的標簽抽取是基於協同過濾的標簽抽取。其核心思想是:

  • 包含醫美詞A的物料中有多少比例的物料也包含醫美詞B,若包含A的物料中大部分也包含B,那可以認為A和B較為相似

  • 得到了相似度之后可以利用推薦系統的思路給物料打上標簽。

          2.1.1 計算醫美詞之間的相似度

                   假設包含醫美詞 a 的物料數為 N(a),包含醫美詞 b 的物料數為 N(b),那么 a 與 b 的相似度為:

                                                             

上述公式可以理解為包含醫美詞 a 的物料中,有多少比例的物料也包含 b,比例越高,說明 a 與 b 的相似度越高。但是這樣的公式

有一個問題,如果醫美詞 b 很熱門,很多物料都包含,那么相似度就會無限接近1,這樣就會造成所有的醫美詞拿出來,都與 b 有

極高的相似度,這樣就沒有辦法證明醫美詞之間的相似度是可靠的了。為了避免出現類似的情況,可以通過以下公式進行改進:

                                                              

         2.1.2 物料打標簽

                  獲得了醫美詞之間的相似度后,根據以下公式來計算標簽 b在物料 u 上的得分:

                                                                    

其中,N(u)是物料包含的醫美詞集合,S(b,K)是和醫美詞 b 最相似的前 K 個醫美詞的集合,Wab 是醫美詞 a 和 b 的相似度,Rua 是

醫美詞 a 在物料 u 中的詞頻(反應了a在物料u中的重要程度)。根據最終的標簽在物料上的得分,我們會選取得分最高的幾個標簽

作為物料的標簽。

技術總結:大家具體應用的時候,還是要結合自己的數據,根據評估結果更好的選擇方法,以上方法更容易找到原文內容中的關鍵詞,

很難擴充出來不出現的,同義詞召回可以擴充一下相近的,總之上面的方法在業務場景中還是非常值得應用的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM