前言
對于大規模數據,我們經常會使用python內置函數或者編寫腳本進行批量化處理,從而提高后續使用算法的效率。
1. 正則表達式
- 定義:用于檢索、替換符合某個模式的文本,是文本預處理常用技術。
- 基本語法
符號 | 描述 |
---|---|
. | 匹配除換行符?\n ?以外的任意單個字符 |
\w | 匹配單個字母數字字符 |
\W | 匹配單個非字母數字字符 |
\d | 匹配單個數字 |
\D | 匹配單個非數字 |
\s | 匹配單個空格字符(空格、換行符、返回符、制表符等) |
\S | 匹配任何非空格字符 |
\t | 匹配單個 tab 符 |
\n | 匹配單個換行符 |
\r | 匹配單個回車符 |
^ | 匹配字符串的開頭 |
$ | 匹配字符串的結尾 |
[..] | 匹配方括號中指定的字符 |
[^..] | 匹配方括號中指定以外的任何字符 |
{m,n} | 匹配前一個字符的出現次數在 m 至 n 次之間 |
a|b | 匹配a或b |
? | 匹配前一個字符出現 0 或 1 次 |
+ | 匹配前一個字符出現 1 次或多次 |
* | 匹配前一個字符出現 0 次或多次 |
\ | 轉義字符,用于將被占用為正則表達的符號還原為原來的意思 |
() | 被括起來的表達式部分將作為分組,并返回相匹配的文本 |
- Python 的?
re
?模塊re.match()
:從字符串首字符開始匹配模式串。
import re result = re.match(r'Hello', 'Hello, World!') if result:print("匹配成功,匹配到的內容是:", result.group()) else:print("匹配失敗")
re.search()
:從字符串任意位置匹配模式串,找到第一個匹配即返回。
result = re.search(r'World', 'Hello, World!') if result:print("匹配成功,匹配到的內容是:", result.group()) else:print("匹配失敗")
re.findall()
:從字符串任意位置匹配模式串,返回所有匹配結果。
text = "Apple and banana are fruits. I like apple juice." result = re.findall(r'apple', text, re.IGNORECASE) print("匹配到的所有結果:", result)
re.sub()
:將字符串中匹配模式串的部分替換為指定內容。
text = "I have 3 apples and 2 bananas." new_text = re.sub(r'\d', 'X', text) print("替換后的文本:", new_text)
2. 分詞
- 定義:將長文本分解為以詞為基本單位的數據結構,方便后續處理分析。
- 中文分詞難點
- 沒有統一標準,存在分詞歧義性。
- 歧義詞難以切分,需結合上下文判斷。
- 未登錄詞難以識別,需實時更新詞表。
- 分詞方法
- 基于詞典的匹配分詞方式:速度快、成本低,但適應性不強。
- 基于統計的分詞方法:適應性較強,但成本高、速度慢。
- 基于深度學習:準確率高、適應性強,但成本高、速度慢。
- 常見分詞工具:Hanlp、Stanford 分詞、ansj 分詞器、哈工大 LTP、KCWS 分詞器、jieba、清華大學 THULAC、ICTCLAS。
jieba
?分詞示例- 全模式:
jieba.cut("文本", cut_all=True)
import jieba seg_list = jieba.cut("我喜歡自然語言處理", cut_all=True) print("全模式分詞結果: ", "/ ".join(seg_list))
- 精確模式:
jieba.cut("文本", cut_all=False)
seg_list = jieba.cut("我喜歡自然語言處理", cut_all=False) print("精確模式分詞結果: ", "/ ".join(seg_list))
- 搜索引擎模式:
jieba.cut_for_search("文本")
seg_list = jieba.cut_for_search("小明碩士畢業于中國科學院計算所") print("搜索引擎模式分詞結果: ", ", ".join(seg_list))
- 添加新詞:
jieba.load_userdict(file_path)
;動態添加:jieba.add_word(word, freq=None, tag=None)
;動態刪除:jieba.del_word(word)
jieba.add_word("自然語言處理") seg_list = jieba.cut("我喜歡自然語言處理", cut_all=False) print("添加新詞后精確模式分詞結果: ", "/ ".join(seg_list)) jieba.del_word("自然語言處理") seg_list = jieba.cut("我喜歡自然語言處理", cut_all=False) print("刪除新詞后精確模式分詞結果: ", "/ ".join(seg_list))
- 全模式:
3. 詞性標注
- 定義:判定文本中每個詞的語法范疇,確定其詞性并加以標注。
- 中文詞性標注難點:中文缺乏詞形態變化,兼類詞現象嚴重,詞類歧義排除任務量大。
- 詞性標注方法
- 基于規則的詞性標注方法。
- 基于統計模型的詞性標注方法,如 HMM、CRF 等。
- 基于統計方法與規則方法相結合的詞性標注方法。
- 基于深度學習的詞性標注方法,如 LSTM+CRF、BiLSTM+CRF 等。
- 常見詞性標注工具:jieba、SnowNLP、THULAC、StanfordCoreNLP、HanLP、NLTK、SpaCy(不支持中文)。
jieba
?詞性標注示例:jieba.posseg.cut("文本")
import jieba.posseg sentence_taged = jieba.posseg.cut("我喜歡自然語言處理") for word, flag in sentence_taged:print(f"詞語: {word}, 詞性: {flag}")
4. 詞干提取與詞形還原
- 詞干提取(Stemming):去除單詞的前后綴得到詞根,用于擴展檢索。
from nltk.stem import PorterStemmer
stemmer = PorterStemmer()
words = ["running", "jumps", "played"]
for word in words:print(f"原詞: {word}, 詞干: {stemmer.stem(word)}")
- 詞形還原(Lemmatisation):基于詞典,將單詞的復雜形態轉變成最基礎的形態,用于文本預處理。
from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
words = ["are", "better", "running"]
for word in words:print(f"原詞: {word}, 詞形還原后: {lemmatizer.lemmatize(word)}")
- 兩者異同
- 相同點:目標類似,結果部分交叉,主流實現方法類似。
- 不同點:變換原理、算法復雜性、結果和應用領域各有側重。
- 注意事項:只針對具有形態變化的語言,中文不存在這兩種預處理操作。
5. 命名實體識別(NER)
- 定義:識別文本中具有特定意義的實體,如人名、地點名、組織機構名、時間等,用于語義挖掘及信息提取。
- NER 方法
- 基于規則的方法、基于字典的方法。
- 傳統機器學習,如 HMM、CRF 等。
- 深度學習,如 LSTM+CRF、BiLSTM+CRF 等。
- 常見 NER 工具:Stanford NER、MALLET、Hanlp、nltk、SpaCy(不支持中文)、Crfsuite。
nltk
?的 NER 示例
import nltk
from nltk.tokenize import word_tokenize
from nltk import pos_tag, ne_chunk
nltk.download('punkt')
nltk.download('averaged_perceptron_tagger')
nltk.download('maxent_ne_chunker')
nltk.download('words')text = "Bill Gates founded Microsoft in 1975."
tokens = word_tokenize(text)
tagged = pos_tag(tokens)
entities = ne_chunk(tagged)
print(entities)
6. 文本的數據增強
- 應用:解決文本數據類別不平衡問題,使模型能學習到樣本少的類別的特性。
- 字符層面數據增廣方法
- 同義詞替換:根據同義詞典或詞向量相似度替換詞匯。
- 文本回譯:將文本翻譯成某一語言再反譯回來。
- 詞匯順序變化:對某些文本在語塊層面重新排列語序。
nlpcda
?工具示例Randomword()
:隨機實體替換。
!pip install nlpcda
from nlpcda import Randomword
sentence = "今天是2024年10月1日:我去了超市"
smw = Randomword(create_num=3, change_rate=0.3)
result = smw.replace(sentence)
print('隨機實體替換結果:')
for r in result:print(r)
Similarword()
:隨機同義詞替換。
from nlpcda import Similarword
sentence = "今天天氣很好,適合出去游玩"
smw = Similarword(create_num=3, change_rate=0.8)
result = smw.replace(sentence)
print('隨機同義詞替換結果:')
for r in result:print(r)
baidu_translate()
:百度中英翻譯互轉實現增強。(需要申請 appid 和 secretKey)
from nlpcda import baidu_translatezh = '天氣晴朗,適合散步'
# 申請你的 appid、secretKey 分別填入 "xxx" 后代碼才能運行
en_s = baidu_translate(content=zh, appid='xxx',secretKey='xxx', t_from='zh', t_to='en') # 中文轉英文
zh_s = baidu_translate(content=en_s, appid='xxx',secretKey='xxx', t_from='en', t_to='zh') # 英文轉回中文
print("回譯后的文本:", zh_s)