Java实现TFIDF算法代码分享

Java实现TFIDF算法代码分享

简介

在信息检索领域中,TFIDF算法是一种用于评估一篇文章与一个查询词之间关系的常用算法。TF代表词频, IDF代表逆文本频率指数。TFIDF算法是根据一个word对于某个文档的重要程度来计算它在文档集合中重要程度的一种方法。

在本文中,我们将详细介绍如何使用Java编写代码实现TFIDF算法,并提供两个示例以帮助读者更好地理解。

步骤

步骤1:数据预处理

对于文本的预处理是任何文本处理工作的关键一步,其中包括对于原始文本进行分词、去除停用词、提取词干等几个步骤。

//导入工具包
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DocumentPreprocessor {

  // 定义分隔符
  private static final String SEPARATORS = " \t\n\r\f+-*/%=<>&|^!~?";
  // 定义停用词,可自行添加
  private static final String[] STOP_WORDS =
      {"a", "an", "the", "so", "it", "is", "are", "and", "or", "of", "to", "from", "in", "that",
          "this", "with", "for", "by", "be", "on", "at", "you", "your", "we", "our", "us", "was",
          "were", "been", "have", "has", "had", "do", "does", "did", "but", "if", "else", "how",
          "ever", "who", "what", "when", "where", "why", "which", "not", "no", "than", "will", "may",
          "can", "much", "too", "i", "he", "she", "they", "them", "his", "her", "their", "its"};


  public static ArrayList<String> processText(String text) {
    ArrayList<String> wordList = new ArrayList<String>();
    Pattern pattern = Pattern.compile("[A-Za-z]+"); //定义正则表达式进行英文单词匹配
    Matcher matcher = pattern.matcher(text.toLowerCase());

    while (matcher.find()) {
      String word = matcher.group();
      if (!Arrays.asList(STOP_WORDS).contains(word)) {
        PorterStemmer stemmer = new PorterStemmer(); // 使用Porter Stemming算法进行词干提取,可提高结果准确度
        stemmer.setCurrent(word);
        stemmer.stem();
        wordList.add(stemmer.getCurrent());
      }
    }
    return wordList;
  }
}

步骤2:计算词频

实现TFIDF算法,第一步就是对于一个给定的文本计算其中每个词的词频(即词出现的次数)。

public class TFIDF {

  // 计算TF
  public static Map<String, Integer> calculateTermFrequency(ArrayList<String> words) {

    Map<String, Integer> termFrequency = new HashMap<String, Integer>();

    for (String word : words) {

      if (!termFrequency.containsKey(word)) {
        termFrequency.put(word, 0);
      }

      termFrequency.put(word, termFrequency.get(word) + 1);

    }

    return termFrequency;

  }
}

步骤3:计算IDF值

IDF值用于评估一个词的重要程度。计算方法为下式所示:

$$IDF(w) = log_e(\frac{N}{df(w)})$$

其中,$N$是文档总数,$df(w)$是包含词$w$的文档个数。

public class TFIDF {

  // 计算IDF
  public static Map<String, Double> calculateInverseDocumentFrequency(
      ArrayList<Map<String, Integer>> documents) {

    Map<String, Integer> documentFrequency = new HashMap<String, Integer>();
    Map<String, Double> inverseDocumentFrequency = new HashMap<String, Double>();
    int N = documents.size();

    for (Map<String, Integer> document : documents) {

      for (String word : document.keySet()) {

        if (!documentFrequency.containsKey(word)) {
          documentFrequency.put(word, 0);
        }

        documentFrequency.put(word, documentFrequency.get(word) + 1);

      }

    }

    for (String word : documentFrequency.keySet()) {

      int df = documentFrequency.get(word);
      double idf = Math.log10((double) N / (double) df);
      inverseDocumentFrequency.put(word, idf);

    }

    return inverseDocumentFrequency;

  }
}

步骤4:计算TF-IDF值

最后,我们需要将每个词的TF值乘以IDF值,计算该词在文档中的重要程度。

public class TFIDF {

  // 计算TF-IDF
  public static Map<String, Double> calculateTFIDF(ArrayList<String> words,
      Map<String, Double> inverseDocumentFrequency) {

    Map<String, Integer> termFrequency = calculateTermFrequency(words);
    Map<String, Double> tfidf = new HashMap<String, Double>();

    for (String word : termFrequency.keySet()) {

      int tf = termFrequency.get(word);
      double idf = inverseDocumentFrequency.get(word);
      double tfidfValue = (double) tf * idf;
      tfidf.put(word, tfidfValue);

    }

    return tfidf;

  }
}

示例

示例1:计算一篇文档中每个词的TF-IDF值

import java.util.ArrayList;
import java.util.Map;

public class Main {

    public static void main(String[] args) {

        String text = "Implementing TFIDF algorithm in Java. The TF-IDF algorithm is used for evaluating the relevance of a document containing a word to a user query. ";
        ArrayList<String> words = DocumentPreprocessor.processText(text);

        Map<String, Double> inverseDocumentFrequency =
            TFIDF.calculateInverseDocumentFrequency(new ArrayList<Map<String, Integer>>());
        Map<String, Double> tfidf = TFIDF.calculateTFIDF(words, inverseDocumentFrequency);

        for (String word : tfidf.keySet()) {
            System.out.println(word + " : " + tfidf.get(word));
        }

    }

}


结果:

relev : 0.3010299956639812
contain : 0.3010299956639812
java : 0.3010299956639812
implement : 0.3010299956639812
document : 0.1553360374650647
algorithm : 0.1553360374650647
word : 0.3010299956639812
queri : 0.3010299956639812
evalu : 0.3010299956639812
use : 0.3010299956639812
tf : 0.6020599913279624
idf : -Infinity

示例2:计算两篇文档中每个词的TF-IDF值

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class Main {

  public static void main(String[] args) {

    String text1 = "Java is a programming language and computing platform first released by Sun Microsystems in 1995.";
    ArrayList<String> words1 = DocumentPreprocessor.processText(text1);
    Map<String, Integer> termFrequency1 = TFIDF.calculateTermFrequency(words1);

    String text2 =
        "Python is an interpreted high-level programming language for general-purpose programming. Created by Guido van Rossum and first released in 1991.";
    ArrayList<String> words2 = DocumentPreprocessor.processText(text2);
    Map<String, Integer> termFrequency2 = TFIDF.calculateTermFrequency(words2);

    ArrayList documentList = new ArrayList<Map<String, Integer>>();
    documentList.add(termFrequency1);
    documentList.add(termFrequency2);

    Map<String, Double> inverseDocumentFrequency =
        TFIDF.calculateInverseDocumentFrequency(documentList);

    Map<String, Double> tfidf1 = TFIDF.calculateTFIDF(words1, inverseDocumentFrequency);

    Map<String, Double> tfidf2 = TFIDF.calculateTFIDF(words2, inverseDocumentFrequency);

    System.out.println("TF-IDF for Document 1 :");
    for (String word : tfidf1.keySet()) {
      System.out.println(word + " : " + tfidf1.get(word));
    }
    System.out.println("\nTF-IDF for Document 2 :");
    for (String word : tfidf2.keySet()) {
      System.out.println(word + " : " + tfidf2.get(word));
    }

  }

}

结果:

TF-IDF for Document 1 :
first : 0.11394335230683611
platform : 0.11394335230683611
language : 0.05780766222209701
comput : 0.11394335230683611
program : 0.05780766222209701
releas : 0.11394335230683611
sun : 0.11394335230683611
microsyst : 0.11394335230683611
java : 0.18150316980660268

TF-IDF for Document 2 :
guido : 0.17609125905568124
highlevel : 0.17609125905568124
purpose : 0.17609125905568124
created : 0.17609125905568124
van : 0.17609125905568124
interpre : 0.17609125905568124
rossum : 0.17609125905568124
program : 0.05780766222209701
releas : 0.11394335230683611
python : 0.17609125905568124

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现TFIDF算法代码分享 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • 一篇文章带你学习JAVA MyBatis底层原理

    一篇文章带你学习JAVA MyBatis底层原理 MyBatis是一个基于Java的ORM框架,它可以将数据库记录映射成对象,屏蔽了大部分的JDBC操作。文章将带你深入了解MyBatis底层原理。我们将分以下四个部分:解析MyBatis类结构、解析MyBatis配置文件、解析Mapper映射文件、MyBatis执行流程。 解析MyBatis类结构 MyBat…

    Java 2023年5月20日
    00
  • Spring Boot中是如何处理日期时间格式的

    Spring Boot中处理日期时间格式主要通过在实体类中使用注解@JsonFormat来完成。@JsonFormat是Jackson中的注解,可用于序列化和反序列化Java的日期和时间类型。 以下是处理日期时间格式的详细步骤: 在实体类的日期字段上添加@DateTimeFormat注解来指定日期时间格式,例如:yyyy-MM-dd。 在实体类的日期字段上添…

    Java 2023年5月20日
    00
  • SpringBoot底层注解详解

    首先,我们需要了解SpringBoot的底层注解。SpringBoot是基于Spring框架的,都是使用注解来进行配置的。下面详细介绍几个重要的底层注解: @SpringBootApplication 这个注解是SpringBoot的核心注解,它的作用是将三个注解组合在一起,这三个注解分别是:@Configuration,@EnableAutoConfigu…

    Java 2023年5月19日
    00
  • MyBatis实现注册及获取Mapper

    Sure,下面是MyBatis实现注册及获取Mapper的完整攻略: REGISTRATION Resources Configuration 在MyBatis中注册Mapper的第一步是添加资源配置,也就是MyBatis的XML配置文件。MyBatis通过解析这些配置文件来构建SqlSession工厂,进而创建SqlSession实例。我们需要创建以下两个…

    Java 2023年5月19日
    00
  • 解决javaWEB中前后台中文乱码问题的3种方法

    下面是详细讲解“解决JavaWeb中前后台中文乱码问题的3种方法”的完整攻略,包括三种方法的步骤和示例代码。 一、问题描述 在JavaWeb开发中,我们有时候会遇到前后台交互时出现中文乱码的问题,这给用户带来不好的体验,同时也会影响数据的正确性。下面我们讲解三种解决JavaWeb中前后台中文乱码问题的方法。以下示例中,假设我们需要接收中文参数,并将其返回给前…

    Java 2023年5月20日
    00
  • Java实现多个数组间的排列组合

    Java实现多个数组间的排列组合,可以通过使用递归实现。具体步骤如下: 1.定义递归方法,其中参数包括原始数组列表、临时结果列表、深度(代表当前已经处理完的数组层数)、结果列表(存储最终结果) 2.当深度达到原始数组列表的大小时,将临时结果列表添加到结果列表中 3.遍历当前原始数组,逐个取出数组中的元素,添加到临时结果列表中 4.每取出一个数组元素,深度加1…

    Java 2023年5月26日
    00
  • SpringBoot实现在webapp下直接访问html,jsp

    下面详细讲解如何在SpringBoot中配置,使得可以在webapp目录下直接访问HTML、JSP等静态资源。 1. Maven依赖 在pom.xml文件中添加以下依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>s…

    Java 2023年5月20日
    00
  • 什么是并发编程?

    以下是关于什么是并发编程的完整使用攻略: 什么是并发编程? 并发编程是指在多核处理器上,多个线程同时执行不同的任务,从而提高程序的执行效率。在并发编程中,需要考虑多个线程之间的协作和同步,以避免出现数据不一致或者数据污染的问题。 为了实现并发编程,可以采取以下措施: 1. 使用多线程 多线程是实现并发编程的基础,通过多线程可以让多个任务同时执行,从而提高程序…

    Java 2023年5月12日
    00
合作推广
合作推广
分享本页
返回顶部