长治网站建设公司,宁波网站建设模板下载免费,服装设计是冷门专业吗,临汾推广型网站开发《统计学习方法》-李航 损失函数总结
概要 div idpost_detailNLP点滴——文本相似度 目录 前言字面距离common lang库相同字符数莱文斯坦距离(编辑距离)定义实现方式Jaro距离定义实现方式应用SimHash定义基本流程相似性度量存储索引实现应用语义相似性背…《统计学习方法》-李航 损失函数总结
概要 div idpost_detailNLP点滴——文本相似度 目录 前言字面距离common lang库相同字符数莱文斯坦距离(编辑距离)定义实现方式Jaro距离定义实现方式应用SimHash定义基本流程相似性度量存储索引实现应用语义相似性背景知识统计语言模型n-gram模型词向量主题模型LSAPLSALDA应用Word2Vec神经网络语言模型CBOW和Skip-gram模型应用参考文献 前言 在自然语言处理过程中经常会涉及到如何度量两个文本之间的相似性我们都知道文本是一种高维的语义空间如何对其进行抽象分解从而能够站在数学角度去量化其相似性。而有了文本之间相似性的度量方式我们便可以利用划分法的K-means、基于密度的DBSCAN或者是基于模型的概率方法进行文本之间的聚类分析另一方面我们也可以利用文本之间的相似性对大规模语料进行去重预处理或者找寻某一实体名称的相关名称模糊匹配。而衡量两个字符串的相似性有很多种方法如最直接的利用hashcode以及经典的主题模型或者利用词向量将文本抽象为向量表示再通过特征向量之间的欧式距离或者皮尔森距离进行度量。本文围绕文本相似性度量的主题从最直接的字面距离的度量到语义主题层面的度量进行整理总结并将平时项目中用到的文本相似性代码进行了整理如有任何纰漏还请指出我会第一时间改正^v^。ps.平时用的Java和scala较多本文主要以Java为例。 字面距离 提到如何比较两个字符串我们从最初编程开始就知道字符串有字符构成只要比较比较两个字符串中每一个字符是否相等便知道两个字符串是否相等或者更简单一点将每一个字符串通过哈希函数映射为一个哈希值然后进行比较。但是这种方法有一个很明显的缺点就是过于“硬”对于相似性的度量其只有两种0不相似1相似哪怕两个字符串只有一个字符不相等也是不相似这在NLP的很多情况是无法使用的所以下文我们就“软”的相似性的度量进行整理而这些方法仅仅考虑了两个文本的字面距离无法考虑到文本内在的语义内容。 common lang库 文中在部分代码应用中使用了Apache提供的common lang库该库包含很多Java标准库中没有的但却很实用的函数。其maven引用如下 dependencygroupIdorg.apache.commons/groupIdartifactIdcommons-lang3/artifactIdversion3.4/version
/dependency 相同字符数 在传统的字符串比较过程中我们考虑字符串中每个字符是否相等并且考虑了字符出现的顺序如果不考虑字符出现的顺序我们可以利用两个文本之间相同的字符数量很简单不再赘述可以利用common lang中的getFuzzyDistance int dis StringUtils.getFuzzyDistance(term, query, Locale.CHINA); 莱文斯坦距离(编辑距离) 定义 我们在学习动态规划的时候一个很经典的算法便是计算两个字符串的编辑距离即 莱文斯坦距离又称Levenshtein距离是编辑距离edit distance的一种。指两个字串之间由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符插入一个字符删除一个字符。 例如将kitten一字转成sitting sitten k→ssittin e→isitting →g 那么二者的编辑距离为3。 俄罗斯科学家弗拉基米尔·莱文斯坦在1965年提出这个概念。 实现方式 我们可以利用common lang中StringUtils的函数来计算 int dis StringUtils.getLevenshteinDistance(s1, s2);
//实现
public static int getLevenshteinDistance(CharSequence s, CharSequence t) {if (s null || t null) {throw new IllegalArgumentException(Strings must not be null);}int n s.length(); // length of sint m t.length(); // length of tif (n 0) {return m;} else if (m 0) {return n;}if (n m) {// swap the input strings to consume less memoryfinal CharSequence tmp s;s t;t tmp;n m;m t.length();}int p[] new int[n 1]; //previous cost array, horizontallyint d[] new int[n 1]; // cost array, horizontallyint _d[]; //placeholder to assist in swapping p and d// indexes into strings s and tint i; // iterates through sint j; // iterates through tchar t_j; // jth character of tint cost; // costfor (i 0; i n; i) {p[i] i;}for (j 1; j m; j) {t_j t.charAt(j - 1);d[0] j;for (i 1; i n; i) {cost s.charAt(i - 1) t_j ? 0 : 1;// minimum of cell to the left1, to the top1, diagonally left and up costd[i] Math.min(Math.min(d[i - 1] 1, p[i] 1), p[i - 1] cost);}// copy current distance counts to previous row distance counts_d p;p d;d _d;}// our last action in the above loop was to switch d and p, so p now// actually has the most recent cost countsreturn p[n];
} Jaro距离 定义 Jaro Distance也是字符串相似性的一种度量方式也是一种编辑距离Jaro 距离越高本文相似性越高;而Jaro–Winkler distance是Jaro Distance的一个变种。据说是用来判定健康记录上两个名字是否相同也有说是是用于人口普查。从最初其应用我们便可看出其用法和用途其定义如下 其中 是匹配数目保证顺序相同字符串长度是换位数目 其中t换位数目表示两个分别来自S1和S2的字符如果相距不超过 我们就认为这两个字符串是匹配的而这些相互匹配的字符则决定了换位的数目t简单来说就是不同顺序的匹配字符的数目的一半即为换位的数目t举例来说MARTHA与MARHTA的字符都是匹配的但是这些匹配的字符中T和H要换位才能把MARTHA变为MARHTA,那么T和H就是不同的顺序的匹配字符t2/21。 而Jaro-Winkler则给予了起始部分就相同的字符串更高的分数他定义了一个前缀p给予两个字符串如果前缀部分有长度为 的部分相同则Jaro-Winkler Distance为 是两个字符串的Jaro Distance是前缀的相同的长度但是规定最大为4则是调整分数的常数规定不能超过0.25不然可能出现dw大于1的情况Winkler将这个常数定义为0.1 举个简单的例子 计算的距离 我们利用可以得到一个匹配窗口距离为3图中黄色部分便是匹配窗口其中1表示一个匹配我们发现两个X并没有匹配因为其超出了匹配窗口的距离3。我们可以得到 其Jaro score为 而计算Jaro–Winkler score我们使用标准权重其结果如下 实现方式 同样我们可以利用common lang中的getJaroWinklerDistance函数来实现注意这里实现的是Jaro–Winkler distance double dis StringUtils.getJaroWinklerDistance(reviewName.toLowerCase(), newsName.toLowerCase());//实现 public static double getJaroWinklerDistance(final CharSequence first, final CharSequence second) { final double DEFAULT_SCALING_FACTOR 0.1; //标准权重 if (first null || second null) { throw new IllegalArgumentException(“Strings must not be null”); } final double jaro score(first,second); // 计算Jaro score final int cl commonPrefixLength(first, second); // 计算公共前缀长度 final double matchScore Math.round((jaro (DEFAULT_SCALING_FACTOR * cl * (1.0 - jaro))) *100.0)/100.0; // 计算 Jaro-Winkler score
span classhljs-keywordreturn/span matchScore;}
应用
在Wetest舆情监控中我们在找寻游戏名简称和全称的对应关系时便使用到了Jaro-Winkler score进行衡量其中我们将Jaro分数大于0.6的认为是相似文本之后在总的相似文本中提取最相似的作为匹配项实现效果还不错 其中冒号左边是待匹配项右边是匹配项游戏名 词频Jaro-Winkler scoreJaro-Winkler score较高的一般都是正确的匹配项。
SimHash
定义
SimHash是一种局部敏感hash它也是Google公司进行海量网页去重使用的主要算法。 传统的Hash算法只负责将原始内容尽量均匀随机地映射为一个签名值原理上仅相当于伪随机数产生算法。传统的hash算法产生的两个签名如果原始内容在一定概率下是相等的如果不相等除了说明原始内容不相等外不再提供任何信息因为即使原始内容只相差一个字节所产生的签名也很可能差别很大。所以传统的Hash是无法在签名的维度上来衡量原内容的相似度而SimHash本身属于一种局部敏感哈希算法它产生的hash签名在一定程度上可以表征原内容的相似度。 我们主要解决的是文本相似度计算要比较的是两个文章是否相似当然我们降维生成了hash签名也是用于这个目的。看到这里估计大家就明白了我们使用的simhash就算把文章中的字符串变成 01 串也还是可以用于计算相似度的而传统的hash却不行。 我们可以来做个测试两个相差只有一个字符的文本串“你妈妈喊你回家吃饭哦回家罗回家罗” 和 “你妈妈叫你回家吃饭啦回家罗回家罗”。 通过simhash计算结果为 1000010010101101111111100000101011010001001111100001001011001011 1000010010101101011111100000101011010001001111100001101010001011 通过传统hash计算为 0001000001100110100111011011110 1010010001111111110010110011101 通过上面的例子我们可以很清晰的发现simhash的局部敏感性相似文本只有部分01变化而hash值很明显即使变化很小一部分也会相差很大。
基本流程
注具体的事例摘自Lanceyan[10]的博客《海量数据相似度计算之simhash和海明距离》
分词把需要判断文本分词形成这个文章的特征单词。最后形成去掉噪音词的单词序列并为每个词加上权重我们假设权重分为5个级别1~5。比如“ 美国“51区”雇员称内部有9架飞碟曾看见灰色外星人 ” 分词后为 “ 美国4 51区5 雇员3 称1 内部2 有1 9架3 飞碟5 曾1 看见3 灰色4 外星人5”括号里是代表单词在整个句子里重要程度数字越大越重要。hash通过hash算法把每个词变成hash值比如“美国”通过hash算法计算为 100101,“51区”通过hash算法计算为 101011。这样我们的字符串就变成了一串串数字还记得文章开头说过的吗要把文章变为数字计算才能提高相似度计算性能现在是降维过程进行时。加权通过 2步骤的hash生成结果需要按照单词的权重形成加权数字串比如“美国”的hash值为“100101”通过加权计算为“4 -4 -4 4 -4 4”“51区”的hash值为“101011”通过加权计算为 “ 5 -5 5 -5 5 5”。合并把上面各个单词算出来的序列值累加变成只有一个序列串。比如 “美国”的 “4 -4 -4 4 -4 4”“51区”的 “ 5 -5 5 -5 5 5” 把每一位进行累加 “45 -4-5 -45 4-5 -45 45” 》 “9 -9 1 -1 1 9”。这里作为示例只算了两个单词的真实计算需要把所有单词的序列串累加。降维把4步算出来的 “9 -9 1 -1 1 9” 变成 0 1 串形成我们最终的simhash签名。 如果每一位大于0 记为 1小于0 记为 0。最后算出结果为“1 0 1 0 1 1”。 整个过程的流程图为
相似性度量
有了simhash值我们需要来度量两个文本间的相似性就像上面的例子一样我们可以比较两个simhash间0和1不同的数量。这便是汉明距离Hamming distance 在信息论中两个等长字符串之间的汉明距离英语Hamming distance是两个字符串对应位置的不同字符的个数。换句话说它就是将一个字符串变换成另外一个字符串所需要替换的字符个数。 汉明重量是字符串相对于同样长度的零字符串的汉明距离也就是说它是字符串中非零的元素个数对于二进制字符串来说就是1的个数所以11101的汉明重量是4。 例如 1011101与1001001之间的汉明距离是2 一般在利用simhash进行文本相似度比较时我们认为汉明距离小于3的文本是相似的。
存储索引 存储
将一个64位的simhash签名拆分成4个16位的二进制码。图上红色的16位分别拿着4个16位二进制码查找当前对应位置上是否有元素。放大后的16位对应位置没有元素直接追加到链表上对应位置有则直接追加到链表尾端。图上的 S1 — SN
查找
将需要比较的simhash签名拆分成4个16位的二进制码。分别拿着4个16位二进制码每一个去查找simhash集合对应位置上是否有元素。如果有元素则把链表拿出来顺序查找比较直到simhash小于一定大小的值整个过程完成。在去重时因为汉明距离小于3则为重复文本那么如果存在simhash相似的文本对于四段simhash则至少有一段simhash是相同的所以在去重时对于待判断文本D如果D中每一段的simhash都没有相同的那么D为无重复文本。
原理 借鉴hashmap算法找出可以hash的key值因为我们使用的simhash是局部敏感哈希这个算法的特点是只要相似的字符串只有个别的位数是有差别变化。那这样我们可以推断两个相似的文本至少有16位的simhash是一样的。具体选择16位、8位、4位大家根据自己的数据测试选择虽然比较的位数越小越精准但是空间会变大。分为4个16位段的存储空间是单独simhash存储空间的4倍。
实现
在实际NLP的使用中我利用Murmur3作为字符串的64位哈希值用Java和spark分别实现了一个simhash的版本 我将源码放在了github上如下链接
github: xlturing/simhashJava
其中利用了结巴作为文本的分词工具Murmur3用来产生64位的hashcode。另外根据上述存储方式进行了simhash分段存储提高搜索速度从而进行高效查重。
应用
simhash从最一开始用的最多的场景便是大规模文本的去重对于爬虫从网上爬取的大规模语料数据我们需要进行预处理删除重复的文档才能进行后续的文本处理和挖掘那么利用simhash是一种不错的选择其计算复杂度和效果都有一个很好的折中。 但是在实际应用过程中也发现一些badcase完全无关的文本正好对应成了相同的simhash精确度并不是很高而且simhash更适用于较长的文本但是在大规模语料进行去重时simhash的计算速度优势还是很不错的。
语义相似性
在NLP中有时候我们度量两个短文本或者说更直接的两个词语的相似性时直接通过字面距离是无法实现的如中国-北京意大利-罗马这两个短语之间的相似距离应该是类似的因为都是首都与国家的关系再比如男人、男孩女人、女孩应该是相同的关系但是我们看其字面距离都是0。 想要做到语义层面的度量我们需要用到机器学习建模而自然语言的问题转化为机器学习的首要问题便是找到一种方法把自然语言的符号数学化。
背景知识
在自然语言处理领域中有两大理论方向一种是基于统计的经验主义方法另一种是基于规则的理性主义方法[15]。而随着计算机性能的提升以及互联网发展而得到的海量语料库目前NLP的研究更多是基于统计的经验主义方法。所以在本文讨论的语义相似性中也是从统计学的角度出发进行总结。
统计语言模型
对于统计语言模型而言最基础的理论便是贝叶斯理论Bayes theorem PS.关于贝叶斯理论强烈推荐数学之美番外篇平凡而又神奇的贝叶斯方法一篇深入浅出的好文。另外推荐下自己师兄参与翻译的作品《贝叶斯方法——概率编程与贝叶斯推断》很全面的贝叶斯理论实践书籍。对于大规模语料库我们可以通过词频的方式来获取概率例如100个句子中出现了1次Okay那么 而同样的对于句子An apple ate the chicken我们可以认为其概率为0因为这不符合我们说话的逻辑。 统计语言模型是用来计算一个句子的概率其通常基于一个语料库D来构建。如何表示一个句子的概率呢我们用来表示一个基元通常就是指词语也可以是字或短语那么对于一个由N个词组成的句子W可以表示为 那么其联合概率 就可以认为是该句子的概率根据贝叶斯公式的链式法则可以得到 其中条件概率便是语言模型的参数如果我们把这些全部算出来那么一个句子的概率我们就能很轻易的得出。但是很明显这个参数的量是巨大的是无法计算的。这时我们可以将映射到某个等价类从而降低参数数目。 ps.语料库我们用C表示而词典D一般为语料中出现的所有不重复词
n-gram模型
既然每个单词依赖的单词过多从而造成了参数过多的问题那么我们就简单点假设每个单词只与其前n-1个单词有关这便是n-1阶Markov假设也就是n-gram模型的基本思想。 那么对于句子W的概率我们可以简化如下 那么对于最简单的一阶情况也称unigram或uni-gram或monogram二阶bigram 三阶trigram就简单表示为 为了在句首和句尾能够统一我们一般会在句首加一个BOS标记句尾加一个EOS标记那么对于句子Mark wrote a book其概率可以表示如下 为了预估条件概率根据大数定理简单统计语料库中出现的频率并进行归一化。我们用c来表示频率那么可表示如下 其中分母在unigram中就可以简单认为是词语出现的次数。 在n-gram模型中还有一个很重要的问题就是平滑化因为再大的语料库都不可能涵盖所有情况考虑两个问题
那么就是0吗那么就是1吗
这显然是不合理的这就需要进行平滑这里不展开讨论。 根据最大似然我们可以得到 其中C表示语料库表示词语的上下文而这里对于n-gram模型取对数后的对数似然函数为 从上式我们可以看出可以看做是关于的函数即 其中为待定参数集通过语料库训练得到参数集后F便确定了我们不需要再存储概率可以直接计算得到而语言模型中很关键的就在于F的构造
词向量
为了从使得计算机从语义层面理解人类语言首先要做的就是将语言数学化如何进行表示呢人们便提出了词向量的概念即用一个向量来表示一个词。
One-hot Representation
一种最简单词向量就是利用词频向量将高维的语义空间抽象成数学符号表示向量长度为词典的大小这种表示方式非常直观但是容易造成维度灾难并且还是不能刻画语义的信息。
词语表示
对于词语而言用一个向量来表示一个词最直观简单的方式就是将每个词变为一个很长的向量向量长度便是词典的长度其中绝大部分为0只有一个维度为1代表了当前词。 假设语料库“冲突容易引发战争”那么词典为
D[冲突,容易,引发,战争]冲突[1,0,0,0]战争[0,0,0,1]
每个词都是含有一个1的n维向量这种方式我们压缩存储下就是给每个词语分配一个ID通常实际变成我们最简单的就是用hash值表示一个词语。这种方式可以用在SVM、最大熵和CRF等等算法中完成NLP的大多数场景。例如我们可以直接将 但是缺点很明显就是我们用这种方式依旧无法度量两个词的语义相似性任意两个词之间都是孤立的比如上面的冲突和战争是近义词但是却没有任何关联性。
文档表示
同样文档也可以用词频向量的形式来表示一般我们会利用tf-idf作为每一个词的特征值之后会挑选每篇文档比较重要的部分词来表示一篇文档拿游戏来说如下 [王者荣耀, 阴阳师, 梦幻西游]
doc1:[tf-idf(王者荣耀), tf-idf(阴阳师), tf-idf(梦幻西游)]doc2:[tf-idf(王者荣耀), tf-idf(阴阳师), tf-idf(梦幻西游)]
然后我们就可以利用K-means等聚类算法进行聚类分析当然对于每篇文档一般我们只会选取部分词汇因为如果词汇过多可能造成NLP中常见的维度“灾难”。这种方式在大多数NLP场景中都是适用的但是由于这种表示往往是建立在高维空间为了避免维度灾难就要损失一定的语义信息这也是这种方法的弊端。
Distributed representation
另外一种词向量的表示Distributed representation最早由 Hinton在 1986年提出。它是一种低维实数向量这种向量一般长成这个样子 [0.792, −0.177, −0.107, 0.109, −0.542, …] 维度以 50 维和 100 维比较常见当然了这种向量的表示不是唯一的。 Distributed representation的关键点在于将高维空间中的词汇映射到一个低维的向量空间中并且让相关或者相似的词在距离上更接近看到这里大家有没有想到普通hash以及simhash的区别呢这里引用一张图片来自[13] 图中是英语和西班牙语通过训练分别得到他们的词向量空间之后利用PCA主成分分析进行降维表示在二维坐标图中的。我们可以清晰的看出对于两种语系的一二三四五在空间距离上竟是如此的相似这就是Distributed representation词向量表示的意义所在。 这种采用低维空间表示法不但解决了维数灾难问题并且挖掘了word之间的关联属性从而提高了向量语义上的准确度下面我们讨论的语言模型都是基于这种词向量表示方式。 PS. 有时候也会出现Word Represention或 Word Embedding(所谓词嵌入)的说法。另外我们这里说的词向量是在词粒度进行分析当然我们也可以在字粒度的字向量、句子粒度的句向量以及文档粒度的文档向量进行表示分析。
主题模型
在长文本的篇章处理中主题模型是一种经典的模型经常会用在自然语言处理、推荐算法等应用场景中。本节从LDA的演变过程对LDA进行阐述然后就LDA在长文本相似性的判断聚类上做简要说明。
LSA
首先对于一篇文档Document词语空间的一个词频向量如下 其中每个维度表示某一词语term在该文档中出现的次数最终对于大量的训练样本我们可以得到训练样本的矩阵X如下图 LSA的基本思想便是利用最基本的SVD奇异值分解将高维语义空间映射到低维空间其流程如下 这样对于训练样本中词表的每一个term我们便得到了一个低维空间的向量表示。但LSA的显著问题便是值考虑词频并不区分同一词语的不同含义
PLSA
LSA基于最基本的SVD分解但缺乏严谨的数理统计逻辑于是Hofmann提出了PLSA其中P便是Probabilistic其基本的假设是每个文档所表示的词频空间向量w服从多项式分布Multinomial distribution 简单扯两句多项式分布
伯努利分布Bernoulli distribution我们从接触概率论开始便知道即所谓的投硬币其离散分布如下 但是吊吊的数学家们总喜欢做一些优雅的让人看不懂的事情所以也可以写作如下公式 其中k为0或者1二项分布Binomial distribution 如果进行次投硬币实验计算出现m次正面朝上的概率 伯努利分布是二项分布中n1时的特殊情况Categorical分布Categorical distribution如果我们将投硬币改成掷骰子那么原来一维向量x就会变成一个六维向量其中每一维度为1表示出现该面0表示没出现用数学表示即对于随机变量X有k中情况其中第种情况出现的概率为 那么我们可以得到其离散概率分布如下 其中如果那么为1否则为0多项式分布Multinomial distribution与二项分布类似Categorical分布进行N次试验便得到多项式分布 同样我们可以写成吊吊的形式
其中为gamma函数当n0则ps.该形式与狄利克雷分布Dirichlet distribution的形式非常相似因为多项式分布是狄利克雷分布的共轭先验 OK简单梳理了下过去的知识PLSA假设每篇文档的词频向量服从Categorical分布那么对于整个训练样本的词频矩阵W则服从多项式分布。PLSA利用了aspect model引入了潜在变量z即所谓主题使其变成一个混合模型mixture model。其图模型如下 其中表示文档集Z便是PLSA中引入的隐含变量主题/类别表示词表。表示单词出现在文档的概率表示文档中出现主题下的单词的概率给定主题出现单词的概率。其中每个主题在所有词项上服从Multinomial分布每个文档在所有主题上服从Multinmial分布。按照生成模型整个文档的生成过程如下 (1)以的概率生成文档 (2)以的概率选中主题 (3)以的概率产生一个单词 那么对于单词出现在文档的联合概率分布而是隐含变量。 其中和分别对应了两组Multinomial分布PLSA需要训练两组分布的参数
LDA
有了PLSA那么LDA就相对简单了其相当于贝叶斯Bayes theorem PS.关于贝叶斯理论强烈推荐数学之美番外篇平凡而又神奇的贝叶斯方法一篇深入浅出的好文PLSA即 LDABayesian pLSA 为什么这么说呢我们站在贝叶斯理论的角度看上文提到的PLSA基于上文的阐述我们知道PLSA的假设是文档-词语的词频矩阵服从多项式分布multinomial distribution那么在贝叶斯理论中相当于我们找到了似然函数那么想要计算后验概率时我们需要找到先验概率。 简单扯两句共轭先验 根据贝叶斯理论我们有如下形式 OK其中我们可以成为似然函数即一件事情发生的似然性最大似然估计那么相当于先验概率分布一般为一个常数所以忽略。那么对于计算后验概率我们需要找到似然函数和先验分布。 一般当我们已知似然函数的形式的时候我们需要找到先验分布那么对于所有满足[0,1]区间内的分布都符合这个条件为了计算简单我们采用与似然函数形式尽量一致的分布作为先验分布这就是所谓的共轭先验。 在上文中介绍多项式分布时提到了Dirichlet分布我们看多项式分布的形式如下 那么我们需要找寻形式相似如下的分布 而Dirichlet分布的形式如下 看出来了吧去掉左边的Beta分布不说在右边的形式上Dirichlet分布和Multinomial分布是及其相似的所以Dirichlet分布是Multinomial分布的共轭先验。 再回到LDA根据之前分析的PLSA可知每个文档中词的Topic分布服从Multinomial分布其先验选取共轭先验即Dirichlet分布每个Topic下词的分布服从Multinomial分布其先验也同样选取共轭先验即Dirichlet分布。其图模型如下 我们可以看出LDA中每篇文章的生成过程如下
选择单词数N服从泊松分布,选择服从狄利克雷分布,对于N个单词中的每个单词 a. 选择一个主题服从多项分布, b. 以概率生成单词其中表示在主题上的条件多项式概率。
在LDA中我们可以利用来表示一篇文档。
应用
从之前LDA的阐述中我们可以利用来表示一篇文档那么我们自然可以利用这个向量对文档进行语义层面的词语和文档的相似性分析从而达到聚类、推荐的效果。当然了LDA本身对于文档分析出的主题以及每个主题下的词汇就是对于文档词汇的一层低维聚类。 之前用过Git上Java版的LDA实现但是语料不是很大对其性能并不能做出很好的评估。其地址如下 github: A Java implemention of LDA(Latent Dirichlet Allocation)
public static void main(String[] args)
{// 1. Load corpus from diskCorpus corpus Corpus.load(data/mini);// 2. Create a LDA samplerLdaGibbsSampler ldaGibbsSampler new LdaGibbsSampler(corpus.getDocument(), corpus.getVocabularySize());// 3. Train itldaGibbsSampler.gibbs(10);// 4. The phi matrix is a LDA model, you can use LdaUtil to explain it.double[][] phi ldaGibbsSampler.getPhi();MapString, Double[] topicMap LdaUtil.translate(phi, corpus.getVocabulary(), 10);LdaUtil.explain(topicMap);
}
其采用吉布斯采样的方法对LDA进行求解。之后自己也准备尝试用spark进行实现看是否能够对性能进行优化。
Word2Vec 谷歌的Tomas Mikolov团队开发了一种词典和术语表的自动生成技术能够把一种语言转变成另一种语言。该技术利用数据挖掘来构建两种语言的结构模型然后加以对比。每种语言词语之间的关系集合即“语言空间”可以被表征为数学意义上的向量集合。在向量空间内不同的语言享有许多共性只要实现一个向量空间向另一个的映射和转换语言翻译即可实现。该技术效果非常不错对英语和西语间的翻译准确率高达90%。 什么是word2vec你可以理解为word2vec就是将词表征为实数值向量的一种高效的算法模型其利用神经网络关于神经网络之前有简单进行整理马里奥AI实现方式探索 ——神经网络增强学习可以通过训练把对文本内容的处理简化为K维向量空间中的向量运算而向量空间上的相似度可以用来表示文本语义上的相似。PS. 这里往往人们会将word2vec和深度学习挂钩但其实word2vec仅仅只是用了一个非常浅层的神经网络跟深度学习的关系并不大。) Word2vec输出的词向量可以被用来做很多NLP相关的工作比如聚类、找同义词、词性分析等等。如果换个思路 把词当做特征那么Word2vec就可以把特征映射到K维向量空间可以为文本数据寻求更加深层次的特征表示 。
神经网络语言模型
word2vec的思想最早起源于2003年Yoshua Bengio等人的论文A Neural Probabilistic Language Model Traditional but very successful approaches based on n-grams obtain generalization by concatenating very short overlapping sequences seen in the training set. We propose to fight the curse of dimensionality by learning a distributed representation for words which allows each training sentence to inform the model about an exponential number of semantically neighboring sentences. [16] 从文中摘要中的这段话我们可以看出神经网络语言模型提出的初衷便是为了解决传统的n-gram模型中维度灾难的问题用distributed representation词向量的形式来表示每一个词语。 文中提出的模型利用了一个三层神经网络如下图(一般投影层算在输入层中这里分开阐述) 其中对于语料库C词典D的长度为(|D|N)为语料库C的词汇量大小。对于任意一个词表示其前n-1个词语类似于n-gram模型二元对为一个训练样本。我们为词向量词向量的维度为m。图中W,U分别为投影层和隐藏层以及隐藏层和输出层之间的权值矩阵p,q分别为隐藏层和输出层上的偏置向量。 论文中给出的神经网络模型如下图 其中C(i)表示第i个词的特征向量词向量我们看到图中第一层为词的上下文的每个词向量在第二层我们将输入层的n-1个词向量按顺序首尾拼接在一起形成一个长向量其长度为(n-1)m输入到激活函数tanh双曲正切函数中计算方式如下 经过上述两步计算得到的只是一个长度为N的向量我们看到图中第三层还做了一次softmaxSoftmax function归一化归一化后 就可以表示为 为词在词典D中的索引。 在之前的背景知识n-gram模型 我们知道语言模型中很关键的便是F的确定其中参数如下
词向量以及填充向量上下文词汇不够n时神经网络参数
论文的主要贡献有一下两点
词语之间的相似性可以通过词向量来表示 不同于之前我们讨论的One-hot Representation表示方式论文中指出在进行训练时向量空间表达的词语维度一般为30、60或100远远小于词典长度17000避免了维度灾难。同时语义相似句子的概率是相似的。比如某个语料库中的两个句子S1A dog is running in the room, S2A cat is running in the room两个句子从语义上看仅仅是在dog和cat处有一点区别假设在语料库中S11000即出现1000次而S21即仅出现一次按照之前我们讲述的n-gram模型p(S1)p(S2)但是我们从语义上来看dog和cat在句子中无论从句法还是语义上都扮演了相似的角色所以两者概率应该相似才对。 而神经网络语言模型可以做到这一点原因是1在神经网络语言模型中假设了相似的词在词向量上也是相似的即向量空间中的距离相近2模型中的概率函数关于词向量是光滑的那么词向量的一个小变化对概率的影响也是一个小变化这样下面的句子 A dog is ruuning in the room A cat is running in the room The cat is running in the room A dog is walking in the bedroom The dog was walking in the bedroom
只要在语料库中出现一个其他句子的概率也会相应增大。
基于词向量的模型在概率计算上已经是平滑的不需要像n-gram模型一样做额外的平滑处理因为在softmax阶段我们已经做了归一化有了平滑性。
我们最终训练得到的词向量在整个神经网络模型中似乎只是一个参数但是这个副作用也正是word2vec中的核心产物。
CBOW和Skip-gram模型
word2vec中用到了两个重要模型CBOW(Continuous Bag-of-Words Model)和Skip-gram(Continuous Skip-gram Model)模型文中作者Tomas Mikolov[17]给出了模型图如下 由图中我们看出word2vec是一个三层结构的神经网络输入层、投影层和输出层这里我们发现word2vec与上面我们阐述的神经网络模型的显著区别是去掉了隐藏层。对于图中左边的CBOW模型是已知当前词的上下文的前提下预测当前词而正好相反Skip-gram模型是已知当前词的前提下来预测其上下文。 CBOW模型的目标函数即其对数似然函数形式如下 而Skip-gram模型的优化目标函数则形如 Mikolov在word2vec中提出了两套框架Hieraichical Softmax和Negative Sampling这里由于博文篇幅太长了就不错过多阐述只对基于Hieraichical Softmax的CBOW模型进行简单总结。 CBOW模型中与之前神经网络语言模型类似表示一个样本其中表示词的前后各c个词语共2c个其三层结构我们可以细化如下
输入层包含中2c个词的词向量每个词向量的维度都是m投影层将输入层的2c个词向量做求和累加即输出层输出层对应一颗二叉树它是以语料中出现过的词作为叶子节点以各词在语料中出现的次数作为权重构造出来的一颗Huffman树Huffman coding其叶子节点共N(|D|)个对应语料库D中的各个词非叶子节点为N-1个。
对比我们之前讨论的最早的神经网络语言模型CBOW模型的区别主要为以下三点
从输入层到投影层的操作前者通过拼接而后者通过累加求和前者有隐藏层后者无隐藏层输出层前者是线性结构softmax后者是树形结构Hierarchical softmax
word2vec对于词典D中的任意词Huffman树必存在一条从根结点到词的路径且唯一。路径上存在个分支每条路径上的总结点数为将每个分支看做一次二次分类每一次分类产生一个概率将这些概率乘起来便是所需的。在二分类的过程中可以利用Huffman编码值即左树为1右树为0进行逻辑回归分类。 word2vec在求解的过程中主要利用了梯度下降的方法调整学习率这里我们不再长篇大论的阐述具体可以参考文献[14]对word2vec中的数学原理阐述的非常清晰。
应用
word2vec从被发布起就是各种大红大紫在谷歌的翻译系统中得到了很好的验证。围绕本篇博文的主题即文本相似度的度量word2vec产生的词向量可以非常方便的让我们做这件事情利用欧氏距离或者cos都可以。 在之前Wetest舆情项目做句法分析时需要找寻某一个词的同类词语我们用用户的游戏评论训练word2vec效果还是不错的如下图 对于游戏的人工想到的维度词进行同类扩展得到扩展维度词。 之前在应用时是自己师兄使用的python版word2vec而Java对于word2vec有一个较好的东东DL4J但其性能我并没有经过大规模预料测试这个大家用的时候需谨慎。
OK长舒一口气~好长的一篇整理整个文章虽然涵盖了好多个模型、算法但是围绕的一个主题便是如何度量两个文本之间的相似性从字面和语义两个角度对自己平时用过接触过的模型算法进行整理归纳如有任何纰漏还请留言指出我会第一时间改正。感谢身边的同事和大神给予的指导帮助
参考文献
莱文斯坦距离Commons LangJaro–Winkler distance字符串相似算法-(1) Jaro-Winkler DistanceProbabilistic Latent Semantic Indexing Thomas Hofmann[Algorithm NLP] 文本深度表示模型——word2vecdoc2vec词向量模型数学之美番外篇平凡而又神奇的贝叶斯方法概率语言模型及其变形系列(1)-PLSA及EM算法概率语言模型及其变形系列(2)-LDA及Gibbs Sampling[Algorithm] 使用SimHash进行海量文本去重海量数据相似度计算之simhash短文本查找word2vec 中的数学原理详解DL4J机器翻译领域的新突破word2vec 中的数学原理详解《统计自然语言处理第2版》 宗成庆A Neural Probabilistic Language ModelExploiting Similarities among Languages for Machine Translation 分类: NLP 标签: 文本相似度, LDA, word2vec, simhash, 自然语言处理, 编辑距离 好文要顶 关注我 收藏该文 xlturing 关注 - 0 粉丝 - 92 加关注 6 0 « 上一篇马里奥AI实现方式探索 ——神经网络增强学习» 下一篇Spark踩坑记——Spark StreamingKafka /divdiv classpostDescposted span idpost-date2016-12-06 10:50/span a hrefhttps://www.cnblogs.com/xlturing/xlturing/a 阅读(span idpost_view_count10295/span) 评论(span idpost_comment_count6/span) a hrefhttps://i.cnblogs.com/EditPosts.aspx?postid6136690 relnofollow编辑/a a href# AddToWz(6136690);return false;收藏/a/div
/div
script src//common.cnblogs.com/highlight/9.12.0/highlight.min.js/scriptscriptmarkdown_highlight();/scriptscript typetext/javascriptvar allowCommentstrue,cb_blogId150286,cb_entryId6136690,cb_blogAppcurrentBlogApp,cb_blogUserGuid7d97d526-35b5-e211-83e8-90b11c0b17d6,cb_entryCreatedDate2016/12/6 10:50:00;loadViewCount(cb_entryId);var cb_postType1;var isMarkdowntrue;/script评论列表 div classfeedbackItemdiv classfeedbackListSubtitlediv classfeedbackManagenbsp;nbsp;span classcomment_actions/span/diva href#3573416 classlayer#1楼/aa name3573416 idcomment_anchor_3573416/a span classcomment_date2016-12-06 11:29/span a ida_comment_author_3573416 hrefhttps://www.cnblogs.com/ddx-deng/ target_blankdeeeeeed/a a hrefhttp://msg.cnblogs.com/send/deeeeeed title发送站内短消息 classsendMsg2Thisnbsp;/a/divdiv classfeedbackCondiv idcomment_body_3573416 classblog_comment_body可以看出作者的知识储备并且在这篇文章上下了功夫/divdiv classcomment_votea hrefjavascript:void(0); classcomment_digg return voteComment(3573416,Digg,this)支持(0)/aa hrefjavascript:void(0); classcomment_bury return voteComment(3573416,Bury,this)反对(0)/a/divspan idcomment_3573416_avatar styledisplay:none;http://pic.cnblogs.com/face/622385/20140410162948.png/span/div/divdiv classfeedbackItemdiv classfeedbackListSubtitlediv classfeedbackManagenbsp;nbsp;span classcomment_actions/span/diva href#3573421 classlayer#2楼/aa name3573421 idcomment_anchor_3573421/a span classcomment_date2016-12-06 11:30/span a ida_comment_author_3573421 hrefhttps://www.cnblogs.com/goodfulcom/ target_blank码有钱/a a hrefhttp://msg.cnblogs.com/send/%E7%A0%81%E6%9C%89%E9%92%B1 title发送站内短消息 classsendMsg2Thisnbsp;/a/divdiv classfeedbackCondiv idcomment_body_3573421 classblog_comment_body干货加油/divdiv classcomment_votea hrefjavascript:void(0); classcomment_digg return voteComment(3573421,Digg,this)支持(0)/aa hrefjavascript:void(0); classcomment_bury return voteComment(3573421,Bury,this)反对(0)/a/divspan idcomment_3573421_avatar styledisplay:none;http://pic.cnblogs.com/face/u162282.jpg?id19203843/span/div/divdiv classfeedbackItemdiv classfeedbackListSubtitlediv classfeedbackManagenbsp;nbsp;span classcomment_actions/span/diva href#3573449 classlayer#3楼/aa name3573449 idcomment_anchor_3573449/a span classcomment_date2016-12-06 11:48/span a ida_comment_author_3573449 hrefhttps://www.cnblogs.com/zssxfc/ target_blankzssxfc/a a hrefhttp://msg.cnblogs.com/send/zssxfc title发送站内短消息 classsendMsg2Thisnbsp;/a/divdiv classfeedbackCondiv idcomment_body_3573449 classblog_comment_body清晰详细/divdiv classcomment_votea hrefjavascript:void(0); classcomment_digg return voteComment(3573449,Digg,this)支持(0)/aa hrefjavascript:void(0); classcomment_bury return voteComment(3573449,Bury,this)反对(0)/a/div/div/divdiv classfeedbackItemdiv classfeedbackListSubtitlediv classfeedbackManagenbsp;nbsp;span classcomment_actions/span/diva href#3573586 classlayer#4楼/aa name3573586 idcomment_anchor_3573586/a span classcomment_date2016-12-06 14:07/span a ida_comment_author_3573586 hrefhttps://www.cnblogs.com/TextEditor/ target_blankcodesnippet.info/a a hrefhttp://msg.cnblogs.com/send/codesnippet.info title发送站内短消息 classsendMsg2Thisnbsp;/a/divdiv classfeedbackCondiv idcomment_body_3573586 classblog_comment_bodyNLP这块以后也是很大的市场。/divdiv classcomment_votea hrefjavascript:void(0); classcomment_digg return voteComment(3573586,Digg,this)支持(0)/aa hrefjavascript:void(0); classcomment_bury return voteComment(3573586,Bury,this)反对(0)/a/divspan idcomment_3573586_avatar styledisplay:none;http://pic.cnblogs.com/face/75847/20160425114402.png/span/div/divdiv classfeedbackItemdiv classfeedbackListSubtitlediv classfeedbackManagenbsp;nbsp;span classcomment_actions/span/diva href#4021637 classlayer#5楼/aa name4021637 idcomment_anchor_4021637/a span classcomment_date2018-07-16 19:37/span a ida_comment_author_4021637 hrefhttp://home.cnblogs.com/u/1401872/ target_blank颦儿爱兮兮/a a hrefhttp://msg.cnblogs.com/send/%E9%A2%A6%E5%84%BF%E7%88%B1%E5%85%AE%E5%85%AE title发送站内短消息 classsendMsg2Thisnbsp;/a/divdiv classfeedbackCondiv idcomment_body_4021637 classblog_comment_body干货~谢谢作者加油/divdiv classcomment_votea hrefjavascript:void(0); classcomment_digg return voteComment(4021637,Digg,this)支持(0)/aa hrefjavascript:void(0); classcomment_bury return voteComment(4021637,Bury,this)反对(0)/a/div/div/divdiv classfeedbackItemdiv classfeedbackListSubtitlediv classfeedbackManagenbsp;nbsp;span classcomment_actions/span/diva href#4188757 classlayer#6楼/aa name4188757 idcomment_anchor_4188757/aspan idcomment-maxId styledisplay:none;4188757/spanspan idcomment-maxDate styledisplay:none;2019/2/26 19:21:32/span span classcomment_date2019-02-26 19:21/span a ida_comment_author_4188757 hrefhttps://www.cnblogs.com/daletxt/ target_blankDaletxt/a a hrefhttp://msg.cnblogs.com/send/Daletxt title发送站内短消息 classsendMsg2Thisnbsp;/a/divdiv classfeedbackCondiv idcomment_body_4188757 classblog_comment_body太有深度了目前一下子消化不了收藏了以后慢慢咀嚼/divdiv classcomment_votea hrefjavascript:void(0); classcomment_digg return voteComment(4188757,Digg,this)支持(0)/aa hrefjavascript:void(0); classcomment_bury return voteComment(4188757,Bury,this)反对(0)/a/div/div/div
div idcomments_pager_bottom/div/divscript typetext/javascriptvar commentManager new blogCommentManager();commentManager.renderComments(0);/script刷新评论刷新页面返回顶部 注册用户登录后才能发表评论请 登录 或 注册访问网站首页。 【推荐】超50万C/C#源码: 大型实时仿真组态图形源码【推荐】百度云“猪”你开年行大运红包疯狂拿低至1折【推荐】专业便捷的企业级代码托管服务 - Gitee 码云【活动】2019第四届全球人工技术大会解码“智能时代” /div!--end: forFlow --
/div看了这么多文章我自己是觉得李航的《统计学习方法》里面用了一些很简单的方式介绍了经典分类、预测、回归等问题。其中不同的场景涉及到不同的损失函数基本思想是通过测量模型的预测值与实际值两者的累计差异来反映模型的好坏。其中的差异一般是通过距离来度量常用的是欧式距离不受维度的限制。为什么不用曼哈顿距离马氏距离,原因它们只能测连个样本点的水平距离或垂直距离。主要包括以下内容
全新的界面设计 将会带来全新的写作体验在创作中心设置你喜爱的代码高亮样式Markdown 将代码片显示选择的高亮样式 进行展示增加了 图片拖拽 功能你可以将本地的图片直接拖拽到编辑区域直接展示全新的 KaTeX数学公式 语法增加了支持甘特图的mermaid语法1 功能增加了 多屏幕编辑 Markdown文章功能增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能功能按钮位于编辑区域与预览区域中间增加了 检查列表 功能。
功能快捷键
撤销Ctrl/Command Z 重做Ctrl/Command Y 加粗Ctrl/Command B 斜体Ctrl/Command I 标题Ctrl/Command Shift H 无序列表Ctrl/Command Shift U 有序列表Ctrl/Command Shift O 检查列表Ctrl/Command Shift C 插入代码Ctrl/Command Shift K 插入链接Ctrl/Command Shift L 插入图片Ctrl/Command Shift G
合理的创建标题有助于目录的生成
直接输入1次#并按下space后将生成1级标题。 输入2次#并按下space后将生成2级标题。 以此类推我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。
如何改变文本的样式
强调文本 强调文本
加粗文本 加粗文本
标记文本
删除文本 引用文本 H2O is是液体。
210 运算结果是 1024.
插入链接与图片
链接: link.
图片:
带尺寸的图片:
居中的图片:
居中并且带尺寸的图片:
当然我们为了让用户更加便捷我们增加了图片拖拽功能。
如何插入一段漂亮的代码片
去博客设置页面选择一款你喜欢的代码片高亮样式下面展示同样高亮的 代码片.
// An highlighted block
var foo bar;生成一个适合你的列表
项目 项目 项目
项目1项目2项目3 计划任务 完成任务
创建一个表格
一个简单的表格是这么创建的
项目Value电脑$1600手机$12导管$1
设定内容居中、居左、居右
使用:---------:居中 使用:----------居左 使用----------:居右
第一列第二列第三列第一列文本居中第二列文本居右第三列文本居左
SmartyPants
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如
TYPEASCIIHTMLSingle backticksIsnt this fun?‘Isn’t this fun?’QuotesIsnt this fun?“Isn’t this fun?”Dashes-- is en-dash, --- is em-dash– is en-dash, — is em-dash
创建一个自定义列表 MarkdownText-to-HTML conversion tool AuthorsJohn Luke 如何创建一个注脚
一个具有注脚的文本。2
注释也是必不可少的
Markdown将文本转换为 HTML。
KaTeX数学公式
您可以使用渲染LaTeX数学表达式 KaTeX:
Gamma公式展示 Γ(n)(n−1)!∀n∈N\Gamma(n) (n-1)!\quad\forall n\in\mathbb NΓ(n)(n−1)!∀n∈N 是通过欧拉积分
Γ(z)∫0∞tz−1e−tdtThinSpace;.\Gamma(z) \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)∫0∞tz−1e−tdt. 你可以找到更多关于的信息 LaTeX 数学表达式here. 新的甘特图功能丰富你的文章
Mon 06Mon 13Mon 20已完成 进行中 计划一 计划二 现有任务Adding GANTT diagram functionality to mermaid关于 甘特图 语法参考 这儿,
UML 图表
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:
张三李四王五你好李四, 最近怎么样?你最近怎么样王五我很好谢谢!我很好谢谢!李四想了很长时间,文字太长了不适合放在一行.打量着王五...很好... 王五, 你怎么样?张三李四王五这将产生一个流程图。:
链接长方形圆圆角长方形菱形关于 Mermaid 语法参考 这儿,
FLowchart流程图
我们依旧会支持flowchart的流程图
Created with Raphaël 2.2.0开始我的操作确认结束yesno关于 Flowchart流程图 语法参考 这儿.
导出与导入
导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 生成一个.md文件或者.html文件进行本地保存。
导入
如果你想加载一篇你写过的.md文件或者.html文件在上方工具栏可以选择导入功能进行对应扩展名的文件导入 继续你的创作。 mermaid语法说明 ↩︎ 注脚的解释 ↩︎