目录

1.前言

2. 什么是N-Gram模型

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

4.N-Gram模型评估语句合理性的例子

5. N-Gram中N的选择及其对性能的影响

6.N-Gram语言模型的其他应用

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

8.推荐阅读


1.前言

自然语言(Natural Language)其实就是人类的语言,自然语言处理(NLP)就是对人类语言的处理,当然主要利用计算机。自然语言处理是关于计算机科学和语言学的交叉学科,常见的研究任务包括:

  • 分词(Word Segmentation或Word Breaker,WB)
  • 信息抽取(Information Extraction,IE):命名实体识别和关系抽取(Named Entity Recognition & Relation Extraction,NER)
  • 词性标注(Part Of Speech Tagging,POS)
  • 指代消解(Coreference Resolution)
  • 句法分析(Parsing)
  • 词义消歧(Word Sense Disambiguation,WSD)
  • 语音识别(Speech Recognition)
  • 语音合成(Text To Speech,TTS)
  • 机器翻译(Machine Translation,MT)
  • 自动文摘(Automatic Summarization)
  • 问答系统(Question Answering)
  • 自然语言理解(Natural Language Understanding)
  • OCR
  • 信息检索(Information Retrieval,IR)

早期的自然语言处理系统主要是基于人工撰写的规则,这种方法费时费力,且不能覆盖各种语言现象。上个世纪80年代后期,机器学习算法被引入到自然语言处理中,这要归功于不断提高的计算能力。研究主要集中在统计模型上,这种方法采用大规模的训练语料(corpus)对模型的参数进行自动的学习,和之前的基于规则的方法相比,这种方法更具鲁棒性。

在这个大背景下产出了统计机器学习方法和统计自然语言处理方法,包括今天提到的统计语言模型。

推荐以下两本很流行的关于统计学习的书:统计学习方法和统计自然语言处理

2. 什么是N-Gram模型

N-Gram是一种基于统计语言模型的算法。它的基本思想是将文本里面的内容按照字节进行大小为N的滑动窗口操作,形成了长度是N的字节片段序列。

每一个字节片段称为gram,对所有gram的出现频度进行统计,并且按照事先设定好的阈值进行过滤,形成关键gram列表,也就是这个文本的向量特征空间,列表中的每一种gram就是一个特征向量维度。

该模型基于这样一种假设,第N个词的出现只与前面N-1个词相关,而与其它任何词都不相关,整句的概率就是各个词出现概率的乘积。这些概率可以通过直接从语料中统计N个词同时出现的次数得到。常用的是二元的Bi-Gram和三元的Tri-Gram。

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

在介绍N-Gram模型在评估语句合理性这个应用之前,先看一个例子。

首先,从统计的角度来看,自然语言中的一个句子 s 可以由任何词构成,不过概率句子s出现的概率 有大有小。例如:

  •  = 我刚吃过晚饭
  •  = 刚我过晚饭吃

显然,对于中文而言是一个通顺且有意义的句子,而不是,所以对于中文来说,.但对于其他语言来说,概率值可能会出现反转。

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

  • the large green__. ('mountain' or 'tree'?)
  • Kate swallowed the large green__.('pill' or 'broccoli'?)

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

如果我们有一个由m个词组成的序列/句子s,即,我们希望算的该句子出现的概率:

上面这个联合概率链规则显然不好算,虽然它考虑了所有词和词之间的依赖关系,但是这样非常复杂,在实际中几乎没有办法使用。于是,我们需要用一种办法来近似这个公式,要求其效果要比独立性假设好(假设句子中每个词之间是独立的,没有任何关系,也就是下文中要提到的1-gram/uni-gram)。 这个办法就是著名的马尔可夫假设,即当前这个词仅仅跟前面几个有限的词相关,因此也就不必追溯到最开始的那个词,这样就可以大幅缩减上述算式的长度,即:

特别地,n取值比较小时,下面给出一元/2元/3元模型:

  • 当n=1时,这是一个一元模型(独立性假设,各个词之间相互独立。1-gram/unigram)

  • 当n=2时,这是一个二元模型(2-gram/bigram):

  • 当n=3时,这是一个三元模型(3-gram/trigram):

下面的思路就比较简单了,在给定的训练语料中,利用贝叶斯定理,将上述的条件概率值都统计计算出来即可,然后相乘就可以得到整个句子出现的概率。公式如下:

  • 对于unigram来说,其中表示n-gram 在训练语料中出现的次数,M是语料库中的总词数(如 对于yes,no,no,no,yes来说,M=5,以下符号都是同理)

  • 对于bigram来说:

  • 对于n-gram来说:

对bi-gram的公式做一下解释,其他都是同理:

4.N-Gram模型评估语句合理性的例子

  • ex1

假设我们现在有如下的一个语料库(一般包含很多句子,很多的词),其中是句首标记,是句尾标记(对于trigram来说,每个句子的第一个词之前要补两个开始标记,最后一个词之后要补两个结束标记。其他n-gram同理):

下面的任务就是评估如下这个句子的概率:

接下来演示使用trigram的概率计算过程:

那么这句话出现的概率就是:

  • ex2

假设现在有一个语料库,我们统计了一下面一些词出现的次数:

下面这些概率作为一些已知条件给出:

下表是基于bigram进行计数的结果:

例如,上表中第一行,第2列表示 给定前一个词是i时,当前词是want的情况出现的次数是827,即语料库中i want出现的次数。其他各项的含义同理。据此,可以计算相应的频率分布表:

因为我们从表1中知道 “i” 一共出现了2533次,而其后出现 “want” 的情况一共有827次,所以P(want|i)=827/2533≈0.33。再比如说,我们就以表中的p(eat|i)=0.0036这个概率值讲解,从表一得出“i”一共出现了2533次,而其后出现eat的次数一共有9次,p(eat|i)=p(eat,i)/p(i)=count(i,eat)/count(i)=9/2533 = 0.0036。

下面我们通过基于这个语料库来判断s1=“<s> i want english food</s>” 与s2 = "<s> want i english food</s>"哪个句子更合理:

通过比较我们可以明显发现0.00000002057<0.000031,也就是说s1= "i want english food</s>"更像人话。

再深层次的分析,我们可以看到这两个句子概率的不同,主要是由于顺序i want还是want i的问题,根据我们的直觉和常用搭配语法,i want要比want i出现的几率要大很多。所以两者的差异,第一个概率大,第二个概率小,也就能说的通了。

  • ex3

再举个简单的邮件分类例子,对于垃圾邮件中的一句话“我司可办理正规发票保真增值税发票点数优惠”,这句话发生的概率P = P(“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”),使用bi-gram模型:

=P(“我”)P(“司”|“我”)P(“可”|“司”)P(“办理”|“可”)...P(“优惠”|“点数”)

如果把依赖词长度再拉长一点,考虑一个词对前两个词的依赖关系,即使用trigram,公式如下:

P(“我”)P(“司”|“我”)P(“可”|“我”,“司”)P(“办理”|“司”,“可”)...P(“优惠”|“发票”,“点数”)

如果我们再考虑长一点,考虑n个词语之间的关系,即n-gram模型。

我们之前使用的简化后的公式,都是基于著名的马尔科夫假设(Markov Assumption):下一个词的出现仅依赖于它前面的一个或几个词。这相对于联合概率链规则,其实是一个有点粗糙的简化,不过很好地体现了就近思路,离得较远和关系比较弱的词语就被简化和省略了。实际应用中,这些简化后的n-gram语法比独立性假设还是强很多的。其实可以把独立性假设理解成为1-gram。

至于这个马尔科夫假设为什么好用?可能是在现实情况中,大家通过真实情况将n=1,2,3,....这些值都试过之后,得到的真实的效果和时间空间的开销权衡之后,发现能够使用。

5. N-Gram中N的选择及其对性能的影响

  • N比较大时

选择依赖词的个数“n”主要与计算条件概率有关。理论上,只要有足够大的语料,n越大越好,毕竟这样考虑的信息更多嘛。条件概率很好算,统计一下各个元组出现的次数就可以,比如:

但我们实际情况往往是训练语料很有限,很容易产生数据稀疏,不满足大数定律,算出来的概率失真。比如(“发票”,“点数”,“优惠”)在训练集中竟没有出现,就会导致零概率问题。又比如在英文语料库IBM, Brown中,三四百兆的语料,其测试语料14.7%的trigram和2.2%的bigram在训练语料中竟未出现!

对于上述的两个问题我们会在之后介绍一些平滑方法来解决。

另一方面,如果n很大,参数空间过大,产生维数灾难,也无法实用。假设词表的大小为100000,那么n-gram模型的参数数量为。这么多的参数,估计内存就不够放了。

其中当N为特定值的时候,我们来看一下n-gram可能的总数,如下表:

对与n-gram模型来说,n个位置,每个位置有|V|个选择,所有可能的n-gram个数就是

对于上图,我用一个例子来进行解释,假如目前词汇表中就只有三个单词,”我爱你“,那么bigram的总数是3^2=9个,有”我我“,我爱,我你,爱爱,爱你,爱我,你你,你我,你爱这9个,所以对应上面的表示是bigrams是20000^2=400000000,trigrams=20000^3 = 8*10e12

  • N比较小时

元组在训练语料中出现的次数更多,可以得到更可靠的统计结果,有更高的可靠性,但是约束信息更少。

  • N的选择

那么,如何选择依赖词的个数n呢?从前人的经验来看:

1.经验上,trigram用的最多。尽管如此,原则上,能用bigram解决,绝不使用trigram。n取≥4的情况较少。

2.当n更大时:对下一个词出现的约束信息更多,具有更大的辨别力;

3. 当n更小时:在训练语料库中出现的次数更多,具有更可靠的统计信息,具有更高的可靠性、实用性。

6.N-Gram语言模型的其他应用

  • 搜索引擎

搜索引擎(Google或百度)或输入法的猜想或提示。在使用百度时,输入一个或几个词,搜索框通常会以下拉菜单的形式给出几个像下图一样的备选,这些备选其实是在猜想你想要的搜索的那个词串。

那么原理是什么呢?也就是我们打入'济南'时,后面的'天气','大学','地铁'等是怎么出来的,又是怎么排序的?

实际上是根据语言模型得到的。假设使用的是2-gram语言模型预测下一个单词:

排序过程就是:

p('天气' | '济南') > p('大学' | '济南') > p('地铁' | '济南') > ...,这些概率值的求法和之前提到的一样,数据来源(语料库)可以是用户搜索的log。

再者,当你用输入法输入一个汉字时,输入法通常可以联系出一个完整的词,例如我输入一个'刘'字,通常输入法会提示是否输入的是'刘备'。通过上面的介绍,你应该能够很敏锐的发觉,这其实是基于N-Gram模型来实现的。

  • 文本自动生成

某某作家或语料库风格的文本自动生成。这是一个有趣的话题。比如下面这句话:

应该不会感到有什么异样,但这并不是人类写的句子,而是计算机根据Jane Austen的语料库利用trigram模型自动生成的文本片段。

  • 词性标注

词性标注是一个典型的多分类问题。常见的词性包括名词、动词、形容词、副词等。而一个词可能属于多种词性。如“爱”,可能是动词,可能是形容词,也可能是名词。但是一般来说,“爱”作为动词还是比较常见的。所以可以统一给“爱”分配为“动词”。这种最简单粗暴的思想非常好实现,如果准确率要求不高则也比较常用。它只需要基于词性标注语料库做一个统计就够了,连贝叶斯方法、最大似然法都不要用。词性标注语料库一般是由专业人员搜集好了的,长下面这个样子。其中斜线后面的字母表示一种词性,词性越多说明语料库分得越细:

需要比较以下各概率的大小,选择概率最大的词性即可:

但这种方法没有考虑上下文的信息。而一般来说,形容词后面接名词居多,而不接动词,副词后面才接动词,而不接名词。 考虑到词性会受前面一两个词的词性的影响,可以引入2-gram模型提升匹配的精确度。 我们匹配以下这句话(已被空格分好词)中“爱”的词性:

将公式进行以下改造,比较各概率的大小,选择概率最大的词性:

计算这个概率需要对语料库进行统计。但前提是你得先判断好“很”的词性,因为采用2-gram模型,进而就需要提前判断“李雷”的词性,需要判断“闷骚的”词性。但是“闷骚的”作为第一个词语,已经找不比它更靠前的词语了。这时就可以考虑用之前最简单粗暴的方法判断“闷骚的”的词性,统一判断为形容词即可。

词性标注是自然语言处理中的一项基础性工作,有其细节实现远比我们介绍地更加丰富。感兴趣的同学可以看看这篇文章《NLTK读书笔记 — 分类与标注》

  • 垃圾邮件识别

下面我们用直观的例子探讨一下其在分类问题上是怎么发挥作用的。一个可行的思路如下:

1. 先对邮件文本进行断句,以句尾标点符号(“。” “!” “?”等)为分隔符将邮件内容拆分成不同的句子。

2. 用N-gram分类器(马上提到)判断每个句子是否为垃圾邮件中的敏感句子。

3.当被判断为敏感句子的数量超过一定数量(比如3个)的时候,认为整个邮件就是垃圾邮件。

N-gram分类器是结合贝叶斯方法和语言模型的分类器。这里用分别表示这垃圾邮件和正常邮件,用?表示被判断的邮件的句子。根据贝叶斯公式有:

比较i=1和2时两个概率值的大小即可得到?所属的分类。对于句子(“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”)用字母?代表,每一个词语用字母表示。?就可以写成一个组成的向量,就是这向量中某个维度的特征。对套用2-gram模型(在语料库不变的情况下,对于每个Yi,P(X)可视为常数,bigram需要的是对比每个Yi的概率的大小从而选择最大那个,而对具体数值没有要求。由于P(X)为常数对数值大小顺序无影响)。 则上式化简为:

公式中的条件概率也比较好求,举个例子:

剩下的就需要在语料库中间做一个的统计就是了。因为这种方法考虑到了词语前面的一个词语的信息,同时也考虑到了部分语序信息,因此区分效果会比单纯用朴素贝叶斯方法更好。

N-gram在实际应用中的一些技巧:

1. 3-gram方法的公式与上面类似。此处省略。从区分度来看,3-gram方法更好些。

2. 句子开头的词,比如本例中的“我”,因为要考虑其本身作为开头的特征,可以考虑在其前面再添加一个句子起始符号如“<?>”,这样我们就不必单独计算?(“我”|??),而是替换为计算?(“我”|“<?>”,??)。形式上与2-gram统一。 这样统计和预测起来都比较方便。

3. 一般地,如果采用N-gram模型,可以在文本开头加入n-1个虚拟的开始符号,这样在所有情况下预测下一个词的可依赖词数都是一致的。

4. 与朴素贝叶斯方法一样,N-gram模型也会发生零概率问题,也需要平滑技术。 一会儿会讨论到。

  • 中文分词

中文分词技术是“中文NLP中,最最最重要的技术之一”,重要到某搜索引擎厂有专门的team在集中精力优化这一项工作,重要到能影响双语翻译百分位的准确度,能影响某些query下搜索引擎百分位的广告收入。不过简单的分词实现方式中,包含的原理其实也非常易懂。

说起来,中文分词也可以理解成一个多分类的问题。 这里用?X表示被分词的句子“我司可办理正规发票”, 用??表示该句子的一个分词方案。 咱们继续套用贝叶斯公式:

比较这些概率的大小,找出使得?(??|?) 最大的??即可得到?所属的分类(分词方案)了。

??作为分词方案,其实就是个词串,比如(“我司”,“可”,“办理”,“正规发票”)或者(“我”,“司可办”,“理正规”,“发票”),也就是一个向量了。

而上面贝叶斯公式中?(?|??)项的意思就是在分类方案 ??的前提下,其对应句子为?的概率。而无论分词方案是(“我司”,“可”,“办理”,“正规发票”)还是(“我”,“司可办”,“理正规”,“发票”),或者其他什么方案,其对应的句子都是“我司可办理正规发票”。也就是说任意假想的一种分词方式之下生成的句子总是唯一的(只需把分词之间的分界符号扔掉剩下的内容都一样)。于是可以将 ?(?|??)看作是恒等于1的。这样贝叶斯公式又进一步化简成为:

也就是说我们只要取最大化的?(??)就成了。而??就是一个词串,也就是一个向量,可以直接套用我们上面的N-gram语言模型。这里采用2-gram。于是有:

第二种分词方案的概率为:

由于在语料库中“司可办”与“理正规”一起连续出现的概率为0,于是?(?2)=0 ,?(?1)的概率更高,优先选择?1的分词方案。

  • 机器翻译与语音识别

N-gram语言模型在机器翻译和语音识别等顶级NLP应用中也有很大的用途。

当然,机器翻译和语音识别是非常复杂的过程,N-gram语言模型只是其中的一部分,但是缺少它整个过程却进行不下去。对于这两个应用我们不打算罗列大量的公式,而只是举些例子,让大家了解一下语言模型是怎么发挥作用的。

对于机器翻译而言,比如中译英,我们对于同一句话『李雷出现在电视上』,得到的三个译文:

其对应短语的翻译概率是一致的,从短语翻译的角度我们无法评定哪句才是正确的翻译结果。这时候,如果我们再使用语言模型(比如机器翻译里面最常见的是3-gram),我们计算会得到最后一句话的概率:

它高于第一句和第二句的概率:

因此我们选择第三句作为正确的答案。这也表明大量语料上的语言模型能够在一定程度上,体现出我们表达某种语言时候的说话习惯。

对应到语音识别问题中,我们也会遇到相同的问题,对于以下的2个句子:

或者对应下述2个句子:

其对应的发音是完全一致的,这时如果我们借助于语言模型,我们会算出这句话的概率:

大于:

而这句话的概率:

远大于:

因此我们会选择I went to a party 和 你现在在干什么作为正确的语音识别结果。

上面只是简单的举例,但是大家应该看出来了,在机器翻译和语音识别中,N-gram语言模型有着至关重要的地位。同样在现在最顶级的计算机视觉任务『图片内容表述』中,语言模型也发挥着至关重要的作用。语言模型的重要性可见一斑。

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

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

这时的解决办法,我们称之为“平滑技术”(Smoothing)或者 “减值” (Discounting)。其主要策略是把在训练样本中出现过的事件的概率适当减小,然后把减小得到的概率密度分配给训练语料中没有出现过的事件。

平滑技术主要解决0概率问题,我们需要给'未出现的n-gram条件概率分布一个非0估计值,相应得需要降低已出现n-gram的条件概率分布,且经数据平滑后一定保证概率和为1.这是平滑技术的基本思想。

实际中平滑算法有很多种,例如

最简单的平滑技术是拉普拉斯平滑,是最古老的一种平滑方法,也叫加一平滑法,其保证每个n-gram在训练语料中至少出现一次。以计算概率?(“优惠”|“发票”,“点数”)为例,公式如下:

在所有不重复的三元组的个数远大于(“发票”,“点数”)出现的次数时,即训练语料库中绝大部分n-gram都是未出现的情况(一般都是如此),拉普拉斯平滑有“喧宾夺主”的现象,效果不佳。

更多平滑技术的详细介绍,可以阅读这篇博客自然语言处理中N-Gram模型的Smoothing算法

8.推荐阅读

Speech and Language Processing(第三版).第四章

自然语言处理 | (11) N-gram语言模型及其应用相关推荐

  1. 自然语言处理(5)——语言模型

    NLP学习笔记(5)--语言模型 1. 基本概念 1.1 概念导入 1.2 划分等价类的方法--n元文法模型(n-gram) 1.3 概率计算 1.4 语言模型的应用 1.4.1 音字转换问题 1.4 ...

  2. 6-斯坦福大学自然语言处理第四课“语言模型(Language Modeling)

    一.课程介绍 斯坦福大学于2012年3月在Coursera启动了在线自然语言处理课程,由NLP领域大牛Dan Jurafsky 和 Chirs Manning教授授课: https://class.c ...

  3. CS224n自然语言处理(二)——语言模型、机器翻译和CNN

    文章目录 一.语言模型及RNN 1.n-gram语言模型 2.Window-based DNN 3.循环神经网络 (一)梯度消失和梯度爆炸 (二)LSTM (三)GRU 4.评估语言模型 5.预处理 ...

  4. 自然语言处理(NLP)之三:语言模型

    语言模型的定义 语言模型是一种预测语句符合语法规范1的概率的计算方法.对给定语句S=W1,W2,-,WnS = W_1, W_2, \dots, W_nS=W1​,W2​,-,Wn​,其符合语法规范的 ...

  5. 【一起入门NLP】中科院自然语言处理第7课-语言模型-神经语言模型(NNLM+RNNLM)

    专栏介绍:本栏目为 "2021秋季中国科学院大学胡玥老师的自然语言处理" 课程记录,不仅仅是课程笔记噢- 如果感兴趣的话,就和我一起入门NLP吧

  6. 自然语言处理从入门到应用——自然语言处理的语言模型(Language Model,LM)

    分类目录:<自然语言处理从入门到应用>总目录 语言模型(Language Model,LM)(也称统计语言模型)是描述自然语言概率分布的模型,是一个非常基础和重要的自然语言处理任务.利用语 ...

  7. 自然语言处理Word2Vec视频学习教程-唐宇迪-专题视频课程

    自然语言处理Word2Vec视频学习教程-7870人已学习 课程介绍         自然语言处理Word2Vec视频培训课程:自然语言处理中重要的算法,word2vec原理,词向量模型.教程从语言模 ...

  8. 【赠书】如何掌握好自然语言处理中的预训练语言模型?你需要读这本书

    ‍‍ 预训练语言模型属于人工智能领域中自然语言处理领域的一个细分,是自然语言处理领域的重要突破,得到了越来越广泛的关注,相关研究者和从业人员在实际应用的过程中,亟需一本理论翔实.代码细节充分的参考书. ...

  9. 如何计算给定一个unigram语言模型_n-gram语言模型原理到实践

    最近开始复习一些nlp基础知识,今天来回顾一下自然语言处理的重要技术语言模型(language model). 1 什么是语言模型 语言模型就是衡量一句话概率的模型,可以用来判断这句话为人话的概率.我 ...

最新文章

  1. macOS安装Telnet
  2. MVVM下listbox默认显示最后一行
  3. 关于使用代理解决跨域问题的原理
  4. python中的ord,chr函数
  5. SQL Server 2012入门T-SQL基础篇:(7)Where子句与Having子句的区别
  6. AI芯片最重要的是什么?Arm中国:背后的软件生态
  7. Java 数组 快速排序
  8. 中国物联网卡的发展历史和变革
  9. linux将目录打包压缩,Linux系统文件、目录及文件系统的压缩与打包详解
  10. 【CO2二氧化碳传感器】senseair S8 LP
  11. django实现腾讯云短信sdk和redis缓存服务,手机号验证码登录,未注册直接注册登录
  12. c语言字符串md5加密解密,.net core使用MD5加密解密字符串
  13. 题目分析参考贺老师的答案————谁是小偷如何派任务
  14. 优秀的图文识别开源项目PandaOCR
  15. java基于springboot班级同学录网站管理系统附源码
  16. 金庸笔下人物以及网络俏皮英语对应关系表-诗词
  17. 【qstock数据篇】行业概念板块与资金流
  18. 时间格式的转换 例如:(2021-05-10 14:20:43) 转为( 2021年5月10日 14时20分43秒)
  19. 最大期望(EM)算法
  20. 开场舞蹈 #普及组#

热门文章

  1. signature=7eaed5a66499b473aab2f11ec0461fe9,Author's reply: To PMID 25293698
  2. android sdk 混淆 修改,Android-SDK默认混淆配置ProGuard
  3. 微服务 java golang_20 个好用的 Go 语言微服务开发框架
  4. Ubuntu14.04 运行VNote 后话
  5. 《麻省理工科技评论》发布2019全球十大突破性技术 阿里巴巴成唯一上榜中国公司...
  6. 华为ensp BGP 练习实验
  7. 如何在线将视频转成gif动画?试试这个视频转gif工具
  8. 微软office办公套件 Microsoft Office 2021 Mac版 支持更新(内附安装包链接)
  9. 网校平台搭建的前后的要点分析
  10. PHP: switch结构