【python 走进NLP】两两计算相似度之后再按内容分组计算条数

# -*- encoding=utf-8 -*-
import pandas as pd
from itertools import permutations
from text_anti_brush_function import *
content_list=['东篱','东篱','在么','在么','快回我','快回我','东篱','东篱','东篱','东篱','东篱','东篱']

source_id_list=['1','2','3','4','5','6','7','8','9','10','11','12']
data1=pd.DataFrame({'content':content_list,'source_id':source_id_list})


print(data1)
test_data=dict(data1['content'])
print('排列有:')
k1=[]
k2=[]
for i,j in permutations(test_data, 2):
    similar=lcs_similarity(str(data1.iloc[i,0]),str(data1.iloc[j,0]))
    print(i,j,data1.iloc[i,0],data1.iloc[j,0],similar)
    k1.append(i)
    k2.append(similar)

data3=pd.DataFrame({'k1':k1,'k2':k2})
print(data3)


# 分组取最大相似度
data3 = data3.groupby(['k1'], as_index=False)['k2'].max()

print(data3)
# 新增一列相似度
data1['max_similar']=data3['k2']

print(data1)


# 筛选相似度大于阈值的数据
data1_101 = data1[data1['max_similar'] >= 0.95]
data1_101['row_number']=data1_101.groupby(data1_101['content'])['max_similar'].rank(ascending=True,method='first')

# # 统计条数
data1_102=data1_101[data1_101['row_number']>=5]
data1_103=data1_101[data1_101['content'].isin(data1_102['content'])]

len_brush = len(data1_103)
print(len_brush)

print(data1_103)



运行结果:

E:\laidefa\python.exe F:/文本标签/文本防刷系统/相似度.py
   content source_id
0       东篱         1
1       东篱         2
2       在么         3
3       在么         4
4      快回我         5
5      快回我         6
6       东篱         7
7       东篱         8
8       东篱         9
9       东篱        10
10      东篱        11
11      东篱        12
排列有:
0 1 东篱 东篱 1.0
0 2 东篱 在么 0.0
0 3 东篱 在么 0.0
0 4 东篱 快回我 0.0
0 5 东篱 快回我 0.0
0 6 东篱 东篱 1.0
0 7 东篱 东篱 1.0
0 8 东篱 东篱 1.0
0 9 东篱 东篱 1.0
0 10 东篱 东篱 1.0
0 11 东篱 东篱 1.0
1 0 东篱 东篱 1.0
1 2 东篱 在么 0.0
1 3 东篱 在么 0.0
1 4 东篱 快回我 0.0
1 5 东篱 快回我 0.0
1 6 东篱 东篱 1.0
1 7 东篱 东篱 1.0
1 8 东篱 东篱 1.0
1 9 东篱 东篱 1.0
1 10 东篱 东篱 1.0
1 11 东篱 东篱 1.0
2 0 在么 东篱 0.0
2 1 在么 东篱 0.0
2 3 在么 在么 1.0
2 4 在么 快回我 0.0
2 5 在么 快回我 0.0
2 6 在么 东篱 0.0
2 7 在么 东篱 0.0
2 8 在么 东篱 0.0
2 9 在么 东篱 0.0
2 10 在么 东篱 0.0
2 11 在么 东篱 0.0
3 0 在么 东篱 0.0
3 1 在么 东篱 0.0
3 2 在么 在么 1.0
3 4 在么 快回我 0.0
3 5 在么 快回我 0.0
3 6 在么 东篱 0.0
3 7 在么 东篱 0.0
3 8 在么 东篱 0.0
3 9 在么 东篱 0.0
3 10 在么 东篱 0.0
3 11 在么 东篱 0.0
4 0 快回我 东篱 0.0
4 1 快回我 东篱 0.0
4 2 快回我 在么 0.0
4 3 快回我 在么 0.0
4 5 快回我 快回我 1.0
4 6 快回我 东篱 0.0
4 7 快回我 东篱 0.0
4 8 快回我 东篱 0.0
4 9 快回我 东篱 0.0
4 10 快回我 东篱 0.0
4 11 快回我 东篱 0.0
5 0 快回我 东篱 0.0
5 1 快回我 东篱 0.0
5 2 快回我 在么 0.0
5 3 快回我 在么 0.0
5 4 快回我 快回我 1.0
5 6 快回我 东篱 0.0
5 7 快回我 东篱 0.0
5 8 快回我 东篱 0.0
5 9 快回我 东篱 0.0
5 10 快回我 东篱 0.0
5 11 快回我 东篱 0.0
6 0 东篱 东篱 1.0
6 1 东篱 东篱 1.0
6 2 东篱 在么 0.0
6 3 东篱 在么 0.0
6 4 东篱 快回我 0.0
6 5 东篱 快回我 0.0
6 7 东篱 东篱 1.0
6 8 东篱 东篱 1.0
6 9 东篱 东篱 1.0
6 10 东篱 东篱 1.0
6 11 东篱 东篱 1.0
7 0 东篱 东篱 1.0
7 1 东篱 东篱 1.0
7 2 东篱 在么 0.0
7 3 东篱 在么 0.0
7 4 东篱 快回我 0.0
7 5 东篱 快回我 0.0
7 6 东篱 东篱 1.0
7 8 东篱 东篱 1.0
7 9 东篱 东篱 1.0
7 10 东篱 东篱 1.0
7 11 东篱 东篱 1.0
8 0 东篱 东篱 1.0
8 1 东篱 东篱 1.0
8 2 东篱 在么 0.0
8 3 东篱 在么 0.0
8 4 东篱 快回我 0.0
8 5 东篱 快回我 0.0
8 6 东篱 东篱 1.0
8 7 东篱 东篱 1.0
8 9 东篱 东篱 1.0
8 10 东篱 东篱 1.0
8 11 东篱 东篱 1.0
9 0 东篱 东篱 1.0
9 1 东篱 东篱 1.0
9 2 东篱 在么 0.0
9 3 东篱 在么 0.0
9 4 东篱 快回我 0.0
9 5 东篱 快回我 0.0
9 6 东篱 东篱 1.0
9 7 东篱 东篱 1.0
9 8 东篱 东篱 1.0
9 10 东篱 东篱 1.0
9 11 东篱 东篱 1.0
10 0 东篱 东篱 1.0
10 1 东篱 东篱 1.0
10 2 东篱 在么 0.0
10 3 东篱 在么 0.0
10 4 东篱 快回我 0.0
10 5 东篱 快回我 0.0
10 6 东篱 东篱 1.0
10 7 东篱 东篱 1.0
10 8 东篱 东篱 1.0
10 9 东篱 东篱 1.0
10 11 东篱 东篱 1.0
11 0 东篱 东篱 1.0
11 1 东篱 东篱 1.0
11 2 东篱 在么 0.0
11 3 东篱 在么 0.0
11 4 东篱 快回我 0.0
11 5 东篱 快回我 0.0
11 6 东篱 东篱 1.0
11 7 东篱 东篱 1.0
11 8 东篱 东篱 1.0
11 9 东篱 东篱 1.0
11 10 东篱 东篱 1.0
     k1   k2
0     0  1.0
1     0  0.0
2     0  0.0
3     0  0.0
4     0  0.0
5     0  1.0
6     0  1.0
7     0  1.0
8     0  1.0
9     0  1.0
10    0  1.0
11    1  1.0
12    1  0.0
13    1  0.0
14    1  0.0
15    1  0.0
16    1  1.0
17    1  1.0
18    1  1.0
19    1  1.0
20    1  1.0
21    1  1.0
22    2  0.0
23    2  0.0
24    2  1.0
25    2  0.0
26    2  0.0
27    2  0.0
28    2  0.0
29    2  0.0
..   ..  ...
102   9  0.0
103   9  0.0
104   9  0.0
105   9  1.0
106   9  1.0
107   9  1.0
108   9  1.0
109   9  1.0
110  10  1.0
111  10  1.0
112  10  0.0
113  10  0.0
114  10  0.0
115  10  0.0
116  10  1.0
117  10  1.0
118  10  1.0
119  10  1.0
120  10  1.0
121  11  1.0
122  11  1.0
123  11  0.0
124  11  0.0
125  11  0.0
126  11  0.0
127  11  1.0
128  11  1.0
129  11  1.0
130  11  1.0
131  11  1.0

[132 rows x 2 columns]
    k1   k2
0    0  1.0
1    1  1.0
2    2  1.0
3    3  1.0
4    4  1.0
5    5  1.0
6    6  1.0
7    7  1.0
8    8  1.0
9    9  1.0
10  10  1.0
11  11  1.0
   content source_id  max_similar
0       东篱         1          1.0
1       东篱         2          1.0
2       在么         3          1.0
3       在么         4          1.0
4      快回我         5          1.0
5      快回我         6          1.0
6       东篱         7          1.0
7       东篱         8          1.0
8       东篱         9          1.0
9       东篱        10          1.0
10      东篱        11          1.0
11      东篱        12          1.0
8
   content source_id  max_similar  row_number
0       东篱         1          1.0         1.0
1       东篱         2          1.0         2.0
6       东篱         7          1.0         3.0
7       东篱         8          1.0         4.0
8       东篱         9          1.0         5.0
9       东篱        10          1.0         6.0
10      东篱        11          1.0         7.0
11      东篱        12          1.0         8.0

Process finished with exit code 0

text_anti_brush_function 脚本

# -*- coding: utf-8 -*-


# 导入包
import numpy as np
import jieba
from simhash import Simhash
import re


# 定义去掉图片html标签函数
def filter_html(html):
    """
    :param html: html
    :return: 返回去掉html的纯净文本
    """
    dr = re.compile(r'<[^>]+>', re.S)
    dd = dr.sub('', html).strip()
    return dd



# 句子文本转换成向量
def get_word_vector(s1, s2):
    """
    :param s1: 句子1
    :param s2: 句子2
    :return: 返回句子的余弦相似度
    """
    # 分词
    cut1 = jieba.cut(s1)
    cut2 = jieba.cut(s2)
    list_word1 = (','.join(cut1)).split(',')
    list_word2 = (','.join(cut2)).split(',')

    # 列出所有的词,取并集
    key_word = list(set(list_word1 + list_word2))
    # 给定形状和类型的用0填充的矩阵存储向量
    word_vector1 = np.zeros(len(key_word))
    word_vector2 = np.zeros(len(key_word))

    # 计算词频
    # 依次确定向量的每个位置的值
    for i in range(len(key_word)):
        # 遍历key_word中每个词在句子中的出现次数
        for j in range(len(list_word1)):
            if key_word[i] == list_word1[j]:
                word_vector1[i] += 1
        for k in range(len(list_word2)):
            if key_word[i] == list_word2[k]:
                word_vector2[i] += 1

    # 输出向量
    # print(word_vector1)
    # print(word_vector2)
    return word_vector1, word_vector2


# 计算两个向量之间的余弦相似度
def cos_dist(vec1, vec2):
    """
    :param vec1: 向量1
    :param vec2: 向量2
    :return: 返回两个向量的余弦相似度
    """
    dist1 = float(np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2)))
    return dist1




# 定义求两个短句子的相似度函数
def bow_similariry(text1,text2):
    """
    :param text1: 文本1
    :param text2: 文本2
    :return: 余弦相似度
    """
    text1 = filter_html(text1)
    text2 = filter_html(text2)

    vec1, vec2 = get_word_vector(text1, text2)
    dist=cos_dist(vec1, vec2)
    return dist


# 定义求两篇文章相似度函数
def simhash_similarity(text1, text2):
    """
    :param tex1: 文本1
    :param text2: 文本2
    :return: 返回两篇文章的相似度
    """
    text1 = filter_html(text1)
    text2 = filter_html(text2)
    aa_simhash = Simhash(text1)
    bb_simhash = Simhash(text2)
    max_hashbit = max(len(bin(aa_simhash.value)), (len(bin(bb_simhash.value))))
    # 汉明距离
    distince = aa_simhash.distance(bb_simhash)
    # 相似度计算
    similar = 1 - distince / max_hashbit
    return similar





# 定义判断句子是长文本或者短文本,并计算相似度
def similarity_classification(text1,text2):
    """
    :param text1: 文本1
    :param text2: 文本2
    :return: 返回相似度,短文本用tf-idf,长文本用simhash
    """
    len_1=len(text1)
    len_2=len(text2)
    # print(len_1, len_2)
    max_len=max(len_1,len_2)


    if max_len<50:

        return bow_similariry(text1,text2)
    else:
        return simhash_similarity(text1,text2)



def LCS(x,y):

    c=np.zeros((len(x)+1,len(y)+1))
    b=np.zeros((len(x)+1,len(y)+1))
    for i in range(1,len(x)+1):
        for j in range(1,len(y)+1):
            if x[i-1]==y[j-1]:
                c[i,j]=c[i-1,j-1]+1
                b[i,j]=2
            else:
                if c[i-1,j]>=c[i,j-1]:
                    c[i,j]=c[i-1,j]
                    b[i,j]=1
                else:
                    c[i,j]=c[i,j-1]
                    b[i,j]=3
    return c,b



# 最长公共子串
def getLCS(x,y):
    c,b=LCS(x,y)
    i=len(x)
    j=len(y)
    lcs=''
    while i>0 and j>0:
        if b[i][j]==2:
            lcs=x[i-1]+lcs
            i-=1
            j-=1
        if b[i][j]==1:
            i-=1
        if b[i][j]==3:
            j-=1
        if b[i][j]==0:
            break
    lcs_len=len(lcs)
    return lcs,lcs_len



# 最长公共子串相似度
def lcs_similarity(a,b):
    lcs, lcs_len = getLCS(a, b)
    similarity = round(lcs_len / max(len(a), len(b)), 4)
    return similarity
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页