TF-IDF的应用(一)比较文章相似度(附完整代码)

提出问题

假设现在有两篇文章,而这两篇文章的的标题十分相似,想通过计算机判断这两篇文章的相似程度,如果相似程度超过60%就断定这两篇文章有抄袭的嫌疑。需要如何实现呢?

余弦相似度

余弦相似度 (Cosine Similarity) 通过计算两个向量的夹角余弦值来评估他们的相似度。将向量根据坐标值,绘制到向量空间中,求得他们的夹角,并得出夹角对应的余弦值,此余弦值就可以用来表征这两个向量的相似性。夹角越小,余弦值越接近于1,它们的方向越吻合,则越相似。
假定A和B是两个n维向量,A是 [A1, A2, …, An] ,B是 [B1, B2, …, Bn] ,则A与B的夹角θ的余弦等于:
在这里插入图片描述

实现方法

1、将两段文本(或者只是两句话)分词;

def CutWord(fileName1,fileName2):
    try:
        lineNums = len(open(fileName1, 'r', encoding='utf-8').readlines())
        source = open(fileName1, "r", encoding='utf-8')
        result_fenci = open(fileName2, "w", encoding='utf-8')
        i = 0
        while i < lineNums:
            line = source.readline()
            line = line.rstrip('\n')
            reg = "[^0-9A-Za-z\u4e00-\u9fa5]"
            line = re.sub(reg, '', line)
            fenci = jieba.cut(line, cut_all=False)
            #fenci = jieba.cut_for_search(line, use_paddle=True)
            fenci =" ".join(fenci)
            #result_fenci.write(" ".join(fenci))
            result_fenci.write(fenci+"\n")
            i = i + 1
    except Exception as e:
        traceback.print_exc(e)
    finally:
        source.close()
        result_fenci.close()

2.两篇文章的关键词合并成一个集合,相同的合并,不同的添加

# 统计关键词及个数
def CountKey(fileName, resultName):
    try:
        # 计算文件行数
        lineNums = len(open(fileName, 'r',encoding='utf-8').readlines())
        print('文件行数: ' + str(lineNums))

        # 统计格式 格式<Key:Value> <属性:出现个数>
        i = 0
        table = {}
        source = open(fileName, "r",encoding='utf-8')
        result = open(resultName, "w",encoding='utf-8')

        while i < lineNums:
            line = source.readline()
            line = line.rstrip('\n')
            print(line)


            words = line.split(" ")  # 空格分隔

            # 字典插入与赋值
            for word in words:
                if word != "" and word in table:  # 如果存在次数加1
                    num = table[word]
                    table[word] = num + 1
                elif word != "":  # 否则初值为1
                    table[word] = 1
            i = i + 1

        # 键值从大到小排序 函数原型:sorted(dic,value,reverse)
        dic = sorted(table.items(), key=lambda d: d[1], reverse=True)
        for i in range(len(dic)):
            # print 'key=%s, value=%s' % (dic[i][0],dic[i][1])
            result.write("<" + dic[i][0] + ":" + str(dic[i][1]) + ">\n")
        return dic

    except Exception as e:
        traceback.print_exc(e)
    finally:
        source.close()
        result.close()
        print('END\n\n')


3.计算每篇文章对于这个集合的词的词频 TF-IDF算法计算权重
4.生成两篇文章各自的词频向量
5.计算两个向量的余弦相似度,值越大表示越相似

# 统计关键词及个数 并计算相似度

def MergeKeys(dic1, dic2):
    # 合并关键词 采用三个数组实现
    arrayKey = []
    for i in range(len(dic1)):
        arrayKey.append(dic1[i][0])  # 向数组中添加元素
    for i in range(len(dic2)):
        if dic2[i][0] in arrayKey:
            print('has_key', dic2[i][0])
        else:  # 合并
            arrayKey.append(dic2[i][0])
    else:
        print('\n\n')



    # 计算词频 infobox可忽略TF-IDF
    arrayNum1 = [0] * len(arrayKey)
    arrayNum2 = [0] * len(arrayKey)

    # 赋值arrayNum1
    for i in range(len(dic1)):
        key = dic1[i][0]
        value = dic1[i][1]
        j = 0
        while j < len(arrayKey):
            if key == arrayKey[j]:
                arrayNum1[j] = value
                break
            else:
                j = j + 1

    # 赋值arrayNum2
    for i in range(len(dic2)):
        key = dic2[i][0]
        value = dic2[i][1]
        j = 0
        while j < len(arrayKey):
            if key == arrayKey[j]:
                arrayNum2[j] = value
                break
            else:
                j = j + 1

    print(arrayNum1)
    print(arrayNum2)
    print(len(arrayNum1), len(arrayNum2), len(arrayKey))

    # 计算两个向量的点积
    x = 0
    i = 0
    while i < len(arrayKey):
        x = x + arrayNum1[i] * arrayNum2[i]
        i = i + 1
    print(x)

    # 计算两个向量的模
    i = 0
    sq1 = 0
    while i < len(arrayKey):
        sq1 = sq1 + arrayNum1[i] * arrayNum1[i]  # pow(a,2)
        i = i + 1
    print(sq1)

    i = 0
    sq2 = 0
    while i < len(arrayKey):
        sq2 = sq2 + arrayNum2[i] * arrayNum2[i]
        i = i + 1
    print(sq2)

    result = float(x) / (math.sqrt(sq1) * math.sqrt(sq2))
    return result
#主函数



def main():
    fileName1 = "Tourist_spots_5A/gugong.txt"
    resultName1 = "Result_Key_BD.txt"

    fileName2 = "Tourist_spots_5A/tiantan.txt"
    resultName2 = "Tourist_spots_5A/Result_Key_001.txt"

    # 使用jieba进行分词
    CutWord(fileName1, 'Tourist_spots_5A/gugong_fenci.txt')
    CutWord(fileName2, 'Tourist_spots_5A/tiantan_fenci.txt')

    # 计算文档1-百度的关键词及个数
    dic1 = CountKey('Tourist_spots_5A/gugong_fenci.txt', resultName1)

    # 计算文档2-互动的关键词及个数
    dic2 = CountKey('Tourist_spots_5A/tiantan_fenci.txt', resultName2)

    # 合并两篇文章的关键词及相似度计算
    result = MergeKeys(dic1, dic2)
    print(result)
    
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
namespace ServiceRanking { /// <summary> /// Summary description for TF_IDFLib. /// </summary> public class TFIDFMeasure { private string[] _docs; private string[][] _ngramDoc; private int _numDocs=0; private int _numTerms=0; private ArrayList _terms; private int[][] _termFreq; private float[][] _termWeight; private int[] _maxTermFreq; private int[] _docFreq; public class TermVector { public static float ComputeCosineSimilarity(float[] vector1, float[] vector2) { if (vector1.Length != vector2.Length) throw new Exception("DIFER LENGTH"); float denom=(VectorLength(vector1) * VectorLength(vector2)); if (denom == 0F) return 0F; else return (InnerProduct(vector1, vector2) / denom); } public static float InnerProduct(float[] vector1, float[] vector2) { if (vector1.Length != vector2.Length) throw new Exception("DIFFER LENGTH ARE NOT ALLOWED"); float result=0F; for (int i=0; i < vector1.Length; i++) result += vector1[i] * vector2[i]; return result; } public static float VectorLength(float[] vector) { float sum=0.0F; for (int i=0; i < vector.Length; i++) sum=sum + (vector[i] * vector[i]); return (float)Math.Sqrt(sum); } } private IDictionary _wordsIndex=new Hashtable() ; public TFIDFMeasure(string[] documents) { _docs=documents; _numDocs=documents.Length ; MyInit(); } private void GeneratNgramText() { } private ArrayList GenerateTerms(string[] docs) { ArrayList uniques=new ArrayList() ; _ngramDoc=new string[_numDocs][] ; for (int i=0; i < docs.Length ; i++) { Tokeniser tokenizer=new Tokeniser() ; string[] words=tokenizer.Partition(docs[i]); for (int j=0; j < words.Length ; j++) if (!uniques.Contains(words[j]) ) uniques.Add(words[j]) ; } return uniques; } private static object
### 回答1: TF-IDF结合余弦相似度是一种常用的文本相似度分析方法。TF-IDF是一种用于评估一个词语在文档中的重要程度的统计方法,它考虑了一个词语在文档中出现的频率以及在整个语料库中出现的频率。余弦相似度是一种用于计算两个向量之间的相似度的方法,它可以用于计算文本之间的相似度。将TF-IDF余弦相似度结合起来,可以计算出两个文本之间的相似度,从而实现文本相似度分析。 ### 回答2: TF-IDF(term frequency-inverse document frequency)是一种常用的文本特征提取方法,被广泛用于文本数据挖掘和信息检索中。它的基本思想是将每个词汇在文本中的重要性权值化,从而实现文本相似度分析。 在TF-IDF中,文本中某个词汇的重要性被定义为该词汇在所有文档中出现的频率(即词频)与该词汇在当前文档中出现的频率的乘积的对数。TF-IDF计算方式可以分为两个步骤:第一步是计算词频TF(term frequency),即某个词汇在当前文档中出现的次数除以该文档中所有词汇的总数。第二步是计算逆文档频率IDF(inverse document frequency),即所有文档数目除以包含该词汇的文档数的对数。最终的TF-IDF权值为TF和IDF的乘积。 余弦相似度是一种常用的衡量两个文本相似度的方法,其基本思想是将文本向量映射到一个n维空间中,然后计算两个文本向量在该空间中的夹角余弦值。余弦值越大,表示两个文本的相似度越高。 把TF-IDF结合余弦相似度来做相似度分析,具体步骤如下: 1. 对于每个文本,利用TF-IDF方法计算每个词汇的权值。 2. 把文本中所有词汇的权值按照其在字典中的顺序排列,构成一个向量。 3. 对于两个文本,分别计算它们的TF-IDF向量。 4. 计算两个向量之间的夹角余弦值,它的值越接近1,表示两个向量越相似。 5. 如果需要对多个文本进行相似度分析,可以计算每个文本与其他文本的相似度,然后根据相似度值进行排名。 TF-IDF结合余弦相似度相似度分析具有以下优点: 1. 通过对每个词汇的权值进行计算,可以准确地反映它在文本中的重要性。 2. 余弦相似度可以在一个高维向量空间中进行,可以避免维数灾难的问题。 3. 多个文本可以进行快速的比较和排序。 4. 可以应用于各种文本数据挖掘和信息检索任务,如推荐系统、文本分类和信息抽取等。 综上所述,TF-IDF结合余弦相似度是一种非常有效的文本相似度分析方法,可以广泛应用于各种文本数据挖掘和信息检索任务中。 ### 回答3: tf-idf结合余弦相似度是一种常用的文本相似度分析方法。它可以用于比较不同文本之间的相似性,以便确定它们是否具有相同的主题或意义。 tf-idf是一种文本特征提取技术,可以计算出某个词在文本中的重要程度。具体来说,tf-idf通过计算某个词在文本中的频率(tf)和在文集中的逆文档频率(idf)来确定其重要程度。逆文档频率表示某个词在文集中的普及程度,计算公式为:$idf(t)=log\frac{N}{df_t}$,其中N表示文集中文档的总数,$df_t$表示出现词t的文档数。 余弦相似度是一种衡量两个向量之间夹角的度量方法。在文本相似度分析中,可以将文本看作是向量,其中每个维度表示一个词的重要程度。通过计算两个文本向量余弦相似度,可以得到它们之间的相似度。 将tf-idf余弦相似度结合起来,可以实现文本相似度分析。具体来说,可以先将每个文本转换成一个向量,根据tf-idf计算出每个向量中每个词的重要程度,并根据余弦相似度计算出两个向量之间的相似度。通过比较所有文本之间的相似度,可以找到相似度较高的文本,进而确定它们之间是否具有相同的主题或意义。 总之,tf-idf结合余弦相似度是一种有效的文本相似度分析方法,可以帮助我们快速准确地比较不同文本之间的相似性。在信息检索、推荐系统、自然语言处理等领域都有广泛的应用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值