(1)从One-hot到Word2vec

因项目需要,重新捡起来NLP进行学习。感觉NLP经过长时间发展在各个领域出现了大量效果好的模型。为了梳理一下思路,特地写博客记录,以便以后复习。

词袋模型

one-hot

中文是独热编码,至于为啥叫这个我也不太懂。不过表现形式还是很简单的。

在早早年,用1,2,3表示不同的单词有个问题,比如说1表示苹果,2表示香蕉,3表示桃,那么我们想表示同时拥有苹果和香蕉使用1+2=3的算法显然是错误的,这代表单纯用索引来表示一个值是很难计算的。

如果我们使用One-hot进行编码的话,苹果是[1,0,0],香蕉是[0,1,0],桃是[0,0,1]。那么同时拥有苹果和香蕉就可以写为[1,1,0]。这样就可以进行计算了。

其实这也是将自然语言图片化

那么再举个栗子:

我们有一个字典表示每个词的索引,比如说:

dic=[‘我‘:'1','苹果','2','想吃':'3']

“我想吃苹果” 这句话中每个词都可以表示成:

我:[1,0,0]

想吃:[0,0,1]

苹果:[0,1,0]

这样就把每个词变成了电脑能看懂的东西,同时也将离散的单词连续化了。这其实是映射到了欧式空间,因为欧式空间有很多计算词频,计算相似度的常用方法。

说个题外话,上面对词典的记录实际上是key:value的形式,按照出现的先后次序进行排列。但是这样建立的词典似乎没有很多的意义。因此还有一种建立词典的方法:词频

我们对一篇文章建立词典的时候先统计每个词在文章中出现的次数,根据出现的次数从低到高进行排列。如果维度过高也可以对低频词进行删除,对于词典中没有的词就可以使用全0表示。

注意:全0的向量属于保留项,用来保留null或者unknown

虽然独热编码简单,好写又好看,但是当词一多就会产生维度灾难,中文几千个常用词每个词都一个编码的话机器就炸了。而且在计算词频的时候诸如“的”,“啊”的词会大量出现,产生很强的噪音。为了解决这些问题,很多科学家又提出了不同的想法。

TF-IDF

TF-IDF(term frequency–inverse document frequency,词频-逆向文件频率)是一种计算词频的方法。因One-hot对于干扰词无法做很好的区分,所以TF-IDF就想了,干扰词是什么文章都有的,那我改一下高频词的定义不就好啦?因此TF-IDF的思想就是:如果一篇文章中出现的词频率高且在其他文章中很少出现,则认为这个词或者短语可以有很好的区分能力,可以应用于分类等领域。

说完这个,那么你的脑海里大概就能想出来这个算法是怎么实现的啦!这里引用一下TF-IDF算法介绍及实现_Asia-Lee-CSDN博客_tf-idf大佬的文章中的公式。其实TF-IDF=TF+IDF,一个计算词频,一个比较该词是否有很好的区分能力。

TF(Term Frequency,词频):             即:。还是比较清晰的

IDF(Inverse Document Frequency,逆向文件频率):: 

即:

最终TF-IDF-TF*IDF就得到最终结果啦!

这里摘录一下TF-IDF介绍及相关代码实现 - 简书大佬的代码


def feature_select(list_words):
    print("1、总词频统计:")
    # 总词频统计
    doc_frequency = defaultdict(int)
    for word_list in tqdm(list_words):
        for i in word_list:
            doc_frequency[i] += 1

    print("2、TF计算:")
    # 计算每个词的TF值
    n = sum(doc_frequency.values())
    word_tf = {}  # 存储没个词的tf值
    for i in tqdm(doc_frequency):
        word_tf[i] = doc_frequency[i] / n

    print("3、IDF计算:")
    # 计算每个词的IDF值
    doc_num = len(list_words)
    word_idf = {}  # 存储每个词的idf值
    word_doc = defaultdict(int)  # 存储包含该词的文档数
    for i in tqdm(range(len(list_words))):
        for word in list_words[i]:
            word_doc[word] += 1

    for i in tqdm(doc_frequency):
        word_idf[i] = math.log(doc_num / (word_doc[i] + 1))

    print("4、TF计算:")
    # 计算每个词的TF*IDF的值
    word_tf_idf = {}
    for i in tqdm(doc_frequency):
        word_tf_idf[i] = word_tf[i] * word_idf[i]

    # 对字典按值由大到小排序
    dict_feature_select = sorted(word_tf_idf.items(), key=operator.itemgetter(1), reverse=True)
    return dict_feature_select

n-gram

n-gram模型涉及到很多统计学知识,先把这些写上

朴素贝叶斯

整理自机器学习算法之朴素贝叶斯(Naive Bayes)--第一篇_踩风火轮的乌龟-CSDN博客

贝叶斯朴素的原因是他基于一个假设:特征之间是相互独立的。所以这个算法不可用于强关联性和非线性的关系。首先看一下贝叶斯法则:

 这个公式可谓是非常经典了,该公式的作用是在给定现象下,预测某种结果的概率。这句话有点绕,其实是在说有已知B->A的关系想求A->B的关系是什么。因此输入是:这个结果下出现这种现象的概率,出现这种结果的概率和出现这种现象的概率。我们引用机器学习算法之朴素贝叶斯(Naive Bayes)--第一篇_踩风火轮的乌龟-CSDN博客大佬的例子:

 这里是已知下雨而且有乌云的概率去计算有乌云下雨的概率,为了达成这个目标要引入下雨的概率和有乌云的概率,我们称下雨的概率为先验概率,有乌云为现象概率。

朴素贝叶斯是这个的扩展,考虑了多个特征。我们设

  1. ωj表示属于哪个类别,j∈{1,2,3,…,m}ωj表示属于哪个类别,j∈{1,2,3,…,m}
  2. xi表示特征向量中的第i个特征,i∈{1,2,3,…,n}

朴素贝叶斯的目标就是分别求得P(ωj|给定现象)j∈{1,2,3,…,m}P(ωj|给定现象)j∈{1,2,3,…,m},选出最大的概率。

P(X|Y):条件概率

随机变量的独立性意味着我告诉你一个变量的出现,并不影响你相信另一个出现的可能。最简单的一个例子就是抛硬币,也就是第一次的反正面并不会影响你再一次抛出现反正面的概率(也就是0.5)。

朴素贝叶斯模型中,特征之间不仅仅是独立的,而且是加条件的独立的。比如说:我的特征向量x中,有n个特征x中,有n个特征,那么我可以把概率写成下面的形式:

 P(x|ωj)P(x|ωj)的概率我们可以理解成:在给定属于某个类别的条件下,观察到出现现象x的概率。在特征向量中的每个特点的概率我们都可以通过极大似然估计(maximum-likelihood estimate)来求得,也就是简单地求某个特征在某个类别中的频率,公式如下:

 先验概率:

 可以设置为一个超参数

现象概率:独立于类别,就是找到所有发生过的概率。类似于找全部类别中deal出现的概率。

为了防止后验概率为0,有些人会加上平滑项,类似于TF-IDF中的+1。

说完了朴素贝叶斯,继续研究n-gram

根据朴素贝叶斯公式,我们得到了每个词的词频。从One-Hot的两个缺点:1、没有合适的词频计算2、没有上下文关系来看,这个模型主要是对于上下文关系的研究。说到底是对单词间顺序的研究。比如说我爱吃苹果不能转换成苹果爱吃我吧

所以N-gram的特点就是每个词都基于其他若干个词而出现,不再把单词看做一个单独的值。前面那个N代表了你想看左右单词的数量。比如说“我爱吃苹果”转换成2-gram(Bi-gram)可得:{我,爱},{爱,吃},{吃,苹},{苹,果}。

这样我们就知道,每个单词都依赖于从第一个单词到他这个单词的影响,就可知公式:

p(wn​∣wn−1​⋯w2​w1​)

又变成朴素贝叶斯啦!

但是这里又有两个问题:

1、参数太多了,有n个

2、数据稀疏

第一个问题是引入了马尔科夫假设:一个词的出现仅与它之前的若干个词有关

Bi-gram就可变成

p(S)=p(w1​w2​⋯wn​)=p(w1​)p(w2​∣w1​)⋯p(wn​∣wn−1​)

Tri-gram为

p(S)=p(w1​w2​⋯wn​)=p(w1​)p(w2​∣w1​)⋯p(wn​∣wn−1​wn−2​)

这样就好算多了!

第二个问题引入了数据平滑,有很多方法。

分布式

为了解决维度灾难,又有人提出了分布式的方法。其实就是把编码映射到高维空间。引用一个网络热图:

 这样就减少了词向量的维度,而且也可以在三维上发现相似性,可以说是非常棒的一个算法了。不过这样的话词向量的质量就直接决定了下游任务的准确性。所以就产生了各种各样的分布式模型,比如word2vec,Glove,BERT等等。这就留给下一篇吧~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值