欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實(shí)現(xiàn)文本查重的方法詳解

 更新時(shí)間:2024年04月16日 14:30:47   作者:Barcke  
Ansj 是一個(gè)開源的 Java 中文分詞工具,基于中科院的 ictclas 中文分詞算法,采用隱馬爾科夫模型(HMM),比其他常用的開源分詞工具(如 MMseg4j)的分詞準(zhǔn)確率更高,下面我們就來(lái)使用它實(shí)現(xiàn)文本查重功能吧

ansj 分詞法介紹

Ansj 是一個(gè)開源的 Java 中文分詞工具,基于中科院的 ictclas 中文分詞算法,采用隱馬爾科夫模型(HMM),比其他常用的開源分詞工具(如 MMseg4j)的分詞準(zhǔn)確率更高。作者為孫?。╝nsjsun),目前實(shí)現(xiàn)了中文分詞、中文姓名識(shí)別、用戶自定義詞典、關(guān)鍵字提取、自動(dòng)摘要、關(guān)鍵字標(biāo)記等功能,適用于對(duì)分詞效果要求高的各種項(xiàng)目。 雖然 Ansj 分詞的基本原理與 ictclas 的一樣,但是 Ansj 做了一些工程上的優(yōu)化,比如:用 DAT 高效地實(shí)現(xiàn)檢索詞典、鄰接表實(shí)現(xiàn)分詞 DAG、支持自定義詞典與自定義消歧義規(guī)則等。

Ansj 分詞器 git地址: github.com/NLPchina/ansj_seg

配置文件

在ansj中配置文件名為library.properties,這是一個(gè)不可更改的約定。

字段名默認(rèn)值說(shuō)明
isNameRecognitiontrue是否開啟人名識(shí)別
isNumRecognitiontrue是否開啟數(shù)字識(shí)別
isQuantifierRecognitiontrue是否數(shù)字和量詞合并
isRealNamefalse是否取得真實(shí)的詞,默認(rèn)情況會(huì)取得標(biāo)注化后的
isSkipUserDefinefalse是否用戶辭典不加載相同的詞
diclibrary/default.dic自定義詞典路徑
dic_[key]你的詞典路徑針對(duì)不同語(yǔ)料調(diào)用不同的自定義詞典
ambiguitylibrary/ambiguity.dic歧義詞典路徑
ambiguity_[key]library/ambiguity.dic歧義詞典路徑
crfnullcrf 詞典路徑,不設(shè)置為默認(rèn)
crf_[key]你的模型路徑針對(duì)不同語(yǔ)料調(diào)用不同的分詞模型
synonyms默認(rèn)的同義詞典針對(duì)不同語(yǔ)料調(diào)用不同的分詞模型
synonyms_[key]你的同義詞典路徑針對(duì)不同語(yǔ)料調(diào)用不同的分詞模型

默認(rèn)的配置文件:

#path of userLibrary this is default library
dic=library/default.dic

#redress dic file path
ambiguityLibrary=library/ambiguity.dic

#set real name
isRealName=true

#isNameRecognition default true
isNameRecognition=true

#isNumRecognition default true
isNumRecognition=true

#digital quantifier merge default true
isQuantifierRecognition=true

目前支持的分詞策略:

名稱用戶自定義詞典數(shù)字識(shí)別人名識(shí)別機(jī)構(gòu)名識(shí)別新詞發(fā)現(xiàn)
BaseAnalysisXXXXX
ToAnalysisXX
DicAnalysisXX
IndexAnalysisXX
NlpAnalysis

計(jì)算余弦相似度

余弦相似度是常見的相似度衡量手段,能夠用以比對(duì)兩個(gè)向量間的相似水準(zhǔn)。如下代碼呈現(xiàn)了計(jì)算兩篇論文之余弦相似度的方式:

余弦相似度是一種常用的計(jì)算兩個(gè)向量相似性的方法。它基于向量的點(diǎn)積和向量的模。

計(jì)算余弦相似度的原理如下:

  • 向量表示:將需要比較的對(duì)象表示為向量。
  • 點(diǎn)積運(yùn)算:計(jì)算兩個(gè)向量的點(diǎn)積,即對(duì)應(yīng)元素相乘后再求和。
  • 向量模的計(jì)算:分別計(jì)算每個(gè)向量的模,通常使用歐幾里得范數(shù)。
  • 計(jì)算余弦相似度:用兩個(gè)向量的點(diǎn)積除以它們的模的乘積。

具體公式為:

余弦相似度 = 向量 A 與向量 B 的點(diǎn)積 / (向量 A 的模 × 向量 B 的模)

余弦相似度的取值范圍在 -1 到 1 之間:

  • 值為 1:表示兩個(gè)向量完全相同,即具有最大相似度。
  • 值為 0:表示兩個(gè)向量相互垂直,即沒(méi)有相似性。
  • 值為 -1:表示兩個(gè)向量完全相反,即具有最小相似度。

余弦相似度的優(yōu)點(diǎn)包括:

  • 不受向量大小影響:它比較的是向量的方向,而不是它們的絕對(duì)大小。
  • 對(duì)噪聲相對(duì)不敏感:在存在一些噪聲或誤差的情況下仍能給出相對(duì)合理的相似度度量。

在實(shí)際應(yīng)用中,余弦相似度常用于:

  • 文本相似性度量:比較文本向量的相似度。
  • 圖像相似性分析:衡量圖像特征向量的相似程度。
  • 推薦系統(tǒng):找到用戶或物品之間的相似性。
/**
     * 計(jì)算余弦相似度
     * @param vec1 map1
     * @param vec2 map2
     * @return 相似度
     */
    public double calculateCosSimilarity(Map<String, Integer> vec1, Map<String, Integer> vec2) {
        double dotProduct = 0.0;
        double norm1 = 0.0;
        double norm2 = 0.0;
        for (Map.Entry<String, Integer> entry : vec1.entrySet()) {
            String word = entry.getKey();
            int count = entry.getValue();
            dotProduct += count * vec2.getOrDefault(word, 0);
            norm1 += Math.pow(count, 2);
        }
        for (Map.Entry<String, Integer> entry : vec2.entrySet()){
            int count = entry.getValue();
            norm2 += Math.pow(count, 2);
        }
        return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));
    }

    /**
     * 計(jì)算余弦相似度
     * @param context1 文本1
     * @param context2 文本2
     * @return 相似度
     */
    public double calculateCosSimilarity(String context1, String context2){
        return calculateCosSimilarity(participleNlp(context1).stream().collect(Collectors.groupingBy(o -> o, Collectors.summingInt(o -> 1))),
                participleNlp(context2).stream().collect(Collectors.groupingBy(o -> o, Collectors.summingInt(o -> 1))));
    }

具體實(shí)現(xiàn)看這里

mavaen 依賴

采用 ansj 5.1.6的版本

        <dependency>
            <groupId>org.ansj</groupId>
            <artifactId>ansj_seg</artifactId>
            <version>5.1.6</version>
        </dependency>

util 代碼如下

package cn.ideamake.business.tools.util;

import lombok.experimental.UtilityClass;
import org.ansj.domain.Term;
import org.ansj.splitWord.analysis.NlpAnalysis;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Barcke
 * @version 1.0
 * @projectName business-tools
 * @className TextPlagiarismCheckUtil
 * @date 2024/4/16 09:40
 * @slogan: 源于生活 高于生活
 * @description: 文本查重工具 分詞采用 ansj 分詞方法
 **/
@UtilityClass
public class TextPlagiarismCheckUtil {

    // 分詞方法 可替換?。?!  start 
    
    /**
     * Nlp分詞方式
     * @param context 文本信息
     * @return 分詞后的list
     */
    public List<String> participleNlp(String context){
        return participleNlpToTerm(context).stream().map(Term::getName).collect(Collectors.toList());
    }

    /**
     * Nlp分詞方式
     * @param context 文本信息
     * @return 分詞后的Term
     */
    public List<Term> participleNlpToTerm(String context){
        return NlpAnalysis.parse(context).getTerms();
    }

    // 分詞方法 可替換!??!  end

    /**
     * 計(jì)算余弦相似度
     * @param vec1 map1
     * @param vec2 map2
     * @return 相似度
     */
    public double calculateCosSimilarity(Map<String, Integer> vec1, Map<String, Integer> vec2) {
        double dotProduct = 0.0;
        double norm1 = 0.0;
        double norm2 = 0.0;
        for (Map.Entry<String, Integer> entry : vec1.entrySet()) {
            String word = entry.getKey();
            int count = entry.getValue();
            dotProduct += count * vec2.getOrDefault(word, 0);
            norm1 += Math.pow(count, 2);
        }
        for (Map.Entry<String, Integer> entry : vec2.entrySet()){
            int count = entry.getValue();
            norm2 += Math.pow(count, 2);
        }
        return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));
    }

    /**
     * 計(jì)算余弦相似度
     * @param context1 文本1
     * @param context2 文本2
     * @return 相似度
     */
    public double calculateCosSimilarity(String context1, String context2){
        return calculateCosSimilarity(participleNlp(context1).stream().collect(Collectors.groupingBy(o -> o, Collectors.summingInt(o -> 1))),
                participleNlp(context2).stream().collect(Collectors.groupingBy(o -> o, Collectors.summingInt(o -> 1))));
    }

    /**
     * 判斷文本是否重復(fù)
     * @param context1 文本1
     * @param context2 文本2
     * @param threshold 閾值
     * @return 是否重復(fù)
     */
    public boolean ifPlagiarism(String context1, String context2, double threshold){
        return calculateCosSimilarity(context1, context2) > threshold;
    }

    /**
     * 判斷文本是否重復(fù) 默認(rèn)閾值 0.7
     * @param context1 文本1
     * @param context2 文本2
     * @return 是否重復(fù)
     */
    public boolean ifPlagiarism(String context1, String context2){
        return ifPlagiarism(context1, context2, 0.7);
    }

}

使用案例

    public static void main(String[] args) {
        String str = "java實(shí)現(xiàn)論文查重,文本查重方案 采用 ansj 分詞法(barcke) -----" ;

        String str2 = "java實(shí)現(xiàn)論文查重,文本查重方案 采用 ansj 分詞法(barcke) -----" ;

	    String str3 = "java實(shí)現(xiàn)cke) -----" ;

        System.out.println("分詞數(shù)據(jù)(ansj分詞法):" + TextPlagiarismCheckUtil.participleNlp(str));

        System.out.println("重復(fù)率:" + TextPlagiarismCheckUtil.calculateCosSimilarity(str, str2) + "是否重復(fù)(默認(rèn)閾值0.7):" + TextPlagiarismCheckUtil.ifPlagiarism(str, str2));

        System.out.println("重復(fù)率:" + TextPlagiarismCheckUtil.calculateCosSimilarity(str, str3) + "是否重復(fù)(默認(rèn)閾值0.7):" + TextPlagiarismCheckUtil.ifPlagiarism(str, str3));
    }

執(zhí)行結(jié)果:

到此這篇關(guān)于Java實(shí)現(xiàn)文本查重的方法詳解的文章就介紹到這了,更多相關(guān)Java文本查重內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java?SpringAOP技術(shù)之注解方式詳解

    Java?SpringAOP技術(shù)之注解方式詳解

    這篇文章主要為大家詳細(xì)介紹了Java?SpringAOP技術(shù)之注解方式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-02-02
  • 深入理解什么是Mybatis懶加載(延遲加載)

    深入理解什么是Mybatis懶加載(延遲加載)

    這篇文章主要介紹了深入理解什么是Mybatis懶加載(延遲加載),mybatis的懶加載,也稱為延遲加載,是指在進(jìn)行關(guān)聯(lián)查詢的時(shí)候,按照設(shè)置延遲規(guī)則推遲對(duì)關(guān)聯(lián)對(duì)象的select查詢,延遲加載可以有效的減少數(shù)據(jù)庫(kù)壓力,需要的朋友可以參考下
    2023-10-10
  • JAVA代碼設(shè)置selector不同狀態(tài)下的背景顏色

    JAVA代碼設(shè)置selector不同狀態(tài)下的背景顏色

    這篇文章主要介紹了JAVA代碼設(shè)置selector不同狀態(tài)下的背景顏色,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-05-05
  • Mybatis + js 實(shí)現(xiàn)下拉列表二級(jí)聯(lián)動(dòng)效果

    Mybatis + js 實(shí)現(xiàn)下拉列表二級(jí)聯(lián)動(dòng)效果

    這篇文章給大家介紹基于Mybatis + js 實(shí)現(xiàn)下拉列表二級(jí)聯(lián)動(dòng)效果,實(shí)現(xiàn)代碼分為前端界面實(shí)現(xiàn)和后端處理方法,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-06-06
  • spring的13個(gè)經(jīng)典面試題

    spring的13個(gè)經(jīng)典面試題

    Spring框架是一個(gè)開放源代碼的J2EE應(yīng)用程序框架,是針對(duì)bean的生命周期進(jìn)行管理的輕量級(jí)容Spring解決了開發(fā)者在J2EE開發(fā)中遇到的許多常見的問(wèn)題,我們這篇文章就來(lái)了解一下spring的面試題
    2021-06-06
  • Java高效調(diào)試排查代碼技巧詳解

    Java高效調(diào)試排查代碼技巧詳解

    這篇文章主要介紹了Java高效調(diào)試排查代碼技巧,調(diào)試是一項(xiàng)不可或缺的技能,無(wú)論你是經(jīng)驗(yàn)豐富的開發(fā)者,還是初入編程世界的新手,都難免會(huì)遇到代碼出錯(cuò)的情況,有效的調(diào)試能幫助我們快速定位并解決問(wèn)題,提高開發(fā)效率,需要的朋友可以參考下
    2025-04-04
  • Java 創(chuàng)建兩個(gè)線程模擬對(duì)話并交替輸出實(shí)現(xiàn)解析

    Java 創(chuàng)建兩個(gè)線程模擬對(duì)話并交替輸出實(shí)現(xiàn)解析

    這篇文章主要介紹了Java 創(chuàng)建兩個(gè)線程模擬對(duì)話并交替輸出實(shí)現(xiàn)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • Java中的LinkedHashMap源碼分析

    Java中的LinkedHashMap源碼分析

    這篇文章主要介紹了Java中的LinkedHashMap源碼分析,LinkedHashMap是HashMap的子類,所以基本的操作與hashmap類似,不過(guò)呢,在插入、刪除、替換key-value對(duì)的時(shí)候,需要的朋友可以參考下
    2023-12-12
  • SpringBoot利用攔截器實(shí)現(xiàn)避免重復(fù)請(qǐng)求

    SpringBoot利用攔截器實(shí)現(xiàn)避免重復(fù)請(qǐng)求

    Spring MVC中的攔截器(Interceptor)類似于Servlet中的過(guò)濾器(Filter),它主要用于攔截用戶請(qǐng)求并作相應(yīng)的處理。本文就將利用攔截器實(shí)現(xiàn)避免重復(fù)請(qǐng)求,感興趣的小伙伴可以了解一下
    2022-11-11
  • SpringBoot應(yīng)用啟動(dòng)流程源碼解析

    SpringBoot應(yīng)用啟動(dòng)流程源碼解析

    這篇文章主要介紹了SpringBoot應(yīng)用啟動(dòng)流程源碼解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04

最新評(píng)論