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 实现。本文使用的例子是亚马逊的评论内容。
import nltk
import numpy as np
import random
from bs4 import BeautifulSoup
导入数据。
positive_reviews = BeautifulSoup(open('positive.review', encoding='utf-8' ).read())
positive_reviews = positive_reviews.findAll('review_text')
建立三连词的字典trigram。
trigrams = {}
for review in positive_reviews:
s = review.text.lower()
tokens = nltk.tokenize.word_tokenize(s)
for i in range(len(tokens)-2):
k = (tokens[i],tokens[i+2])
if k not in trigrams:
trigrams[k] = []
trigrams[k].append(tokens[i+1])
建立三连词概率的字典trigrams_p。
trigrams_p = {}
for k,word in trigrams.items():
if(len(set(word))>1):
d = {}
n = 0
for w in word:
if w not in d:
d[w] = 0
d[w] += 1
n += 1
for w,c in d.items():
d[w] = float(c)/n
trigrams_p[k] = d
定义随机抽取的函数。
def random_choice(d):
r = random.random()
cum = 0
for k,c in d.items():
cum += c
if r < cum:
return k
对全文进行词语替换,在这里设置的阈值是第八行的0.2 。
def test_spinner():
review = random.choice(positive_reviews)
s = review.text.lower()
print("original:")
print(s)
tokens = nltk.tokenize.word_tokenize(s)
for i in range(len(tokens)-2):
if random.random() < 0.2:
k = (tokens[i],tokens[i+2])
if k in trigrams_p:
word = random_choice(trigrams_p[k])
tokens[i+1] = word
print("spun:")
print(" ".join(tokens))
最后运行test_spinner()函数即可。会打印出原始的评论文本和生成的替换文本。
test_spinner()
将生成的一组文本附在下面,供大家参考。
original:
this product was perfect. it's a sturdy case that holds my large collection of cd's and dvd's.
my other cases were flimsy and wore out fast. this one has a hard outside shell and 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
spun:
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的主要内容,如果未能解决你的问题,请参考以下文章
Sqlite FTS5:使用 Trigram Tokenizer 进行子字符串匹配
广告行业中那些趣事系列2:BERT实战NLP文本分类任务(附github源码)