歡迎光臨
每天分享高質量文章

黑科技 | 用Python只花十五分鐘完成正則運算式五天任務量

資料清理是很多機器學習任務上我們遇到的首要問題。本文介紹的 FastText 是一個開源 Python 庫,可用於快速進行大規模語料庫的文字搜尋與替換。該專案的作者表示,使用正則運算式(Regex)需要 5 天的任務在新的方法中只需要 15 分鐘即可完成。

專案連結:https://github.com/vi3k6i5/flashtext

自然語言處理領域的開發者在處理文字之前必須對資料進行清理。有些時候,此類工作是由關鍵詞替換完成的,就像吧「Javascript」替換成「JavaScript」。另一些時候,我們只需要知道檔案中是否提到了「JavaScript」。

這類資料清理任務是大多數處理文字的資料科學專案必須要做的。

資料科學從清理資料開始

本文作者是 Belong.co 的一名資料科學家,需要從事有關自然語言處理的工作,於是遇到了這個問題。當我在自己的檔案語料庫中開始訓練 Word2Vec 模型時,它開始將同義詞歸為同類項,「Javascripting」被歸類為「JavaScript」的同類項。

為瞭解決這個問題,我寫了一個正則運算式(Regex),用標準化命名來替換所有已知的同義詞。Regex 會將「Javascripting」替換為「JavaScript」,這解決了一個問題,卻又帶來了另一個問題。

有些人遇到問題時會想:「沒關係,我們有正則運算式。」現在問題變成了兩個。

上文所述引自 Stack-exchange question,現在讓我遇到了。

事實證明,正則運算式的速度很快——如果要搜尋和替換的關鍵詞數量是一百多個的話。但是面對超過 20k 個關鍵詞,300 萬個檔案的語料庫,事情就會變得很糟。當我測試我的程式碼時,我發現完全執行需要 5 天之久。

通常,面對這種情況我們的解決方案是並行運算。但在面對上千萬個檔案中成百上千出現頻次的關鍵詞,並行的效能提升有限,我們必須找到更好的方法!

幸好,在 Stack Overflow 上我的疑問獲得了大家的關註,網友們和公司同事 Vinay Pandey、Suresh Lakshmanan 等人提到了一個名叫 Aho-Corasick 演演算法的神奇工具,以及字首樹資料結構(Trie Data Structure)。然而目前網路上還缺乏相關資源。

  • Aho-Corasick 演演算法:https://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_algorithm

  • Trie Data Structure:https://en.wikipedia.org/wiki/Trie

所以我開始自己動手,FlashText 誕生了。

在介紹 FlashText 的結構和工作原理之前,先看看它的搜尋效能表現:

下麵的紅線是 FlashText 的搜尋耗時

如上圖所示,Regex 演演算法和 FlashText 搜尋同一篇檔案的耗時相差很大。隨著關鍵詞數量的增加,Regex 的耗時呈線性增長,而對於 FlashText 來說並沒有影響。

FlashText 可以把 5 天的工作縮短到 15 分鐘!

這是 FlashText 替換的速度:

同樣,下麵的紅線是 FlashText 的替換速度。

所以,FlashText 是什麼?

FlashText 是我在 GitHub 上開源的一個 Python 庫,它能高效地提取和替換關鍵詞。

使用 FlashText 時,首先你需要傳送一系列關鍵詞,這個串列將被用於在內部建立一個字首樹字典。隨後你需要傳遞一個字串,告訴它你需要執行替換還是搜尋。

在替換時,它會建立一個新字串來替換關鍵詞。在搜尋時,它會傳回一個關鍵詞串列。這一切都將在輸入字串上進行。

有的使用者是這樣評價FastText的:

Radim Řehůřek 是著名 Python 庫 Gensim 的作者

FlashText 為什麼那麼快?

我們用一個例子來嘗試和理解這一部分。假設我們有一個包含三個單詞的句子 I like Python,和一個有四個單詞的語料庫 {Python,Java,J2ee,Ruby}。

如果每次取出語料庫中的一個單詞,並檢查其在句子中是否出現,這需要四次操作。

  1. is 'Python' in sentence?

  2. is 'Java' in sentence?

  3. ...

如果語料庫有 n 個單詞,意味著需要做 n 次的迴圈操作,並且每一個時間步的搜尋都是 isin sentence ? 這有點像正則表示式相配(Regex match)中的過程。

還有另一種和第一種相反的方法。對於句子中的每一個單詞,檢查其是否在語料庫中出現。

  1. is 'I' in corpus?

  2. is 'like' in corpus?

  3. is 'python' in corpus?

如果句子 m 個單詞,意味著需要做 m 次的迴圈操作。在這個例子中所需的時間步取決於句子中的單詞數。而使用字典查詢進行 isin corpus ? 會快得多。

FlashText 基於第二種方法,由 Aho-Corasick 演演算法和字首樹(Trie)資料結構所啟發。

它的工作方式為:

首先由語料庫建立一個如下圖所示的字首樹字典:

語料庫的字首樹字典

Start 和 EOT(End Of Term,期末)表示單詞的邊界比如 space、period 和 new_line。只有兩側都有邊界的關鍵詞才能得到匹配,這可以防止把 apple 匹配到 pineapple。

下一步我們將取輸入字串為 I like Python,並按字元逐個對齊進行搜尋。

  1. Step 1: is Iin dictionary? No

  2. Step 2: is likein dictionary? No

  3. Step 3: is Pythonin dictionary? Yes

Python出現在字典中。

由於這是一個字元匹配過程,我們可以輕易地在進行到l 的時候跳過整個like,因為 start 並沒有和 l 相連。這使得跳過缺失單詞的過程變得非常快。

FlashText 演演算法只需要遍歷輸入字串『I like Python』的每一個字元。即使字典有上百萬個關鍵詞,對執行時間也沒有任何影響。這是 FlashText 演演算法的真正威力。

什麼時候需要使用 FlashText?

簡單的回答是:當關鍵詞數量>500 的時候

當關鍵詞數量>500 的時候,FlashText 的搜尋速度開始超過 Regex

完整的回答是:Regex 可以搜尋基於特殊字元比如^、$、*、d 等的關鍵詞,而 FlashText 不支援這種搜尋。

所以如果想要匹配部分單詞比如『worddvec』,使用 FlashText 並沒有好處,但其非常善於提取完整的單詞比如『word2vec』。

用於尋找關鍵詞的程式碼

  1. # pip install flashtext

  2. from flashtext.keyword import KeywordProcessor

  3. keyword_processor = KeywordProcessor()

  4. keyword_processor.add_keyword('Big Apple', 'New York')

  5. keyword_processor.add_keyword('Bay Area')

  6. keywords_found = keyword_processor.extract_keywords('I love Big Apple and Bay Area.')

  7. keywords_found

  8. # ['New York', 'Bay Area']

使用 FlashText 提取關鍵詞的簡單例子

用於替換關鍵詞的程式碼

FlashText 不僅可以提取句子中的關鍵詞還可以對其進行替換。我們將此作為資料處理管道的資料清理步驟。

  1. from flashtext.keyword import KeywordProcessor

  2. keyword_processor = KeywordProcessor()

  3. keyword_processor.add_keyword('Big Apple', 'New York')

  4. keyword_processor.add_keyword('New Delhi', 'NCR region')

  5. new_sentence = keyword_processor.replace_keywords('I love Big Apple and new delhi.')

  6. new_sentence

  7. # 'I love New York and NCR region.'

使用 FlashText 替換關鍵詞的簡單例子

原文連結:https://medium.freecodecamp.org/regex-was-taking-5-days-flashtext-does-it-in-15-minutes-55f04411025f

本文轉載自微信公眾號:機器之心




————近期開班————

馬哥聯合BAT、豆瓣等一線網際網路Python開發達人,根據目前企業需求的Python開發人才進行了深度定製,加入了大量一線網際網路公司:大眾點評、餓了麼、騰訊等生產環境真是專案,課程由淺入深,從Python基礎到Python高階,讓你融匯貫通Python基礎理論,手把手教學讓你具備Python自動化開發需要的前端介面開發、Web框架、大監控系統、CMDB系統、認證堡壘機、自動化流程平臺六大實戰能力,讓你從0開始蛻變成Hold住年薪20萬的Python自動化開發人才

10期面授班:2018年03月05號(北京)

09期網路班:騰訊課堂隨到隨學網路

掃描二維碼領取學習資料

更多Python好文請點選【閱讀原文】哦

↓↓↓

贊(0)

分享創造快樂

© 2024 知識星球   網站地圖