嗨嚕嗨嚕~
轉眼一個禮拜就快要過去啦!前幾天的小暖身希望大家都還吸收的順利,今天我們要談到在做 NLP(自然語言處理) 任務時,一個超級關鍵的步驟,那就是對資料進行「資料預處理」。
再談之前,先大致講一下NLP 任務會有的步驟通常就是:收集資料、對資料進行預處理、建模、執行任務、評估模型成效。
我們為什麼需要先處理資料呢?
原因很簡單,有時候我們的資料可能是從網路或各種來源取得的資料,往往會充滿雜訊:例如多餘的空白、奇怪的符號、重複內容、廣告標籤,或是亂碼、網址等,如果我們直接把這些「髒資料」丟給模型訓練,不但會增加運算負擔,還可能讓模型學到錯誤的規律。
而這些資料根據我們的任務不同,所需要的資料樣子也會有所不同。舉例來說,今天你可能想要做的是對社群媒體貼文的情緒偵測,這時候你的資料裡面的驚嘆號可能就需要留者,畢竟驚嘆號可能與代表某種情緒,因此需要被保留。但如果你今天的目的不是要做情緒偵測,那這些驚嘆號可能對你來說,就是不必要的資訊。
所以,在進行任何 NLP 任務之前,了解自己的目的進行資料預處理,是絕對必要的ㄧ環!
而在資料預處理的過程中,我們通常會用正規表達式 (Regular Expression)來清洗資料中不必要的訊息,所以今天的重點就是要來和大家介紹講解正規表達式拉!
簡單來說,正規表達式就是一個能幫我們快速地「搜尋、篩選、替換」特定的字串模式的工具,
這邊先列幾個常見的符號:
符號 | 意義 | 範例 | 說明 |
---|---|---|---|
. |
任意字元 | a.c |
可以匹配 abc 、a-c 、a0c 等 |
\d |
一個數字 (0–9) | \d\d |
會找到兩位數,例如 12 |
\w |
英文、數字或底線 | \w+ |
找出一串英數字,如 cat99 |
^ |
行首 | ^Hello |
找出以 Hello 開頭的行 |
$ |
行尾 | world$ |
找出以 world 結尾的行 |
* |
前一字元出現 0 次或多次 | go*gle |
匹配 ggle 、gogle 、google |
+ |
前一字元出現 1 次或多次 | \d+ |
找出連續的整數,例如 123 |
[ ] |
字元集合 | [aeiou] |
找出任何母音字元 |
{m,n} |
前一字元出現 m 到 n 次 | \d{2,4} |
找出 2–4 位數字 |
這只是其中一些些,網路上有很多cheat sheet ,大家如果忘記指令或符號的話也可以上網搜尋,這邊提供大家一個可以參考的連結:
https://www.datacamp.com/cheat-sheet/regular-expresso
python 跟 r 在處理regrex 的指令會有點不一樣,大家要注意喔!這邊是教的是python 常用的指令呦
那廢話不多說,知道regrex 在幹嘛後我們就來實作練習一下唄!
text = """
今天特價只要 NT$100!
連絡我們:contact@test.com
或撥打 0912-345-678
明天的價格可能會漲到 NT$250。
"""
假設我們今天想把這段文字的email 抓取出來,我們可以用findall
這個參數
他的語法是
re.findall(pattern, string, flags=0)
其中pattern 代表的是,你想要抓什麼東西,你的規則是什麼string
代表的是,你要從哪裡抓這些東西(以這邊來說,就是text)flags
是指額外的參數,這邊我們可以先忽略
要完成這個任務我們就可以用下面的方式抓:
import re #先把re 套件引入進來
prices = re.findall(r"NT\$[0-9]+", text)
print(prices)
#輸出結果
['NT$100', 'NT$250']
同理,我們也可以用這個方式,找出手機電話的訊息:
phones = re.findall(r"09\d{2}-\d{3}-\d{3}", text)
print(phones)
#輸出
['0912-345-678']
這段規則 09\d{2}-\d{3}-\d{3}
的意思是:09
:電話一定以 09 開頭\d{2}
:接著 2 個數字-
:然後是一個連字號 -\d{3}
:再來 3 個數字-
:再一個連字號\d{3}
:最後 3 個數字
所以任何有符合這個規則的字串都會被找到!
值得注意的是,這個規則沒有標準的正確答案,只有能不能成功抓到每一個你想要的資料樣子而已,所以大家也可以想想看還有哪些寫法可以抓到電話號碼喔!
那第二個例子,加設我今天想把text2 中的apple 全部換成banana 可以怎麼做呢?
text2 = 'I like to eat apple, she likes to eat apple, he likes to eat apple'
我們可以用sub
這個參數來執行,他是用來幫助你可以「替換掉」想替換的東西
他的語法是
re.sub(pattern, replacement, string)
其中的pattern
跟剛剛一樣代表的是規則(你想要換掉什麼東西),replacement
代表的是你想要「替換成什麼」,而最後的 string
一樣代表的是你要在哪裡執行替換的動作(以這裡來說就會是text2)
所以要完成這個任務我們就可以用下面的方式抓:
new_text = re.sub(r"apple", "banana", text2)
print(new_text)
輸出就會是:
I like to eat banana, she likes to eat banana, he likes to eat banana
這樣就完成拉~~非常低簡單,但也非常的實用!
真正在處理資料上面regrex 真的是一個非常強大的工具,但要用regrex 把資料清理的很乾淨往往會需要花費很多時間~相信大家多碰就會感覺得出來xd
這邊給大家一個小小練習題大家可以想想看:如何寫出一段可以成功抓取台灣身分證字號碼的正規表達式呢?
小提示:
大家不妨拿起電腦試試看,有練習絕對有差!
好拉~那我們今天就到這裡,希望大家有所收穫!
我們就明天見~