NLP 系列之一:用 Trigram 进行 Article Spinner

Posted LiteAdventure

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NLP 系列之一:用 Trigram 进行 Article Spinner相关的知识,希望对你有一定的参考价值。

Article Spinner 指文章的制作者通过改写文章的部分段落,或者用相似内容替换文中词汇,句子甚至段落来批量制造内容相近文章的技术。Article Spinner 主要运用在Search Engine Optimization(SEO)中,可以在批量生成近似内容的同时,有效降低文章的相似度来避开搜索引擎对重复内容的惩罚。有了这个方法,站长再也不用为了SEO把一个关键词用看不见的颜色重复一万次了。

本文接下来的内容主要分为三个部分,第一部分是简单介绍 Article Spinner 中最常用的三连词(trigram)方法的思路,第二部分是介绍三连词方法的步骤,最后一部分是介绍三连词方法的 Python 实现。


Article Spinner 中最常用的技术就是对文中的词汇进行近义词替换,替换的依据有很多,在这里介绍一下利用三连词(trigram)的方法。

三连词是上下文(context)的最简化形式。在Article Spinner 问题中,我们用词语的条件概率来表示上下文。首先将所有出现的词语分别标记为w(1),w(2)...w(n),然后求出P(w(i)|w(1),w(2),..w(i-1),w(i+1),..w(n))。在三连词中,这个条件概率被进一步简化为P(w(i)|w(i-1),w(i+1)),即一个词在一对特定的词之间出现的概率。随后,在出现该特定的两个词时,程序会选择若干条件概率较大的w(i)之一,对原本夹在中间的词进行替换。在实际应用中,不会将每个词都替换掉,而是设置阈值来控制替换控制的比例,因为如果替换过多,可能会生成的内容不合语法或者有歧义。


接下来简单描述一下使用三连词进行 Article Spinner 的流程。

首先,对原始文章进行分词处理。

第二步,建立一个三连词的字典dictionaryw,以文中所有(上一个词,下一个词)的组合作为key,将文中所有以(上一个词,word,下一个词)形式出现过的word放入一个list,作为对应的value。

第三步,基于第二步的dictionaryw,建立关于三连词概率的字典dictionaryp,key与dicionaryw相同,value为dictionaryw里对应value的每个词出现的频率。这个频率将被作为概率的估计,在下一步作为词语替换的依据。

最后一步,进行替换,设定一个阈值,对文中所有词按阈值的比例进行替换。替换的基本规则为选择上下文三连词中条件概率较大的词语,为了避免同一个同一个上下文词组总是被固定的中间词替换,通常还会加入一些随机性,来保证替换词语的多样性。


最后来看一下用三连词进行 Article Spinner 的 Python 实现。本文使用的例子是亚马逊的评论内容。

 
   
   
 
  1. import nltk

  2. import numpy as np

  3. import random

  4. from bs4 import BeautifulSoup

导入数据。

 
   
   
 
  1. positive_reviews = BeautifulSoup(open('positive.review', encoding='utf-8' ).read())

  2. positive_reviews = positive_reviews.findAll('review_text')

建立三连词的字典trigram。

 
   
   
 
  1. trigrams = {}

  2. for review in positive_reviews:

  3.    s = review.text.lower()

  4.    tokens = nltk.tokenize.word_tokenize(s)

  5.    for i in range(len(tokens)-2):

  6.        k = (tokens[i],tokens[i+2])

  7.        if k not in trigrams:

  8.            trigrams[k] = []

  9.        trigrams[k].append(tokens[i+1])

建立三连词概率的字典trigrams_p。

 
   
   
 
  1. trigrams_p = {}

  2. for k,word in trigrams.items():

  3.    if(len(set(word))>1):

  4.        d = {}

  5.        n = 0

  6.        for w in word:

  7.            if w not in d:

  8.                d[w] = 0

  9.            d[w] += 1

  10.            n += 1

  11.        for w,c in d.items():

  12.            d[w] = float(c)/n

  13.        trigrams_p[k] = d

定义随机抽取的函数。

 
   
   
 
  1. def random_choice(d):

  2.    r = random.random()

  3.    cum = 0

  4.    for k,c in d.items():

  5.        cum += c

  6.        if r < cum:

  7.            return k

对全文进行词语替换,在这里设置的阈值是第八行的0.2 。

 
   
   
 
  1. def test_spinner():

  2.    review = random.choice(positive_reviews)

  3.    s = review.text.lower()

  4.    print("original:")

  5.    print(s)

  6.    tokens = nltk.tokenize.word_tokenize(s)

  7.    for i in range(len(tokens)-2):

  8.        if random.random() < 0.2:

  9.            k = (tokens[i],tokens[i+2])

  10.            if k in trigrams_p:

  11.                word = random_choice(trigrams_p[k])

  12.                tokens[i+1] = word

  13.    print("spun:")

  14.    print(" ".join(tokens))

最后运行test_spinner()函数即可。会打印出原始的评论文本和生成的替换文本。

 
   
   
 
  1. test_spinner()

将生成的一组文本附在下面,供大家参考。

 
   
   
 
  1. original:

  2. this product was perfect. it's a sturdy case that holds my large collection of cd's and dvd's.

  3. my other cases were flimsy and wore out fast. this one has a hard outside shell and the inside holds my dvd's nicely.

  4. so i have no complaints. and at the price i paid i'd say this was a great deal

  5. spun:

  6. this phone was perfect . it 's a great case that holds my large collection of cd 's and dvd 's . my other cases were flimsy and wore out fast . this card has a hard outside shell . the inside holds my dvd 's nicely . so i have no complaints . and at the price i paid i 'd say this was a great deal


以上是关于NLP 系列之一:用 Trigram 进行 Article Spinner的主要内容,如果未能解决你的问题,请参考以下文章

NLP系列_用朴素贝叶斯进行文本分类(上)

自然语言处理(NLP)知识整理及概述(一)

Sqlite FTS5:使用 Trigram Tokenizer 进行子字符串匹配

广告行业中那些趣事系列2:BERT实战NLP文本分类任务(附github源码)

拓端数据tecdat:用于NLP的Python:使用Keras进行深度学习文本生成

百度NLP深度学习悉数亮相NeurIPS 2019,一系列年度突破大放异彩