问题引出
在做文本分析时,例如网上购物的评论中,有些用户会为了获取积分或者获取金钱奖励,而采取一种复制手段,可以称之为机械重复词:如下图所示:
这些重复词只是为了单纯的凑字数,并没实际含义,但在文本分析时产生的影响确实不可忽略的。
问题处理
对于这些机械重复词,直接利用jieba分词处理显然是不合适的,可以利用一些规则找出这些重复词的索引,然后将这些索引对应的词给删掉,以达到去重目的:
(1)首先把字符串转化列表,list会自动按单个字符分词;
(2)准备两个空列表,一个list1用于存储当前词,一个list2用于存储判断重复词;
(3)判断第i个字符是否为此字符串的最后一个字符,若是就判断list1与list2是否相等,若相等就记录其索引;
(4)比较当前单个字符分词与list1中的第一个单个字符是否相等,同时需要判断list2的长度是否大于1,若当前字符和list1首字符相同,list2为空,将词加入list2;当前字符和list1首字符不同,list2为空,将词加入list1;
(5)当前词和list1不同,list2不为空,若list1与list2重复,记录list2字符的索引,list1本来的内容不用再去判断重复了清空list1与list2,并把当前值赋个list1;当前词和list1首字符不同,list2不为空,若list1与list2不重复,将当前字符添加到list2;
(6)当前字符词和list1首字符相同,list2不为空,若list1与list2重复,记录list2中字符对应的索引,删除list2里的内容,list1需要再去和后面的词汇继续判断重复,再将当前值赋到list2,当前字符词和list1首字符相同,list2不为空,若list1与list2不重复,将list2的值赋给list1,当前字符赋给list2;
(7)将记录的索引对应重复的字符删除,并将剩下的字符重新拼接起来。
函数代码
// An highlighted block
def qc_string_forward(s):
filelist = s
filelist2 = []
for a_string in filelist:
temp1 = a_string.strip('\n')
temp2 = temp1.lstrip('\ufeff')
temp3 = temp2.strip('\r')
char_list = list(temp3) //把字符串转化列表自动按单个字符分词了
//print(char_list)
list1 = []
list1.append(char_list[0])
list2 = ['']
//记录要删除的索引
del1 = []
i = 0
while (i<len(char_list)):
i = i+1
//这里是对后面没有词汇的时候对列表1和列表2判断一次重复
if i == len(char_list):
if list1 == list2:
m = len(list2)
for x in range(i-m,i):
del1.append(x)
else:
if char_list[i] == list1[0] and list2==['']:
//print('词汇和list1相同,list2为空,将词加入list2')
list2[0]=char_list[i] //这里初始化用append会让lisr2初始化为['','**']
elif char_list[i] != list1[0] and list2==['']:
//print('词汇和1不同,2为空,将词加入1')
list1.append(char_list[i])
//触发判断
elif char_list[i] != list1[0] and list2 !=['']:
if list1 == list2 and len(list2)>=2:
//print('词和1不同,2不为空,判断1和2重复')
m = len(list2)
//删除列表2里的内容,列表1本来的内容不用再去判断重复了
for x in range(i-m,i):
del1.append(x)
list1= ['']
list2 = ['']
list1[0]=char_list[i]
else:
//print('词和1不同,2不为空,判断1和2不重复')
list2.append(char_list[i])
//触发判断
elif char_list[i] == list1[0] and list2 != ['']:
if list1 == list2:
//print('词和1相同,2不为空,判断1和2重复')
m = len(list2)
//删除列表2里的内容,列表1需要再去和后面的词汇继续判断重复
for x in range(i-m,i):
del1.append(x)
list2 = ['']
list2[0]=char_list[i]
else:
//print('词和1相同,2不为空,判断1和2不重复')
//逻辑对书本上进行了修改,书上是清空列表1和2,就是保留现在列表1和2内容不做删除,这里只保留1,列表2内容还需要做对比
list1 = list2
list2 = ['']
list2[0]=char_list[i]
a = sorted(del1) //从数字更大的索引删起,这样就不用考虑元素删除后索引的变化问题
t = len(a) - 1
while(t>=0):
del char_list[a[t]]
t = t-1
str1 = ''.join(char_list)
str2 = str1.strip()
filelist2.append(str2)
return filelist2
结果就是这样子啦,还不错
还有一个问题
上面的讨论只能处理重复词在开头的的字符串,通常这些重复词还会出现在结尾,当然这就比较简单了,只需要在调用函数之前将字符串翻转一下,再将函数输出结果翻转回来就ok了,对于重复词在中间的情况,比较复杂,出现的频次也并不是很多,以后再探索吧!