包含n-gramjava的词条

博主:adminadmin 2023-01-02 17:03:06 829

今天给各位分享n-gramjava的知识,其中也会对进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

自然语言处理(NLP)的基础难点:分词算法

自然语言处理(NLP,Natural Language Processing)是人工智能领域中的一个重要方向,主要研究人与计算机之间用自然语言进行有效通信的各种理论和方法。自然语言处理的底层任务由易到难大致可以分为词法分析、句法分析和语义分析。分词是词法分析(还包括词性标注和命名实体识别)中最基本的任务,也是众多NLP算法中必不可少的第一步,其切分准确与否往往与整体结果息息相关。

金融领域分词的难点

分词既简单又复杂。简单是因为分词的算法研究已经很成熟了,大部分的算法(如HMM分词、CRF分词)准确率都可以达到95%以上;复杂则是因为剩下的5%很难有突破,主要可以归结于三点:

▲粒度,即切分时的最小单位,不同应用对粒度的要求不一样,比如“融资融券”可以是一个词也可以是两个词

▲歧义,比如“恒生”一词,既可指恒生公司,又可指恒生指数

▲未登录词,即未出现在算法使用的词典中的词,比如不常见的专业金融术语,以及各种上市公司的名称

在金融领域中,分词也具有上述三个难点,并且在未登录词方面的难点更为突出,这是因为金融类词汇本来就多,再加上一些专有名词不仅有全称还有简称,这就进一步增大了难度。

在实际应用中,以上难点时常会造成分词效果欠佳,进而影响之后的任务。尤其是在一些金融业务中,有许多需要与用户交互的场景,某些用户会用口语化的词汇描述业务,如果分词错误会影响用户意图的解析,这对分词的准确性提出了更高的要求。因此在进行NLP上层应用开发时,需要对分词算法有一定的了解,从而在效果优化时有能力对分词器进行调整。接下来,我们介绍几种常用的分词算法及其应用在金融中的优劣。

几种常见的分词算法

分词算法根据其核心思想主要分为两种:

第一种是基于字典的分词,先把句子按照字典切分成词,再寻找词的最佳组合方式,包括最大匹配分词算法、最短路径分词算法、基于N-Gram model的分词算法等;

第二种是基于字的分词,即由字构词,先把句子分成一个个字,再将字组合成词,寻找最优的切分策略,同时也可以转化成序列标注问题,包括生成式模型分词算法、判别式模型分词算法、神经网络分词算法等。

最大匹配分词寻找最优组合的方式是将匹配到的最长词组合在一起,主要的思路是先将词典构造成一棵Trie树(也称为字典树),Trie树由词的公共前缀构成节点,降低了存储空间的同时可以提升查找效率。

最大匹配分词将句子与Trie树进行匹配,在匹配到根结点时由下一个字重新开始进行查找。比如正向(从左至右)匹配“他说的确实在理”,得出的结果为“他/说/的确/实在/理”。如果进行反向最大匹配,则为“他/说/的/确实/在理”。

这种方式虽然可以在O(n)时间对句子进行分词,但是只单向匹配太过绝对,尤其是金融这种词汇较丰富的场景,会出现例如“交易费/用”、“报价单/位”等情况,所以除非某些词的优先级很高,否则要尽量避免使用此算法。

最短路径分词算法首先将一句话中的所有词匹配出来,构成词图(有向无环图DAG),之后寻找从起始点到终点的最短路径作为最佳组合方式,例:

我们认为图中每个词的权重都是相等的,因此每条边的权重都为1。

在求解DAG图的最短路径问题时,总是要利用到一种性质:即两点之间的最短路径也包含了路径上其他顶点间的最短路径。比如S-A-B-E为S到E到最短路径,那S-A-B一定是S到B到最短路径,否则会存在一点C使得d(S-C-B)d(S-A-B),那S到E的最短路径也会变为S-C-B-E,这就与假设矛盾了。利用上述的最优子结构性质,可以利用贪心算法或动态规划两种求解算法:

(1)基于Dijkstra算法求解最短路径,该算法适用于所有带权有向图,求解源节点到其他所有节点的最短路径,并可以求得全局最优解;

(2)N-最短路径分词算法,该方法是对Dijkstra算法的扩展,在每一步保存最短的N条路径,并记录这些路径上当前节点的前驱,在最后求得最优解时回溯得到最短路径。这种方法的准确率优于Dijkstra算法,但在时间和空间复杂度上都更大。

相较于最大匹配分词算法,最短路径分词算法更加灵活,可以更好地把词典中的词组合起来,能更好地解决有歧义的场景。比如上述“他说的确实在理”这句话,用最短路径算法的计算结果为“他/说/的/确实/在理”,避免了正向最大匹配的错误。但是对于词典中未存在的词基本没有识别能力,无法解决金融领域分词中的“未登录词”难点。

N-Gram(又称N元语法模型)是基于一个假设:第n个词出现与前n-1个词相关,而与其他任何词不相关。在此种假设下,可以简化词的条件概率,进而求解整个句子出现的概率。

现实中,常用词的出现频率或者概率肯定比罕见词要大。因此,可以将求解词图最短路径的问题转化为求解最大概率路径的问题,即分词结果为“最有可能的词的组合“。

计算词出现的概率,仅有词典是不够的,还需要充足的语料,所以分词任务已经从单纯的“算法”上升到了“建模”,即利用统计学方法结合大数据挖掘,对“语言”(句子出现的概率)进行建模。

我们将基于N-gram模型所统计出的概率分布应用到词图中,可以得到词的概率图。对该词图用最短路径分词算法求解最大概率的路径,即可得到分词结果。

相较于前两种分词算法,基于N-Gram model的分词算法对词频进行了统计建模,在切分有歧义的时候力求得到全局最优值,比如在切分方案“证券/自营/业务”和“证券/自/营业/务”中,统计出“证券/自营/业务”出现的概率更大,因此结果有更高的准确率。但也依然无法解决金融场景中未登录词的问题。

生成式模型主要有隐马尔可夫模型(HMM,Hidden Markov Model)、朴素贝叶斯分类等。HMM是常用的分词模型,基于Python的jieba分词器和基于Java的HanLP分词器都使用了HMM。

HMM模型认为在解决序列标注问题时存在两种序列,一种是观测序列,即人们显性观察到的句子,另一种是隐状态序列,即观测序列的标签。假设观测序列为X,隐状态序列是Y,则因果关系为Y-X。因此要得到标注结果Y,必须对X的概率、Y的概率、P(X|Y)进行计算,即建立P(X,Y)的概率分布模型。

HMM算法可以在一定程度上解决未登录词的问题,但生成式模型的准确率往往没有接下来要谈到的判别式模型高。

判别式模型主要有感知机、支持向量机(SVM,Support Vector Machine)、条件随机场(CRF,Conditional Random Field)、最大熵模型等,其中感知机模型和CRF模型是常用的分词模型。

(1)平均感知机分词算法

感知机是一种简单的二分类线性模型,通过构造超平面,将特征空间(输入空间)中的样本分为正负两类。通过组合,感知机也可以处理多分类问题。但由于每次迭代都会更新模型的所有权重,被误分类的样本会造成很大影响,因此采用平均的方法,在处理完一部分样本后对更新的权重进行平均。

(2)CRF分词算法

CRF可以看作一个无向图模型,假设给定的标注序列为Y,观测序列为X,CRF对条件概率P(Y|X)进行定义,而不是对联合概率建模。

平均感知机算法虽然速度快,但仍不够准确。适合一些对速度要求高、对准确性要求相对不那么高的场景。CRF分词算法可以说是目前最常用的分词、词性标注和实体识别算法,它对未登陆词也有很好的识别能力,是目前在速度、准确率以及未登录词识别上综合表现最突出的算法,也是我们目前所采用的解决方案,但速度会比感知机慢一些。

在NLP中,最常用的神经网络为循环神经网络(RNN,Recurrent Neural Network),它在处理变长输入和序列输入问题中有着巨大的优势。LSTM(Long Short-Term Memory,长短期记忆网络)为RNN变种的一种,在一定程度上解决了RNN在训练过程中梯度消失和梯度爆炸的问题。

目前对于序列标注任务,业内公认效果最好的模型是BiLSTM+CRF。相比于上述其它模型,双向循环神经网络BiLSTM,可以更好地编码当前字等上下文信息,并在最终增加CRF层,核心是用Viterbi算法进行解码,以得到全局最优解,避免B,S,E这种不可能的标记结果的出现,提高准确率。

神经网络分词虽然能在准确率、未登录词识别上有更好的表现,但RNN无法并行计算,在速度上没有优势,所以该算法通常在算法研究、句子精确解析等对速度要求不高的场景下使用。

分词作为NLP底层任务之一,既简单又重要,很多时候上层算法的错误都是由分词结果导致的。因此,对于底层实现的算法工程师,不仅需要深入理解分词算法,更需要懂得如何高效地实现和调试。

而对于上层应用的算法工程师,在实际分词时,需要根据业务场景有选择地应用上述算法,比如在搜索引擎对大规模网页进行内容解析时,对分词对速度要求大于精度,而在智能问答中由于句子较短,对分词的精度要求大于速度。

什么是N-Gram

该模型基于这样一种假设,第n个词的出现只与前面N-1个词相关,而与其它任何词都不相关,整句的概率就是各个词出现概率的乘积。这些概率可以通过直接从语料中统计N个词同时出现的次数得到。常用的是二元的Bi-Gram和三元的Tri-Gram。如果一个词的出现仅依赖于它前面出现的一个词,那么我们就称之为bigram。如果一个词的出现仅依赖于它前面出现的两个词,那么我们就称之为trigram。在实践中用的最多的就是bigram和trigram了,而且效果很不错。高于四元的用的很少,因为训练它需要更庞大的语料,而且数据稀疏严重,时间复杂度高,精度却提高的不多。

通俗理解n-gram语言模型

假设现在语料库的词汇量为 ,对于长度为 的句子来说:

通过上面的表格可以看出,增加条件概率中的条件相对应的参数数量会呈现指数的增长。参数的数量越多表示模型相对越复杂。如果我们想要减少参数,最简单的方法就是简化模型,考虑极端情况下只保留 ,此时计算句子的概率公式为:

依然使用上面我们自己构建的小型语料库:

如果想要计算p(BOS 商品 和 服务 EOS)的概率,只需要计算出p(BOS)、p(商品)、p(和)、p(服务)以及p(EOS)的五个概率值(依然使用最大似然估计来计算这些概率值):

因此p(商品 和 服务) = p(BOS) p(商品) p(和) p(服务) p(EOS) = = 。

不使用条件概率使用 认为当前单词出现的概率仅仅本身相关, 我们称之为unigram,即一元语言模型。从 个参数缩减到了拥有 个参数的一元语言模型,显然模型太简单了。比如对于下面两个句子:

如果使用一元语言模型来这两个句子的概率值。

通过一元语言模型计算两个句子主要区别就在于p(篮球)和p(游泳)的概率值,其余概率值都是相同的,但是就两句话而言,"我 打 篮球"这句话要比"我 打 游泳"这句话的概率值要高很多。由于简化了模型,仅仅考虑当前单词的出现概率与本身有关,单词与单词之间是相互独立的。不过就上面两个句子而言,p(篮球 | 打) 要比p(游泳 | 打)的概率值要高,此时仅仅考虑当前单词自身的一元语言模型太简单了。

假设当前单词的出现概率仅仅与前面的1个单词相关, 我们称之为bigram,即二元语言模型。二元语言模型的计算公式:

假设当前单词的出现概率仅仅与前面的2个单词相关, 我们称之为trigram,即三元语言模型。三元语言模型的计算公式:

以此类推,假设当前单词的出现概率仅仅与前面的 个单词相关,我们称之为n-gram语言模型。这种减少参数简化模型的假设方法就是马尔科夫假设。

随着 的取值越大,n-gram模型在理论上越精确,但是也越复杂,需要的计算量和训练语料数据量也就越大,并且精度提升的不够明显,所以在实际的任务中很少使用 的语言模型。

无论是原始的语言模型还是n-gram语言模型,都是使用极大似然估计法来估计概率值,通过统计频次来近似概率值,统计频次极有可能统计不到较长句子的频次。

这被称为数据稀疏,对于n-gram语言模型来说,n越大,数据稀疏的问题越严重。即使是使用n相对比较小的二元语言模型,许多二元靠语料库也是统计不到的。比如对于下面这个小型的语料库:

"商品 货币"的频次就为0,当n-gram语言模型中的n越小,可统计的n元也就越丰富,一个很自然的解决方案就是利用低阶n元语法平滑到高阶n元语法。所谓的平滑就是字面上的意思:使n元语法频次的折线平滑为曲线。我们不希望二元语法"商品 货币"的频次突然跌倒0,因此使用一元语法"商品"和("或",不同的平滑方法可能需要不同的处理)"货币"的频次去平滑它。

平滑策略是语言模型的研究课题之一,人们提出了很多平滑技术,比如线性差值法(linear interpolation)、图灵平滑(Good-Turing)、加法平滑(Add-One Smoothing)等。

原文地址:

通俗理解n-gram语言模型

自然语言处理中的N-Gram模型详解

N-Gram(有时也称为N元模型)是 自然语言 处理中一个非常重要的概念,通常在NLP中,人们基于一定的语料库,可以利用N-Gram来预计或者评估一个句子是否合理。另外一方面,N-Gram的另外一个作用是用来评估两个字符串之间的差异程度。这是模糊匹配中常用的一种手段。本文将从此开始,进而向读者展示N-Gram在自然语言处理中的各种powerful的应用。

基于N-Gram模型定义的字符串距离

利用N-Gram模型评估语句是否合理

使用N-Gram模型时的数据平滑算法

欢迎关注白马负金羁的博客 ,为保证公式、图表得以正确显示,强烈建议你从该地址上查看原版博文。本博客 主要关注方向 包括:数字图像处理、 算法 设计与分析、 数据结构 、 机器学习 、数据挖掘、统计分析方法、自然语言处理。

基于N-Gram模型定义的字符串距离

在自然语言处理时,最常用也最基础的一个操作是就是“模式匹配”,或者称为“字符串查找”。而模式匹配(字符串查找)又分为 精确匹配 和 模糊匹配 两种。

所谓精确匹配,大家应该并不陌生,比如我们要统计一篇文章中关键词 “ information ” 出现的次数,这时所使用的方法就是精确的模式匹配。这方面的算法也比较多,而且应该是计算机相关专业必修的基础课中都会涉及到的内容,例如KMP算法、BM算法和BMH算法等等。

另外一种匹配就是所谓的模糊匹配,它的应用也随处可见。例如,一般的文字处理软件(例如,Microsoft Word等)都会提供拼写检查功能。当你输入一个错误的单词,例如 “ informtaion ” 时,系统会提示你是否要输入的词其实是 “ information ” 。将一个可能错拼单词映射到一个推荐的正确拼写上所采用的技术就是模糊匹配。

模糊匹配的关键在于如何衡量两个长得很像的单词(或字符串)之间的“差异”。这种差异通常又称为“距离”。这方面的具体算法有很多,例如基于编辑距离的概念,人们设计出了 Smith-Waterman 算法和Needleman-Wunsch 算法,其中后者还是历史上最早的应用动态规划思想设计的算法之一。现在Smith-Waterman 算法和Needleman-Wunsch 算法在生物信息学领域也有重要应用,研究人员常常用它们来计算两个DNA序列片段之间的“差异”(或称“距离”)。甚至于在LeetCode上也有一道 “No.72 Edit Distance” ,其本质就是在考察上述两种算法的实现。可见相关问题离我们并不遥远。

N-Gram在模糊匹配中的应用

事实上,笔者在新出版的 《算法之美——隐匿在数据结构背后的原理》 一书中已经详细介绍了包括Needleman-Wunsch算法、Smith-Waterman算法、N-Gram算法、Soundex算法、Phonix算法等在内的多种距离定义算法(或模糊匹配算法)。而今天为了引出N-Gram模型在NLP中的其他应用,我们首先来介绍一下如何利用N-Gram来定义字符串之间的距离。

我们除了可以定义两个字符串之间的编辑距离(通常利用Needleman-Wunsch算法或Smith-Waterman算法)之外,还可以定义它们之间的N-Gram距离。N-Gram(有时也称为N元模型)是自然语言处理中一个非常重要的概念。假设有一个字符串 s

,那么该字符串的N-Gram就表示按长度 N 切分原词得到的词段,也就是 s

中所有长度为 N 的子字符串。设想如果有两个字符串,然后分别求它们的N-Gram,那么就可以从它们的共有子串的数量这个角度去定义两个字符串间的N-Gram距离。但是仅仅是简单地对共有子串进行计数显然也存在不足,这种方案显然忽略了两个字符串长度差异可能导致的问题。比如字符串 girl 和 girlfriend,二者所拥有的公共子串数量显然与 girl 和其自身所拥有的公共子串数量相等,但是我们并不能据此认为 girl 和girlfriend 是两个等同的匹配。

为了解决该问题,有学者便提出以非重复的N-Gram分词为基础来定义 N-Gram距离这一概念,可以用下面的公式来表述:

|GN(s)|+|GN(t)|−2×|GN(s)∩GN(t)|

此处,|GN(s)|

是字符串 s

的 N-Gram集合,N 值一般取2或者3。以 N = 2 为例对字符串Gorbachev和Gorbechyov进行分段,可得如下结果(我们用下画线标出了其中的公共子串)。

有兴趣的读者可以在引用相关JAR包之后在Eclipse中执行上述Java程序,你会发现,和我们预期的一样,字符串Gorbachev和Gorbechyov所得之距离评分较高(=0.7),说明二者很接近;而girl和girlfriend所得之距离评分并不高(=0.3999),说明二者并不很接近。

利用N-Gram模型评估语句是否合理

从现在开始,我们所讨论的N-Gram模型跟前面讲过N-Gram模型从外在来看已经大不相同,但是请注意它们内在的联系(或者说本质上它们仍然是统一的概念)。

为了引入N-Gram的这个应用,我们从几个例子开始。首先,从统计的角度来看,自然语言中的一个句子 s

可以由任何词串构成,不过概率 P(s)

有大有小。例如:

s1

= 我刚吃过晚饭

s2

= 刚我过晚饭吃

显然,对于中文而言 s1

是一个通顺而有意义的句子,而s2

则不是,所以对于中文来说,P(s1)P(s2)

。但不同语言来说,这两个概率值的大小可能会反转。

其次,另外一个例子是,如果我们给出了某个句子的一个节选,我们其实可以能够猜测后续的词应该是什么,例如

the large green __ . Possible answer may be “mountain” or “tree” ?

Kate swallowed the large green __ . Possible answer may be “pill” or “broccoli” ?

显然,如果我们知道这个句子片段更多前面的内容的情况下,我们会得到一个更加准确的答案。这就告诉我们,前面的(历史)信息越多,对后面未知信息的约束就越强。

如果我们有一个由 m

个词组成的序列(或者说一个句子),我们希望算得概率 P(w1,w2,⋯,wm)

,根据链式规则,可得

P(w1,w2,⋯,wm)=P(w1)P(w2|w1)P(w3|w1,w2)⋯P(wm|w1,⋯,wm−1)

这个概率显然并不好算,不妨利用马尔科夫链的假设,即当前这个词仅仅跟前面几个有限的词相关,因此也就不必追溯到最开始的那个词,这样便可以大幅缩减上诉算式的长度。即P(wi|w1,⋯,wi−1)=P(wi|wi−n+1,⋯,wi−1)

特别地,对于 n

取得较小值的情况当 n=1

, 一个一元模型(unigram model)即为P(w1,w2,⋯,wm)=∏i=1mP(wi)

当 n=2

, 一个二元模型(bigram model)即为P(w1,w2,⋯,wm)=∏i=1mP(wi|wi−1)

当 n=3

, 一个三元模型(trigram model)即为P(w1,w2,⋯,wm)=∏i=1mP(wi|wi−2wi−1)

接下来的思路就比较明确了,可以利用最大似然法来求出一组参数,使得训练样本的概率取得最大值。

对于unigram model而言,其中c(w1,..,wn)

表示 n-gram w1,..,wn

在训练语料中出现的次数,M

是语料库中的总字数(例如对于 yes no no no yes 而言,M=5

)P(wi)=C(wi)M

对于bigram model而言,P(wi|wi−1)=C(wi−1wi)C(wi−1)

对于n

-gram model而言,P(wi|wi−n−1,⋯,wi−1)=C(wi−n−1,⋯,wi)C(wi−n−1,⋯,wi−1)

来看一个具体的例子,假设我们现在有一个语料库如下,其中s1s2

是句首标记,/s2/s1

是句尾标记:

s1s2yesnonononoyes/s2/s1s1s2nononoyesyesyesno/s2/s1

下面我们的任务是来评估如下这个句子的概率:s1s2yesnonoyes/s2/s1

我们来演示利用trigram模型来计算概率的结果P(yes|s1s2)=12,P(no|s2yes)=1P(no|yesno)=12,P(yes|nono)=25P(/s2|noyes)=12,P(/s1|yes/s2)=1

所以我们要求的概率就等于:12×1×12×25×12×1=0.05

再举一个来自文献[1]的例子,假设现在有一个语料库,我们统计了下面一些词出现的数量

下面这个概率作为其他一些已知条件给出:P(i|s)=0.25P(english|want)=0.0011P(food|english)=0.5P(/s|food)=0.68

,则可以算得P(s1)=P(i|s)P(want|i)P(english|want)P(food|english)P(/s|food)=0.25×0.33×0.0011×0.5×0.68=0.000031

使用N-Gram模型时的数据平滑算法

有研究人员用150万词的训练语料来训练 trigram 模型,然后用同样来源的 测试 语料来做验证,结果发现23%的 trigram 没有在训练语料中出现过。这其实就意味着上一节我们所计算的那些概率有空为 0,这就导致了数据稀疏的可能性,我们的表3中也确实有些为0的情况。对语言而言,由于数据稀疏的存在,极大似然法不是一种很好的参数估计办法。

这时的解决办法,我们称之为“平滑技术”(Smoothing)或者 “减值” (Discounting)。其主要策略是把在训练样本中出现过的事件的概率适当减小,然后把减小得到的概率密度分配给训练语料中没有出现过的事件。实际中平滑算法有很多种,例如:▸ Laplacian (add-one) smoothing▸ Add-k smoothing▸ Jelinek-Mercer interpolation▸ Katz backoff▸ Absolute discounting▸ Kneser-Ney

对于这些算法的详细介绍,我们将在后续的文章中结合一些实例再来进行讨论。

A Final Word

如果你能从前面那些繁冗、复杂的概念和公式中挺过来,恭喜你,你对N-Gram模型已经有所认识了。尽管,我们还没来得及探讨平滑算法(但它即将出现在我的下一篇博文里,如果你觉得还未过瘾的话),但是其实你已经掌握了一个相对powerful的工具。你可以能会问,在实践中N-Gram模型有哪些具体应用,作为本文的结束,主页君便在此补充几个你曾见过的或者曾经好奇它是如何实现的例子。

Eg.1 搜索引擎 (Google或者Baidu)、或者输入法的猜想或者提示。你在用百度时,输入一个或几个词,搜索框通常会以下拉菜单的形式给出几个像下图一样的备选,这些备选其实是在猜想你想要搜索的那个词串。再者,当你用输入法输入一个汉字的时候,输入法通常可以联系出一个完整的词,例如我输入一个“刘”字,通常输入法会提示我是否要输入的是“刘备”。通过上面的介绍,你应该能够很敏锐的发觉,这其实是以N-Gram模型为基础来实现的,如果你能有这种觉悟或者想法,那我不得不恭喜你,都学会抢答了!

Eg.2 某某作家或者语料库风格的文本自动生成。这是一个相当有趣的话题。来看下面这段话(该例子取材自文献【1】):

“You are uniformly charming!” cried he, with a smile of associating and now and then I bowed and they perceived a chaise and four to wish for.

你应该还没有感觉到它有什么异样吧。但事实上这并不是由人类写出的句子,而是计算机根据Jane Austen的语料库利用trigram模型自动生成的文段。(Jane Austen是英国著名女作家,代表作有《傲慢与偏见》等)

再来看两个例子,你是否能看出它们是按照哪位文豪(或者语料库)的风格生成的吗?

This shall forbid it should be branded, if renown made it empty.

They also point to ninety nine point six billion dollars from two hundred four oh three percent of the rates of interest stores as Mexico and Brazil on market conditions.

答案是第一个是莎士比亚,第二个是华尔街日报。最后一个问题留给读者思考,你觉得上面两个文段所运用的n-gram模型中,n应该等于多少?

推荐阅读和参考文献:

[1] Speech and Language Processing. Daniel Jurafsky James H. Martin, 3rd. Chapter 4[2] 本文中的一些例子和描述来自 北京大学 常宝宝 以及 The University of Melbourne “Web Search and Text Analysis” 课程的幻灯片素材

n-gramjava的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于、n-gramjava的信息别忘了在本站进行查找喔。