[nlp] 小傻学数据预处理
1. 分词
1.1 分词方法
1.1.1 基于规格(词典、词库)
基于字符串匹配分词。将待分的字符串与一个充分大的机器词典中的词条进行匹配。
正向最大匹配: 对输入的句子从左至右,以贪心的方式切分出当前位置上长度最大的词,组不了词的字单独划开。其分词原理是:词的颗粒度越大,所能表示的含义越精确。
逆向最大匹配: 原理与正向最大匹配相同,但顺序不是从首字开始,而是从末字开始,而且它使用的分词词典是逆序词典,其中每个词条都按逆序方式存放。在实际处理时,先将句子进行倒排处理,生成逆序句子,然后根据逆序词典,对逆序句子用正向最大匹配。
双向最大匹配: 将正向最大匹配与逆向最大匹配组合起来,对句子使用这两种方式进行扫描切分,如果两种分词方法得到的匹配结果相同,则认为分词正确,否则,选取分词结果中单个汉字数目较少的那一组。
小结: 基于词典的分词方法简单、速度快,效果也还可以,但对歧义和新词的处理不是很好,对词典中未登录的词没法进行处理。
1.1.2 基于知识理解
该方法主要**基于句法、语法分析,并结合语义分析,通过对上下文内容所提供信息的分析对词进行定界,**它通常包括三个部分:分词子系统、句法语义子系统、总控部分。在总控部分的协调下,分词子系统可以获得有关词、句子等的句法和语义信息来对分词歧义进行判断。这类方法试图让机器具有人类的理解能力,需要使用大量的语言知识和信息。由于汉语语言知识的笼统、复杂性,难以将各种语言信息组织成机器可直接读取的形式。因此目前基于知识的分词系统还处在试验阶段。
1.1.3 基于(词频)统计
从大量已经分词的文本中,利用统计学习方法来学习词的切分规律,从而实现对未知文本的切分。随着大规模语料库的建立,基于统计的分词方法不断受到研究和发展,渐渐成为了主流。
常用的统计学习方法有:隐马尔可夫模型(HMM)、条件随机场(CRF)和基于深度学习的方法。
jieba是基于统计的分词方法,jieba分词采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合,对于未登录词,采用了基于汉字成词能力的HMM模型,使用了Viterbi算法。
**小结:**基于统计的分词方法能很好地处理歧义和新词问题,效果比基于词典的要好,但该方法需要有大量人工标注分好词的语料作为支撑,训练开销大,就分词速度而言不如前一种。
1.2 分词工具
Jieba分词 https://github.com/fxsjy/jieba
SnowNLP https://github.com/isnowfy/snownlp
LTP http://www.ltp-cloud.com/
HanNLP https://github.com/hankcs/HanLP/
1.3 jieba分词原理
jieba分词项目地址
**原理:**基于前缀词典实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图 (Directed Acyclic Graph,DAG);采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合;
对于未登录词,采用了基于汉字成词能力的 HMM 模型,使用了 Viterbi 算法。
1.3.1 前缀词典
结巴分词首先会依照结巴默认的统计词典dict.txt构造前缀词典。
dict.txt含有近35万的词条,每个词条占用一行,其中每一行有3列,第一列为词条,第二列为对应的词频,第三列为词性,构造前缀词典需要用到前两列。
具体做法为:首先定义一个空的python字典,然后遍历dict.txt的每一行,取词条作为字典的键,词频作为对应的键值,然后遍历该词条的前缀。如果前缀对应的键不在字典里,就把该前缀设为字典新的键,对应的键值设为0,如果前缀在字典里,则什么都不做。
这样等遍历完dict.txt后,前缀词典就构造好了。在构造前缀词典时,会对统计词典里所有词条的词频做一下累加,累加值等计算最大概率路径时会用到。
1.3.2 有向无环图生成
基于前缀词典,对输入文本进行切分;e.g.:
对于‘去’:没有前缀,只有一种划分方式;
对于‘北’:有‘北’,‘北京’,‘北京大学’三种划分方式;
对于‘大’:有‘大’,‘大学’两种划分方式……
依次类推,可以得到每个字开始大前缀词的划分方式。
对于0: [0],表示位置0对应的词,就是0 ~ 0,就是“去”;对于1: [1,2,4],表示位置1开始,在1,2,4位置都是词,就是1 ~ 1,1 ~ 2,1 ~ 4,即“北”,“北京”,“北京大学”这三个词。
对于每一种划分,都将相应的首尾位置相连,例如,对于位置1,可以将它与位置1、位置2、位置4相连接,最终构成一个有向无环图。
1.3.3 计算概率最大路径
在得到所有坑的切分方式构成的有向无环图后,其从起点到终点有多条路径(即多个分词结果);我们需要计算出最大概率路径,即按照这种方式切分后的分词结果的概率最大。
采用维特比算法进行计算。
对未登录词采用HMM模型进行分词
当出现没有在前缀词典里收录的词时,会采用HMM模型进行分词
结巴分词已经内置了训练好的状态初始概率、状态转移概率和状态发射概率。
句子会作为观测序列,当有新句子进来时,具体做法为:先通过Viterbi算法求出概率最大的状态序列,然后基于状态序列输出分词结果(每个字的状态为B、M、E、S之一)。(B, M, E, S): {B:begin, M:middle, E:end, S:single}
如果切出了词典中没有的词语,效果不理想,结巴里也可以关闭新词发现。
2 文本纠错
纠错是一个重要又不重要的领域。 不纠错下游工作其实也能进行,只是会影响效果、体验(例如word2vec之类大样本训练任务)。但有时候用户体验直接影响收入(如电商搜索,输入法,校对等,此时纠错又显得比较重要。)
纠错相对更偏系统工程(经常是其它nlp任务的上游,对响应速度要求较高)
2.1 why?
2.1.1
纠错场景:
输入法(拼音、英文)
通用搜索(百度、搜狗)
垂类搜索(电商、社区、图片)
智能问答
训练语料清洗
基本上凡是涉及用户输入的场景(nlp)都需要纠错
why:
文本输入(输入法): 直接影响输入体验
语义理解(搜索、对话): 直接影响(商品、候选回答等的)召回效果
数据预处理(训练样本,数仓):过脏的数据无法用来做分析和训练,虽然可以假设正确样本占多数,
校对(出版社):直接影响用户阅读理解
纠错常与分词一起,具体谁在前不一定;有分词纠错同时进行的
英文NER可以在纠错之前,中文NER一般在纠错之后
中文较少因为纠错让实体词变为非实体词
2.2 英文纠错
2.2.1 non-word, 不再词典中
编辑距离
2.2.2 real-word,用词错误
处理方法与中文相同
2.2.3 编辑距离(edit distance)
一个字符串需经过多少次变化后变为另外一个字符串,工业上一般编辑距离不超过2。
出错场景:
- 少输:hello->hllo(ed=1), hlo(ed=2)
- 多输:hello->helloo, (ed=1)
- 错输:hello->hallo, (ed=1)
- 顺序不对:hello->ehllo (ed=1or2)
处理方法:
输入字符串=s
触发条件:oov or unigram词频太低
候选词(方法一)
先尝试ed=1,
少字符(s的每个位置加入a-z)
多字符(删除s的每个字符)
错字符(把s的每个字符用a-z代替,可以基于字符位置(26键)做过滤)
顺序错(把s相临的每两个字符交换)
再试ed=2
把ed=1的每个字符串再遍历一遍ed=1的处理
不在词表的去掉
基于unigram词频去掉值太低的
BK-Tree
成立条件:
d(x,y)=0 当且仅当x=y
d(x,y)=d(y,x)
d(x,y)+d(y,z)>=d(x,z)
d(x,z)=a, d(x,y)=b, 求f=d(y,z)的范围
d(x,z)+d(z,y) >= d(x,y) => f>=b-a
d(y,x)+d(x,z) >= d(y,z) => f<=b+a
a=搜索范围、b=query与节点的距离、f=节点与子节点的距离
构造
以任一单词作为根
1. 插入时先计算与该子树节点的距离
2. 插入到该子树对应子节点下
3. 循环1、2直到成为叶子节点
查询
求与query编辑距离<=a的单词
计算query与子树根节点的距离
然后往下找出距离=[b-a,b+a]之间的子树
b=query与节点的距离
逐层往下最终到叶子节点
当a较小时有价值,较大时与遍历区别不大
候选词选择
尝试纠错
合并召回统一基于unigram排序
ed=1扣积分,ed=2扣更多分
输入为句子
计算整句但概率(ppl or lm(2gram or lstm))
选择概率最大的那个词,同样需要针对ed做降权
排序权重学习
词频、纠错排序等
用户有显式返回场景(输入法,补全框)
样本稀疏,一般针对人群
2.3 噪声通道模型
p(I)就是语言模型,类似hmm的发射概率
𝑝(𝑤𝑜𝑟𝑑│𝑒𝑟𝑟)=(𝑝(𝑒𝑟𝑟│𝑤𝑜𝑟𝑑)𝑝(𝑤𝑜𝑟𝑑))/𝑝(𝑒𝑟𝑟)
直接统计p(wrd|err)也是可以的
朴素贝叶斯𝑝(𝑐│𝑋)的X是多个样本(词),没法直接统计结果
err过于稀疏
p(wrd)本来已有,所以统计p(err|wrd)并不比p(wrd|err)费力,p(x)计算相对值不需要
常见用法
召回,基于先验代替p(err|word)
编辑距离(拼音混淆、方言等)
排序
用LM做排序
因为每种错误的频率过低,概率不好统计
可以混合使用
对高频错误计算p(wrd|err)
先要正常搜索候选,再根据ed+p(wrd|err)排序
不在错误表里的依然使用前面的方法
后面的pattern识别即是此方法
real word error
方法一:
每个词都认为是错词,找到N个候选
然后类似‘最短路径分词’,找到概率最优的那条(经常用Viterbi)
也会对ed=1/2降权
方法二:
基于LM(2gram等)找出概率突降的位置
对该词寻找候选词令整句ppl最高
2.4 拼音纠错
场景:
输入法
难度最高
输入场景(搜索、评论)直接输拼音
与输入法不同,拼音本身就难识别,所以用户一般会自查
至少默认声母都是正确的
无法给用户提供候选集,天然也不适合做大量召回
中文纠错(音似导致的错误,恢复拼音再纠错)
词已经确定,相对容易
9键经常不进行纠错
因为候选集本身就很多,错误概率也不高
候选的拼音很多,对应的字词就更多了
拼音纠错法:
以前:
词库为映射表,nihao->你好
长句、非标准词序输入支持非常弱
必须用户逐字/词的指定
无法给出合理的默认值
即使给出也多为词的硬关联,语义合理性差
现在:
使用语言模型词库(bigram&unigram)
1)基于声母拆字
2)基于拆好的拼音查找候选字
3)基于bigram&unigram找出概率最高的序列
hmm(Viterbi)/最短路径
未来:
手机性能增长、模型压缩、网速大增(完全基于在线计算)
基于已上屏的上下文,用dl模型推荐出当前最可能的输入
做过尝试,代价比较高,效果凑合
直接基于拼音与输入做端到端的训练
现在长句一般也会发送到云端做解析
但依然是先拆字再计算概率,只是用更重的模型(3/4gram, lstm等)
对响应时间要求依然很高
拼音常见错误:
常见的拼音错误
输入错误,与英文类似
混淆音字词、方言(l-n/f-h/yie-ye/iou-iu/u-v)
gu|a->ai|wu 挂物(怪物)攻城奖励
s|en->un|zi 森子兵法 → 孙子兵法
前后鼻音: 打战片 → 打仗片
UV不分:鲁政俏佳人 → 律政俏佳人
LN不分: 晚良 → 晚娘
平翘舌: 甑([zèng])嬛传 → 甄嬛传
多音字
同音字
迟暮刚宪 →赤木刚宪
豌豆夹 → 豌豆荚
徐铮 → 徐峥
纠错流程:
先断字
每种断法都作为下一步的候选
基于某种断字方法
进行ed=1 or 2的候选扩充
如果增删改的字符让新字符串不构成拼音则抛弃
声母只能代替声母,韵母只能代替韵母
也可使用bk-tree搜索
包括混淆音、方言等问题
拼音编辑距离
in->ing/an->ang/z->zh/l->n
unigram/bigram
使用的是断字之后字词本身的uni/bigram
方言混淆音的召回不降权
中文常见错误:
词本身错
同音字词 (拼音输入法)
配副眼睛-配副眼镜
拼音错误(编辑距离)
拼风-屏风
形似字错误 (笔划、五笔、二笔)
高梁-高粱
混淆音字词、方言(l-n/f-h/yie-ye/iou-iu/u-v)
流浪织女-牛郎织女,打战片-打仗片,ln不分:晚良-晚娘
语法错误
多字/少字
字词顺序颠倒
周伦杰-周杰伦 (一般两个以上颠倒较难纠正)
语法错误
想象难以->难以想象
用词错
知识错误
传统算法基本无法解决。只能通过数据挖掘出一些常见模式。
名人人名、身高等信息错误
英文场景也会遇到类似错误
2.4 .1 纠错传统方法主体流程
语法错误
1) 做句法分析计算句法概率去识别,然后基于句法匹配去纠正
正确率也不高
2) 用NMT模型直接输出
1 错误检测:
大量的工程工作
可控优先
困惑集
基于每个单字可能出错的同音同形字
假设每个字都可以错,全部找出候选用ngram/ppl/等找出最优组合。
错词库、热词库pattern
可以用字典树查找
置信较高可直接替换
其它作为候选
泥(你)好->水泥好贵
难点:错词库的建立,置信度的评估(错误数/共现数)
分词
凡是 单字 和 不在词表的词 都认为可能出现错误
如果分词错误可能导致误判
王青水你好->王青水泥好
ML
MaxEnt最大熵模型作为分类器
SVM作为分类器
神经网络作为识别器
LM语言模型式,类似ngram
基于前面(或双向)文字预测当前位置可能出现的字
序列标注问题
逐字or逐词预测是否正确
2 候选词
字形类似
每个字都有一个同形映射表,查找。都属于困惑集
同音、类似音、拼音错误
汉字恢复为拼音
可做先验,恢复的汉字声母首字母都是正确的
最多就是l/n方言式固定变换
基于拼音找出候选词
与拼音纠错相同
问题
对于少字情况无法通用处理
单字独立成词,常用汉字7000多,无法逐一尝试增加
只能使用pattern解决常见情况
3 错误纠正
其实是排序
基于LM
ngram计算用候选字词代替当前字词分数最高的那个
如果候选字的个数不等,则不好比
计算整句ppl最高的那个
ppl依赖的ngram可用词级别
字级别远距离识别较差,对整体评分不利
nn给整句通顺度打分
与ppl类似,但可以识别远距离关系
HMM
正确的字为隐藏状态
转移概率(2gram),发射概率(该字发生该错误的概率)
去掉发射概率也可直接用viterbi解码
原 理还是语言模型
SVM
基于窗口
前后几个字符的特征、是否在ngram内,分数
可以用来识别
基于整句
特征工程(LM信息、词频、编辑距离、是否同音近似音等)
只能用来排序
纠错流程(pycorrector)
1)直接搜索有没有常见错误
直接根据映射纠正
保守期间可以作为候选
2)分词
所有不在词表里的词或单字都可能是错误
都作为候选
3)基于语言模型找出概率值较低的那些字
2gram与3gram取平均
再求方差,取方差高于阀值的
4)生成候选
把所有疑似错字找到对应同音、同型字,作为正确候选
5)计算用候选正确字代替后的ppl
停用词过滤
1. 加载停用词
def load_stop_words(stop_word_path):
'''
加载停用词
param stop_word_path:停用词路径
return: 停用词表 list
'''
## 打开文件
file = open(stop_word_path, 'r', encoding='utf-8')
## 读取所有行
stop_words = file.readlines()
## 去除每一个停用词前后 空格 换行符
stop_words = [stop_word.strip() for stop_word in stop_words]
return stop_words```
## 词的标准化
```python
在这里插入代码片
过滤无用字符
2. 过滤字符
def clean_sentence(line):
line = re.sub(
"[a-zA-Z0-9]|[\s+\-\|\!\/\[\]\{\}_,.$%^*(+\"\')]+|[::+——()?【】《》“”!,。?、~@##¥%……&*()]+|题目", '',line)
words = jieba.cut(line, cut_all=False)
return words
词的标准化
在这里插入代码片
采样
为什么要对数据进行采样平衡
- 下采样:克服高维特征以及大量数据导致的问题,有助于降低成本,缩短时间甚至提升效果
- 上采样:均衡正负样本的数据,避免数据不平衡导致分类器对正负样本的有偏训练
- 比如99%为正样本,1%为负样本,如果分类器把所以样本预测为正样本则准确率高达99%,显然不符合实际情况
是否一定需要对原始数据进行采样平衡
否。
- 采样前后会对原始数据的分布进行改变,可能导致泛化能力大大下降
- 采样有一定概率会造成过拟合,当原始数据过少而采样量又很大当时候,造成大量数据被重复,造成模型训练的结果有一定的过拟合
有哪些常见的采样方法?
- 随机采样
- 无放回的简单抽样:每条样本被采到的概率相等且都为1/N
- 有放回的简单抽样:每条样本可能多次被选中
- 上采样:即合理地增加少数类的样本
- 下采样:欠抽样技术是将数据从原始数据集中移除
- 平衡采样:考虑正负样本比
- 分层采样:通过某一些feature对数据进行切分,按照切分后的占比分别进行采样
- 整体采样:先将数据集T中的数据分组成G个互斥的簇,然后再从G个簇中简单随机采样s个簇作为样本集
- 合成采样
相对于采样随机的方法进行上采样, 还有两种比较流行的上采样的改进方式:- SMOTE
- x_new = x + rand(0,1) * (x′−x)
- 带来新样本的同时有可能造成不同类别样本之间的重合
- Borderline-SMOTE为了解决上面的问题,在x_new生成之前,会先判断x这个点是否周围都是同类别的点
- ADASYN
- 同上,也是在构造样本点的过程中考虑了正负样本比
- SMOTE
- 平衡欠采样
- EasyEnsemble,利用模型融合的方法(Ensemble)
- 少样本不变,多样本拆分成N份,分别组合进行模型训练后进行模型融合
- BalanceCascade,利用模型融合的方法(Boost)
- 每次剔除预测正确的多数样本,加入新的未预测的多数样本
- NearMiss
- 选择离各种情况下的少数样本位置最远的多数样本进行训练
- EasyEnsemble,利用模型融合的方法(Ensemble)
能否避免采样?
可以通过修改模型训练中的loss权重,比如罗辑回归中进行case_weight的调整,adaboost中对样本错分权重的改变等等。
你平时怎么用采样方法?
尽量避免使用合成采样的方式去做数据填充,总结如下:
- 由于项目中时间的充裕问题,填充的结果往往是正负样本交叠且无感知的,会干扰分类器
- 通常我们引入的特征不仅仅是连续变量,在分类变量上合成采样表现并不优秀
- 合成采样往往无法与后序模型进行结合使用,比如随机采样可以引入模型交叉,比如平衡欠采样可以引入模型融合
缺失值处理
是不是一定需要对缺失值处理?
当缺失值占比在可接受的范围以内的时候才需要进行填充,如果缺失值大于50%以上的时候,可以选择进行二分化,如果缺失值大于80%可以完整删除该列而不是强行去填充
直接填充方法有哪些?
- 均值
- 中位数
- 众数
- 分位数
模型插值方法有哪些?及方法的问题
- 有效性存疑,取决于特征列数
- 生成的插值来源于其他列的特征,是不是意味着插值的结果已经是和其他列的组合高相关
如何直接离散化?
- 离散特征新增缺失的category
hold位填充方法有哪些?
把全部结果都embedding化,对空值或者缺失值按照一定规则生成若干个hold位,以hold位的向量结果作为缺失值的结果
- 可以参考YouTube中的新商品向量生成逻辑
- bert中的[UNK]向量,[unused]向量
怎么理解分布补全?
如果我们能在原始数据上发现明显规律,比如整体数据满足高维多元高斯分布,则可以通过未知列补全缺失列的值
random方法
在缺失量特别少(通常认为小于1%)的时候,可以随机生成
总结
- 实际机器学习工程中,直接删除、众数填充和直接离散化方法用的最多
- 快速
- 对原始数据的前提假设最少,也不会影响到非缺失列
- 在深度学习中,hold位填充方法用的最多
- 在大量数据的拟合条件下,能保证这些未知数据处的向量也能得到收敛
- 而且通过随机构造的特性,保证了缺失处的[UNK]向量,[unused]向量的通配性
特征选择
为什么要做特征选择?
- 耗时:特征个数越多,分析特征、训练模型所需的时间就越长。
- 过拟合:特征个数越多,容易引起“维度灾难”,模型也会越复杂,其推广能力会下降。
- 共线性:单因子对目标的作用被稀释,解释力下降
从哪些方面可以做特征选择?
- 方差,是的feature内的方向更大,对目标区分度提高更高贡献
- 相关性,与区分目标有高相关的特征才有意义
既然说了两个方向,分别介绍一些吧
- 方差
- 移除低方差特征
- 移除低方差特征是指移除那些方差低于某个阈值,即特征值变动幅度小于某个范围的特征,这一部分特征的区分度较差,我们进行移除
- 考虑有值数据中的占比,异常数据的占比,正常范围数据过少的数据也可以移除
- 移除低方差特征
- 相关性
- 单变量特征选择:单变量特征是基于单一变量和目标y之间的关系,通过计算某个能够度量特征重要性的指标,然后选出重要性Top的K个特征。但是这种方式有一个缺点就是忽略了特征组合的情况
- 皮尔森相关系数:
- Fisher得分:
- 假设检验
- 卡方检验
- ANOVA
- 熵检验
- 互信息熵
- 度量两个变量之间的相关性,互信息越大表明两个变量相关性越高;互信息为0,两个变量越独立
- KL散度
- 相对熵
- 互信息熵
- 单变量特征选择:单变量特征是基于单一变量和目标y之间的关系,通过计算某个能够度量特征重要性的指标,然后选出重要性Top的K个特征。但是这种方式有一个缺点就是忽略了特征组合的情况
异常点识别
统计方法
- 3∂原则
- 数据需要服从正态分布
- 只能解决一维问题: μ ± 3 σ \mu \pm 3\sigma μ±3σ
- 基于正态分布的离群点检测方法
- 一元高斯分布校验:,如果概率值大小离群则代表为异常点
- 多元高斯分布检测:
- 假设 n 维的数据集合 ,可以计算 n 维的均值向量
- n × n n \times n n×n的协方差矩阵: - 得到
- 假设 n 维的数据集合 ,可以计算 n 维的均值向量
- 马氏距离
- 假设a是均值向量,其中S是协方差矩阵。
-
x
2
x^2
x2统计检验
- a i a_i ai是a在第i维上的取值, E i E_i Ei是所有对象在第 i 维的均值,n是维度
- 箱型图
- IQR,[Q1-3/2(Q3-Q1),Q3+3/2(Q3-Q1)]
矩阵分解方法
- PCA
- 去除均值后的协方差矩阵对应的特征值和特征向量,按照特征值排序,topN个特征向量组成新的低维空间
- 核心:在于组合原始的特征,使得新的原始数据在新的低维度空间中的方差更大,特征更有区分力
- 问题是没有做到剔除,只是对空间上的表现进行了优化,尽可能的压缩异常点在新空间中作用
- SVD
- 假设 dataMat 是一个 p 维的数据集合,有 N 个样本,它的协方差矩阵是 X。那么协方差矩阵就通过奇异值分解写成:
- 其中 P 是一个 (p,p) 维的正交矩阵,它的每一列都是 X 的特征向量。D 是一个 (p,p) 维的对角矩阵,包含了特征值 。
- 可以认为是dataMat在主成分topj上的映射
- 最后还需要拉回原空间:
- 异常值分数(outlier score): +
特征值和特征向量的本质是什么?
- 一个特征向量可以看成 2 维平面上面的一条线,或者高维空间里面的一个超平面
- 特征向量所对应的特征值反映了这批数据在这个方向上的拉伸程度
矩阵乘法的实际意义?
- 两个矩阵相乘的意义是将右边矩阵中的每一列列向量变换到左边矩阵中每一行行向量为基所表示的空间中去。
- 矩阵点乘向量的意义是将右边的向量变换到左边矩阵中每一行行向量为基所表示的空间中去。
密度的离群点检测
- 定义密度为到k个最近邻的平均距离的倒数。如果该距离小,则密度高,反之亦然。另一种密度定义是使用DBSCAN聚类算法使用的密度定义,即一个对象周围的密度等于该对象指定距离d内对象的个数。
- 我们可以通过随机选择联通点,人为设置联通点附近最小半径a,半径内最小容忍点个数b,再考虑密度可达,形成蓝色方框内的正常数据区域,剩下的黄色区域内的点即为异常点。
- Local Outlier Factor算法
- 孤立森林:
- 经验1:每棵树的最大深度limit length=ceiling(log2(样本大小))
- 经验2:树的个数在256棵以下
缺点: - 计算量大:o(n^2)
- 需要人为选择阈值
聚类的离群点检测
- 一个对象是基于聚类的离群点,如果该对象不强属于任何簇,那么该对象属于离群点。
- 缺点也就是聚类的缺点,包括初始点对结果的影响,数据是否保持凸型对结果对影响,簇的个数的选择
如何处理异常点?
- 删除含有异常值的记录:直接将含有异常值的记录删除;
- 视为缺失值:将异常值视为缺失值,利用缺失值处理的方法进行处理;
- 平均值修正:可用前后两个观测值的平均值修正该异常值;
- 生成列新特征:category异常
- 不处理:直接在具有异常值的数据集上进行数据挖掘;
数据变换
为什么需要对数据进行变换?
- 避免异常点:比如对连续变量进行份桶离散化
- 可解释性或者需要连续输出:比如评分卡模型中的iv+woe
- 使得原始数据的信息量更大:比如log/sqrt变换
归一化和标准化之间的关系?
-
归一化(max-min)
- 缩放仅仅跟最大、最小值的差别有关,只是一个去量纲的过程
-
标准化(z-score)
- 缩放和所有点都相关,数据相对分布不会改变,集中的数据标准化后依旧集中
-
作用
- 解决部分模型由于数据值域不同对模型产生的影响,尤其是距离模型
- 更快的收敛
- 去量纲化
- 避免数值计算溢出
-
总结
- 异常点角度:特征数据上下限明显异常的时候使用标准化方法,简单归一化会造成数据差异模糊,整体方差下降
- 分布角度:使用标准化之前,要求数据需要近似满足高斯分布,不然会改变数据的分布,尤其是对数据分布有强假设的情况下
- 上线变动角度:归一化在上线的时候需要考虑上下约束届是否需要变动,标准化则不需要考虑变动
- 值域范围角度:归一化对数据范围约定较为固定,而标准化的输出上下届则不定
- 模型角度:一般涉及距离计算,协方差计算,数据满足高斯分布的情况下用标准化,其他归一化或其他变换
-
常用模型
- knn:计算距离,不去量冈则结果受值域范围影响大
- neural network:梯度异常问题+激活函数问题
连续特征常用方法
-
截断
- 连续型的数值进行截断或者对长尾数据进行对数后截断(保留重要信息的前提下对特征进行截断,截断后的特征也可以看作是类别特征)
- 参考异常点里面的outlier识别,以最大值填充或者以None
-
二值化
- 数据分布过于不平衡
- 空值/异常值过多
-
分桶
- 小范围连续数据内不存在逻辑关系,比如31岁和32岁之间不存在明显的差异,可以归为一类
-
离散化
- 数值无意义,比如学历、祖籍等等
-
缩放
- z-score标准化
- min-max归一化
- 范数归一化:
- L1范数
- L2范数
- 平方根缩放
- 对数缩放
- 对数缩放适用于处理长尾分且取值为正数的数值变量
- 它将大端长尾压缩为短尾,并将小端进行延伸
- 可以把类似较差的特征线性化,比如x1x2/y,log变换后变成了log(x1)+log(x2)-log(y)
- 可以把有偏分布修正为近似正太分布
- 对数缩放适用于处理长尾分且取值为正数的数值变量
- Box-Cox转换
- 通过因变量的变换,使得变换后的y(λ)与自变量具有线性依托关系。因此,Box-Cox变换是通过参数的适当选择,达到对原来数据的“综合治理”,使其满足一个线性模型条件
-
特征交叉
- 人为分段交叉
- 提升模型的拟合能力,使基向量更有表示能力。比如,本来是在二维空间解释一个点的意义,现在升维到三维后解释
- 离散变量的交并补
- 连续变量的点积,attention类似
- 交叉中需要并行特征筛选的步骤
- 自动组合
- FM/FFM中的矩阵点积
- Neural Network里面的dense
- FM/FFM中的矩阵点积
- 条件选择
- 通过树或者类似的特征组合模型去做最低熵的特征选择
- 通过树或者类似的特征组合模型去做最低熵的特征选择
- 人为分段交叉
-
非线性编码
- 核向量进行升维
- 树模型的叶子结点的stack
- 谱聚类/pca/svd等信息抽取编码
- lda/EM等分布拟合表示
离散特征常用方法
- one-hot-encoder
- 分层编码
- 有一定规律的类别数据,邮政编码,手机号等等
- 计数编码
- 将类别特征用其对应的计数来代替,这对线性和非线性模型都有效
- 对异常值比较敏感,特征取值有可能冲突
- 计数排名编码
- 解决上述问题,以排名代替值
- Embedding
- 对于基数(类别变量所有可能不同取值的个数)很大的离散特征,简单模型任意欠拟合,而复杂模型任意过拟合;对于独热编码,得到的特征矩阵太稀疏.对于高基数类别变量,有效方式是基于目标变量对类别特征进行编码,即有监督的编码方式,适用于分类和回归问题
- 类别特征之间交叉组合
- 笛卡尔交叉
- 类别特征和数值特征之间交叉组合
- 均值、中位数、标准差、最大值和最小值
- 分位数、方差、vif值、分段冲量
文本特征
- 预处理手段有哪些?
- 将字符转化为小写
- 分词
- 去除无用字符
- 繁体转中文
- 去除停用词
- 去除稀有词
- 半角全角切换
- 错词纠正
- 关键词标记
- TF-IDF
- LDA
- LSA
- 提取词根
- 词干提取
- 标点符号编码
- 文档特征
- 实体插入和提取
- 文本向量化
- word2vec
- glove
- bert
- 文本相似性
- 如何做样本构造?
- 按标点切分
- 按句切分
- 对话session切分
- 按文章切分
- 按场景切分
- 分词过程中会考虑哪些方面?
- 词性标注
- 词形还原和词干提取
- 词形还原为了通用性特征的提取
- 词干提取为了去除干扰词把训练注意力集中在关键词上,同时提高速度;缺点是不一定词干代表完整句义
- 文本中的统计信息一般有哪些?
- 直接统计值:
- 文本的长度
- 单词个数
- 数字个数
- 字母个数
- 大小写单词个数
- 大小写字母个数
- 标点符号个数
- 特殊字符个数
- 数字占比
- 字母占比
- 特殊字符占比
- 不同词性个数
- 直接统计值的统计信息:
- 最小最大均值方差标准差
- 分位数,最早/最晚出现位置
- 直接统计值:
- 直接对文本特征进行整理手段有哪些?
- N-Gram模型
- 将文本转换为连续序列,扩充样本特征
- 连续语意的提取
- TF-IDF
- 权重评分,去除掉一些低重要性的词,比如每篇文章都出现的"的",“了”
- LDA
- 主题抽取,用狄利克雷分布去拟合出文章和主题之间的关系
- 相似度
- 余弦相似度
- Jaccard相似度
- 共现性
- Levenshtein(编辑距离)
- 文本近似程度
- 海林格距离
- 用来衡量概率分布之间的相似性
- JSD
- 衡量prob1 和 prob2两个分布的相似程度
- 向量化
- word2vec
- glove
- bert
- N-Gram模型
- 文本处理有大量可以讲,可以谈的,以上只是做了一个最简单的汇总,详细的会在自然语言处理的专题一条一条分析,面试官也一定会就每个知识点进行展开
画一个最简单的最快速能实现的框架
- 建议不要上来就transfer+attention+bert+xlnet,挖了坑要跳的
- 建议从简单的开始,然后面试官说还有其他方法么?再做延展: