工程架构
- 配置
congfig
- 常量
constant
- 计时器
timer
- 数据可视化
visualize
- 日志
log
- 常量
- 语料库
corpora
- 训练数据
train_data
- 词库
dictionary
- 训练数据
- 文本处理
processing
- 清洗
clean
- 文本切割
cutter
- 分句
clause
- 分词
word
- 词性标注
flag
- 分句
- 清洗
- 模型
model
- 专家系统
expert_system
- 机器学习
machine_learning
- 有监督模型
supervised
- 逻辑回归
logistic_regression
- 朴素贝叶斯
naive_bayes
- 逻辑回归
- 向量化
vectorization
- TF-IDF
tfidf
- 词向量
word2vector
- TF-IDF
- 有监督模型
- 深度学习
deep_learning
- 卷积神经网络
cnn
- 循环神经网络
rnn
- 卷积神经网络
- 专家系统
- 应用
application
- 命名实体识别
ner
- 文本分类
classification
- 统计分析
statistic
- 命名实体识别
项目流程
语料库构建
词库构建
- 词库获取
- 通用词库:jieba、nltk
- 公司内部数据库:各种专用名词、字段名…
- 网上整理:科技、农业、体育、政治…
- 功能词库(停词、情感词、量词…)
- 爬虫或网购:行政区划、电影名、公司名…
- 新词
- 词分类
训练数据
- 内部数据
- 数据库、日志文件
- 工作报告(PPT、WORD、EXCEL)
- 外部数据
- 购买
- 爬虫获取
- 网络资源
- 数据增强
- 统计语言模型生成
- 短文本生成(基于统计)
- 标注
- 自带标注
- 人工标注
- 算法标注
数据处理
清洗
- 特殊符号处理
def replace_punctuation(text):
"""替换标点(英→中)"""
text = text.replace('(', '(').replace(')', ')') # 圆括号
text = text.replace('【', '(').replace('】', ')') # 方括号(之后用于关键词高亮)
text = replace_empty_bracket(text) # 空括号
text = re.sub('[;;]+', ';', text) # 分号
text = re.sub('[!!]+', '!', text) # 叹号
text = re.sub('[??]+', '?', text) # 问号
text = re.sub('[.]{3,}|,{3,}|。{3,}|,{3,}|…+', '…', text) # 省略号
text = text.replace("'", '"') # 引号
text = re.sub('(?<=[\u4e00-\u9fa5]),(?=[\u4e00-\u9fa5])', ',', text) # 逗号
text = re.sub('(?<=[\u4e00-\u9fa5])[.](?=[\u4e00-\u9fa5])', '。', text) # 句号
return text.strip().lower() # 转小写
def replace_space(text):
"""清除连续空白"""
text = re.sub('\s*\n\s*', '\n', text.strip())
text = re.sub('[ \f\r\t ]+', ' ', text)
text = re.sub('([\u4e00-\u9fa5]) ([^\u4e00-\u9fa5])', lambda x: x.group(1)+x.group(2), text)
text = re.sub('([^\u4e00-\u9fa5]) ([\u4e00-\u9fa5])', lambda x: x.group(1)+x.group(2), text)
return text
- 过滤
- 停词
- 低频词(减少维度 以 提高程序效率)
- 替换(或离散化)
- 数量词:时间、长度、重量……
- 实体统一:公司名、地名……
- 近义词(如:番茄≈西红柿)
- 筛选
- 按词性
- 按长度
文本切割
切句
sep10 = re.compile('[\n。…;;]+|(?<=[\u4e00-\u9fa5])[.]+(?=[\u4e00-\u9fa5])').split
sep15 = re.compile('[\n。…;;!!??]+|(?<=[a-z\u4e00-\u9fa5])[.]+(?=[a-z\u4e00-\u9fa5])', re.I).split
sep20 = re.compile('[!!??]+').split
sep30 = re.compile('[,,::]+').split
sep40 = re.compile('\W+').split # 非中英文数字下划线
sep45 = re.compile('[^a-zA-Z\u4e00-\u9fa5]+').split # 非中英文
分词
jiaba、nltk、ltp、foolnltk……
特征工程
- 词性
- 通用词性(jieba词性)
- 领域属性:公司名、电影名、地名……
- 功能属性:情感词、程度词、否定词、数量词、词根……
- 拼音特征
- 文本向量化
- TF-IDF、textrank权重
- word2vector
- Glove: Global Vectors for Word Representation
- 共现矩阵+SVD
- 句子特征
- 统计特征
模型
极简常用示例代码
TF-IDF向量化+逻辑回归
from jieba import cut
from sklearn.linear_model import LogisticRegression
from sklearn.feature_extraction.text import TfidfVectorizer
"""语料"""
texts = [
'三个只有一个是新鲜的,其它两个都坏了,买得最差的一次水果',
'京东,才发现你是个骗子,服务更是一样的烂',
'火龙果很小,而且还有一个烂了,发霉了',
'物流慢,收到时有两个底部已开始腐烂',
'屏幕清晰度不高,而且运行速度巨慢',
'贝质量很好,款式时尚,大小合适,做工精致,穿着舒服,服务很好',
'质量很好的,款式也不错,看起来高档大气,卖家服务还好,不错',
'裤子收到了,质量不错,价格便宜,穿着舒服,下次我还会来买的',
'宝贝收到了,试了一下,穿上挺舒服的,是正品,综合给好评',
'裤子挺好看,质量也不错,老公搭配衣服挺好看也很喜欢穿',
]
y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
"""向量转换器"""
vectorizer = TfidfVectorizer(tokenizer=cut, stop_words=set('的在了是和也有为就都说等与才这,'))
X = vectorizer.fit_transform(texts)
"""分类模型"""
clf = LogisticRegression()
clf.fit(X, y)
print(clf.score(X, y))
应用
- 文本分类(篇章级、句级、实体级)
- 文本聚类(篇章级、实体级)
- 新主题抽取及归类
- 信息抽取
- 关键词抽取、专名识别
- 公司名、人名、医学名词……
- 关系抽取
- 投资关系、词组搭配关系
- 文本摘要
- 关键词抽取、专名识别
- 统计分析
- 词频、词组频
经验总结
-
项目思维
-
评估项目难度:跑一个简单模型,看看差多少
模型选择:优先使用 简单模型和 有监督模型,然后逐步优化
常用方法如 频数统计、 逻辑回归等;基于统计,寻找语料特征,迭代语料
尽快了解业务,公司数据库本身就已经存在很多重要语料了
数据才是王道
-
词库要求精准;带标签的数据要求精准且足量
快速迭代词库和语料:必须 人工+业务,并利用 算法和 可视化辅助
数据清洗占据大量时间,Pycharm的正则表达式功能非常好用!
常用可视化技术
-
文本可视化:
关键词高亮
数据可视化:条形图(简单直接)
个人积累
-
除了积累算法,还要
积累数据(词库、正则表达式、带标签语料、结构化数据)
优先积累通用的体量小的数据:停词、情感词、地区+经纬度、文本清洗正则表达式…
NLP与业务高度挂钩,选择一个自己喜欢的业务,深入学下去
测试
- 功能测试、性能测试、数据校验(数据量、准确率、缺失率…) 数据量过大时
- 用 Spark