成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Python中七種主要關鍵詞提取算法的基準測試

開發(fā) 后端 算法
我一直在尋找有效關鍵字提取任務算法。 目標是找到一種算法,能夠以有效的方式提取關鍵字,并且能夠平衡提取質量和執(zhí)行時間,因為我的數(shù)據(jù)語料庫迅速增加已經達到了數(shù)百萬行。

我一直在尋找有效關鍵字提取任務算法。 目標是找到一種算法,能夠以有效的方式提取關鍵字,并且能夠平衡提取質量和執(zhí)行時間,因為我的數(shù)據(jù)語料庫迅速增加已經達到了數(shù)百萬行。 我對于算法一個主要的要求是提取關鍵字本身總是要有意義的,即使脫離了上下文的語境也能夠表達一定的含義。

[[437010]]

本篇文章使用 2000 個文檔的語料庫對幾種著名的關鍵字提取算法進行測試和試驗。

使用的庫列表

我使用了以下python庫進行研究

NLTK,以幫助我在預處理階段和一些輔助函數(shù)

  • RAKE
  • YAKE
  • PKE
  • KeyBERT
  • Spacy

Pandas 和Matplotlib還有其他通用庫

實驗流程

基準測試的工作方式如下

 

 

我們將首先導入包含我們的文本數(shù)據(jù)的數(shù)據(jù)集。 然后,我們將為每個算法創(chuàng)建提取邏輯的單獨函數(shù)

algorithm_name(str: text) → [keyword1, keyword2, ..., keywordn]

然后,我們創(chuàng)建的一個函數(shù)用于提取整個語料庫的關鍵詞。

extract_keywords_from_corpus(algorithm, corpus) → {algorithm, corpus_keywords, elapsed_time}

下一步,使用Spacy幫助我們定義一個匹配器對象,用來判斷關鍵字是否對我們的任務有意義,該對象將返回 true 或 false。

最后,我們會將所有內容打包到一個輸出最終報告的函數(shù)中。

數(shù)據(jù)集

我使用的是來自互聯(lián)網的小文本數(shù)數(shù)據(jù)集。這是一個樣本

 

  1. ['To follow up from my previous questions. . Here is the result!\n'
  2. 'European mead competitions?\nI’d love some feedback on my mead, but entering the Mazer Cup isn’t an option for me, since shipping alcohol to the USA from Europe is illegal. (I know I probably wouldn’t get caught/prosecuted, but any kind of official record of an issue could screw up my upcoming citizenship application and I’m not willing to risk that).\n\nAre there any European mead comps out there? Or at least large beer comps that accept entries in the mead categories and are likely to have experienced mead judges?''Orange Rosemary Booch\n''Well folks, finally happened. Went on vacation and came home to mold.\n''I’m opening a gelato shop in London on Friday so we’ve been up non-stop practicing flavors - here’s one of our most recent attempts!\n'"Does anyone have resources for creating shelf stable hot sauce? Ferment and then water or pressure can?\nI have dozens of fresh peppers I want to use to make hot sauce, but the eventual goal is to customize a recipe and send it to my buddies across the States. I believe canning would be the best way to do this, but I'm not finding a lot of details on it. Any advice?", 'what is the practical difference between a wine filter and a water filter?\nwondering if you could use either', 'What is the best custard base?\nDoes someone have a recipe that tastes similar to Culver’s frozen custard?', 'Mold?\n' 

 

大部分是與食物相關的。我們將使用2000個文檔的樣本來測試我們的算法。

我們現(xiàn)在還沒有對文本進行預處理,因為有一些算法的結果是基于stopwords和標點符號的。

算法

讓我們定義關鍵字提取函數(shù)。

 

  1. # initiate BERT outside of functions 
  2. bert = KeyBERT() 
  3. # 1. RAKE 
  4. def rake_extractor(text): 
  5. ""
  6. Uses Rake to extract the top 5 keywords from a text 
  7. Arguments: text (str) 
  8. Returns: list of keywords (list) 
  9. ""
  10. r = Rake() 
  11. r.extract_keywords_from_text(text) 
  12. return r.get_ranked_phrases()[:5] 
  13. # 2. YAKE 
  14. def yake_extractor(text): 
  15. ""
  16. Uses YAKE to extract the top 5 keywords from a text 
  17. Arguments: text (str) 
  18. Returns: list of keywords (list) 
  19. ""
  20. keywords = yake.KeywordExtractor(lan="en", n=3, windowsSize=3, top=5).extract_keywords(text) 
  21. results = [] 
  22. for scored_keywords in keywords: 
  23. for keyword in scored_keywords: 
  24. if isinstance(keyword, str): 
  25. results.append(keyword)  
  26. return results  
  27. # 3. PositionRank 
  28. def position_rank_extractor(text): 
  29. ""
  30. Uses PositionRank to extract the top 5 keywords from a text 
  31. Arguments: text (str) 
  32. Returns: list of keywords (list) 
  33. ""
  34. # define the valid Part-of-Speeches to occur in the graph 
  35. pos = {'NOUN''PROPN''ADJ''ADV'
  36. extractor = pke.unsupervised.PositionRank() 
  37. extractor.load_document(text, language='en'
  38. extractor.candidate_selection(pos=pos, maximum_word_number=5) 
  39. # 4. weight the candidates using the sum of their word's scores that are 
  40. # computed using random walk biaised with the position of the words 
  41. in the document. In the graph, nodes are words (nouns and 
  42. # adjectives only) that are connected if they occur in a window of 
  43. # 3 words. 
  44. extractor.candidate_weighting(window=3, pos=pos) 
  45. # 5. get the 5-highest scored candidates as keyphrases 
  46. keyphrases = extractor.get_n_best(n=5) 
  47. results = [] 
  48. for scored_keywords in keyphrases: 
  49. for keyword in scored_keywords: 
  50. if isinstance(keyword, str): 
  51. results.append(keyword)  
  52. return results  
  53. # 4. SingleRank 
  54. def single_rank_extractor(text): 
  55. ""
  56. Uses SingleRank to extract the top 5 keywords from a text 
  57. Arguments: text (str) 
  58. Returns: list of keywords (list) 
  59. ""
  60. pos = {'NOUN''PROPN''ADJ''ADV'
  61. extractor = pke.unsupervised.SingleRank() 
  62. extractor.load_document(text, language='en'
  63. extractor.candidate_selection(pos=pos) 
  64. extractor.candidate_weighting(window=3, pos=pos) 
  65. keyphrases = extractor.get_n_best(n=5) 
  66. results = [] 
  67. for scored_keywords in keyphrases: 
  68. for keyword in scored_keywords: 
  69. if isinstance(keyword, str): 
  70. results.append(keyword)  
  71. return results  
  72. # 5. MultipartiteRank 
  73. def multipartite_rank_extractor(text): 
  74. ""
  75. Uses MultipartiteRank to extract the top 5 keywords from a text 
  76. Arguments: text (str) 
  77. Returns: list of keywords (list) 
  78. ""
  79. extractor = pke.unsupervised.MultipartiteRank() 
  80. extractor.load_document(text, language='en'
  81. pos = {'NOUN''PROPN''ADJ''ADV'
  82. extractor.candidate_selection(pos=pos) 
  83. # 4. build the Multipartite graph and rank candidates using random walk, 
  84. # alpha controls the weight adjustment mechanism, see TopicRank for 
  85. # threshold/method parameters. 
  86. extractor.candidate_weighting(alpha=1.1, threshold=0.74, method='average'
  87. keyphrases = extractor.get_n_best(n=5) 
  88. results = [] 
  89. for scored_keywords in keyphrases: 
  90. for keyword in scored_keywords: 
  91. if isinstance(keyword, str): 
  92. results.append(keyword)  
  93. return results 
  94. # 6. TopicRank 
  95. def topic_rank_extractor(text): 
  96. ""
  97. Uses TopicRank to extract the top 5 keywords from a text 
  98. Arguments: text (str) 
  99. Returns: list of keywords (list) 
  100. ""
  101. extractor = pke.unsupervised.TopicRank() 
  102. extractor.load_document(text, language='en'
  103. pos = {'NOUN''PROPN''ADJ''ADV'
  104. extractor.candidate_selection(pos=pos) 
  105. extractor.candidate_weighting() 
  106. keyphrases = extractor.get_n_best(n=5) 
  107. results = [] 
  108. for scored_keywords in keyphrases: 
  109. for keyword in scored_keywords: 
  110. if isinstance(keyword, str): 
  111. results.append(keyword)  
  112. return results 
  113. # 7. KeyBERT 
  114. def keybert_extractor(text): 
  115. ""
  116. Uses KeyBERT to extract the top 5 keywords from a text 
  117. Arguments: text (str) 
  118. Returns: list of keywords (list) 
  119. ""
  120. keywords = bert.extract_keywords(text, keyphrase_ngram_range=(3, 5), stop_words="english", top_n=5) 
  121. results = [] 
  122. for scored_keywords in keywords: 
  123. for keyword in scored_keywords: 
  124. if isinstance(keyword, str): 
  125. results.append(keyword) 
  126. return results 

 

每個提取器將文本作為參數(shù)輸入并返回一個關鍵字列表。對于使用來講非常簡單。

注意:由于某些原因,我不能在函數(shù)之外初始化所有提取器對象。每當我這樣做時,TopicRank和MultiPartiteRank都會拋出錯誤。就性能而言,這并不完美,但基準測試仍然可以完成。

 

Python中7種主要關鍵詞提取算法的基準測試

 

我們已經通過傳遞 pos = {'NOUN', 'PROPN', 'ADJ', 'ADV'} 來限制一些可接受的語法模式——這與 Spacy 一起將確保幾乎所有的關鍵字都是從人類語言視角來選擇的。 我們還希望關鍵字包含三個單詞,只是為了有更具體的關鍵字并避免過于籠統(tǒng)。

從整個語料庫中提取關鍵字

現(xiàn)在讓我們定義一個函數(shù),該函數(shù)將在輸出一些信息的同時將單個提取器應用于整個語料庫。

 

  1. def extract_keywords_from_corpus(extractor, corpus): 
  2. """This function uses an extractor to retrieve keywords from a list of documents""" 
  3. extractor_name = extractor.__name__.replace("_extractor"""
  4. logging.info(f"Starting keyword extraction with {extractor_name}"
  5. corpus_kws = {} 
  6. start = time.time() 
  7. # logging.info(f"Timer initiated.") <-- uncomment this if you want to output start of timer 
  8. for idx, text in tqdm(enumerate(corpus), desc="Extracting keywords from corpus..."): 
  9. corpus_kws[idx] = extractor(text) 
  10. end = time.time() 
  11. # logging.info(f"Timer stopped.") <-- uncomment this if you want to output end of timer 
  12. elapsed = time.strftime("%H:%M:%S"time.gmtime(end - start)) 
  13. logging.info(f"Time elapsed: {elapsed}"
  14.  
  15. return {"algorithm": extractor.__name__,  
  16. "corpus_kws": corpus_kws,  
  17. "elapsed_time": elapsed} 

 

這個函數(shù)所做的就是將傳入的提取器數(shù)據(jù)和一系列有用的信息組合成一個字典(比如執(zhí)行任務花費了多少時間)來方便我們后續(xù)生成報告。

語法匹配函數(shù)

這個函數(shù)確保提取器返回的關鍵字始終(幾乎?)意義。 例如,

 

Python中7種主要關鍵詞提取算法的基準測試

 

我們可以清楚地了解到,前三個關鍵字可以獨立存在,它們完全是有意義的。我們不需要更多信息來理解關鍵詞的含義,但是第四個就毫無任何意義,所以需要盡量避免這種情況。

Spacy 與 Matcher 對象可以幫助我們做到這一點。 我們將定義一個匹配函數(shù),它接受一個關鍵字,如果定義的模式匹配,則返回 True 或 False。

 

  1. def match(keyword): 
  2. """This function checks if a list of keywords match a certain POS pattern""" 
  3. patterns = [ 
  4. [{'POS''PROPN'}, {'POS''VERB'}, {'POS''VERB'}], 
  5. [{'POS''NOUN'}, {'POS''VERB'}, {'POS''NOUN'}], 
  6. [{'POS''VERB'}, {'POS''NOUN'}], 
  7. [{'POS''ADJ'}, {'POS''ADJ'}, {'POS''NOUN'}],  
  8. [{'POS''NOUN'}, {'POS''VERB'}], 
  9. [{'POS''PROPN'}, {'POS''PROPN'}, {'POS''PROPN'}], 
  10. [{'POS''PROPN'}, {'POS''PROPN'}, {'POS''NOUN'}], 
  11. [{'POS''ADJ'}, {'POS''NOUN'}], 
  12. [{'POS''ADJ'}, {'POS''NOUN'}, {'POS''NOUN'}, {'POS''NOUN'}], 
  13. [{'POS''PROPN'}, {'POS''PROPN'}, {'POS''PROPN'}, {'POS''ADV'}, {'POS''PROPN'}], 
  14. [{'POS''PROPN'}, {'POS''PROPN'}, {'POS''PROPN'}, {'POS''VERB'}], 
  15. [{'POS''PROPN'}, {'POS''PROPN'}], 
  16. [{'POS''NOUN'}, {'POS''NOUN'}], 
  17. [{'POS''ADJ'}, {'POS''PROPN'}], 
  18. [{'POS''PROPN'}, {'POS''ADP'}, {'POS''PROPN'}], 
  19. [{'POS''PROPN'}, {'POS''ADJ'}, {'POS''NOUN'}], 
  20. [{'POS''PROPN'}, {'POS''VERB'}, {'POS''NOUN'}], 
  21. [{'POS''NOUN'}, {'POS''ADP'}, {'POS''NOUN'}], 
  22. [{'POS''PROPN'}, {'POS''NOUN'}, {'POS''PROPN'}], 
  23. [{'POS''VERB'}, {'POS''ADV'}], 
  24. [{'POS''PROPN'}, {'POS''NOUN'}], 
  25. matcher = Matcher(nlp.vocab) 
  26. matcher.add("pos-matcher", patterns) 
  27. create spacy object 
  28. doc = nlp(keyword) 
  29. # iterate through the matches 
  30. matches = matcher(doc) 
  31. # if matches is not empty, it means that it has found at least a match 
  32. if len(matches) > 0: 
  33. return True 
  34. return False 

 

基準測試函數(shù)

我們馬上就要完成了。 這是啟動腳本和收集結果之前的最后一步。

我們將定義一個基準測試函數(shù),它接收我們的語料庫和一個布爾值,用于對我們的數(shù)據(jù)進行打亂。 對于每個提取器,它調用

extract_keywords_from_corpus 函數(shù)返回一個包含該提取器結果的字典。 我們將該值存儲在列表中。

對于列表中的每個算法,我們計算

  • 平均提取關鍵詞數(shù)
  • 匹配關鍵字的平均數(shù)量
  • 計算一個分數(shù)表示找到的平均匹配數(shù)除以執(zhí)行操作所花費的時間

我們將所有數(shù)據(jù)存儲在 Pandas DataFrame 中,然后將其導出為 .csv。

 

  1. def get_sec(time_str): 
  2. """Get seconds from time.""" 
  3. h, m, s = time_str.split(':'
  4. return int(h) * 3600 + int(m) * 60 + int(s) 
  5. def benchmark(corpus, shuffle=True): 
  6. """This function runs the benchmark for the keyword extraction algorithms""" 
  7. logging.info("Starting benchmark...\n"
  8.  
  9. # Shuffle the corpus 
  10. if shuffle: 
  11. random.shuffle(corpus) 
  12. # extract keywords from corpus 
  13. results = [] 
  14. extractors = [ 
  15. rake_extractor,  
  16. yake_extractor,  
  17. topic_rank_extractor,  
  18. position_rank_extractor, 
  19. single_rank_extractor, 
  20. multipartite_rank_extractor, 
  21. keybert_extractor, 
  22. for extractor in extractors: 
  23. result = extract_keywords_from_corpus(extractor, corpus) 
  24. results.append(result) 
  25. # compute average number of extracted keywords 
  26. for result in results: 
  27. len_of_kw_list = [] 
  28. for kws in result["corpus_kws"].values(): 
  29. len_of_kw_list.append(len(kws)) 
  30. result["avg_keywords_per_document"] = np.mean(len_of_kw_list) 
  31. # match keywords 
  32. for result in results: 
  33. for idx, kws in result["corpus_kws"].items(): 
  34. match_results = [] 
  35. for kw in kws: 
  36. match_results.append(match(kw)) 
  37. result["corpus_kws"][idx] = match_results 
  38. # compute average number of matched keywords 
  39. for result in results: 
  40. len_of_matching_kws_list = [] 
  41. for idx, kws in result["corpus_kws"].items(): 
  42. len_of_matching_kws_list.append(len([kw for kw in kws if kw])) 
  43. result["avg_matched_keywords_per_document"] = np.mean(len_of_matching_kws_list) 
  44. # compute average percentange of matching keywords, round 2 decimals 
  45. result["avg_percentage_matched_keywords"] = round(result["avg_matched_keywords_per_document"] / result["avg_keywords_per_document"], 2) 
  46.  
  47. create score based on the avg percentage of matched keywords divided by time elapsed (in seconds) 
  48. for result in results: 
  49. elapsed_seconds = get_sec(result["elapsed_time"]) + 0.1 
  50. # weigh the score based on the time elapsed 
  51. result["performance_score"] = round(result["avg_matched_keywords_per_document"] / elapsed_seconds, 2) 
  52.  
  53. delete corpus_kw 
  54. for result in results: 
  55. del result["corpus_kws"
  56. create results dataframe 
  57. df = pd.DataFrame(results) 
  58. df.to_csv("results.csv"index=False
  59. logging.info("Benchmark finished. Results saved to results.csv"
  60. return df 

 

結果

 

  1. results = benchmark(texts[:2000], shuffle=True

 

Python中7種主要關鍵詞提取算法的基準測試

 

下面是產生的報告

 

Python中7種主要關鍵詞提取算法的基準測試

 

我們可視化一下:

 

Python中7種主要關鍵詞提取算法的基準測試

 

根據(jù)我們定義的得分公式(

avg_matched_keywords_per_document/time_elapsed_in_seconds), Rake 在 2 秒內處理 2000 個文檔,盡管準確度不如 KeyBERT,但時間因素使其獲勝。

如果我們只考慮準確性,計算為

avg_matched_keywords_per_document 和 avg_keywords_per_document 之間的比率,我們得到這些結果

 

Python中7種主要關鍵詞提取算法的基準測試

 

從準確性的角度來看,Rake 的表現(xiàn)也相當不錯。如果我們不考慮時間的話,KeyBERT 肯定會成為最準確、最有意義關鍵字提取的算法。Rake 雖然在準確度上排第二,但是差了一大截。

 

如果需要準確性,KeyBERT 肯定是首選,如果要求速度的話Rake肯定是首選,因為他的速度塊,準確率也算能接受吧。

 

責任編輯:華軒 來源: 今日頭條
相關推薦

2023-07-03 12:47:01

2010-08-31 10:57:36

2011-03-24 14:45:48

2020-07-23 10:20:28

物聯(lián)網工業(yè)物聯(lián)網技術

2011-06-20 14:32:59

關鍵詞

2011-06-07 18:45:41

關鍵詞

2024-06-13 09:05:12

2018-02-07 16:38:27

算法自然語言文本

2011-06-14 19:11:38

關鍵詞

2011-06-21 16:48:21

關鍵詞SEO

2011-06-24 17:01:44

關鍵詞

2011-06-16 17:25:45

關鍵詞

2011-06-22 18:19:40

2013-08-26 15:43:40

AppStore關鍵詞開發(fā)者應用選取關鍵詞

2011-06-19 12:20:47

長尾關鍵詞

2011-06-14 10:01:03

長尾關鍵詞

2025-05-13 08:20:58

2015-12-21 09:50:07

2020-08-27 07:00:00

游戲游戲測試測試技術

2019-12-22 13:48:26

退休科技行業(yè)大佬
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲精品乱码久久久久久按摩观 | 成年人精品视频 | 日韩国产在线观看 | 在线成人 | 日韩欧美国产不卡 | 成年人黄色一级片 | 色天天综合 | 国产真实精品久久二三区 | 久久久久国产精品一区二区 | 欧美日韩综合一区 | 欧美天堂一区 | 婷婷福利 | 日本又色又爽又黄的大片 | 91精品欧美久久久久久久 | 日本午夜精品一区二区三区 | 国家一级黄色片 | 韩国av网站在线观看 | 草草草网站| 蜜臀久久99精品久久久久野外 | 欧美精品久久久 | 99国产精品久久久 | 欧美黑人国产人伦爽爽爽 | 天天想天天干 | 国产在线一区观看 | 国产精品久久在线 | h视频在线免费 | 精品91av | 欧美一区不卡 | 99资源站 | 草草网 | 天天操网 | 久久一 | 91精品久久久| 操网站| 国产日本精品视频 | 中文字幕在线中文 | 在线日韩 | 91av视频在线观看 | 亚洲精品一区国产精品 | 精品久久久久久亚洲综合网 | 国产激情免费视频 |