前言
对于大规模数据,我们经常会使用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)