热门标签 | HotTags
当前位置:  开发笔记 > 人工智能 > 正文

Java实现TFIDF算法代码分享

这篇文章主要介绍了Java实现TFIDF算法代码分享,对算法进行了简单介绍,概念,原理,以及实现代码的分享,具有一定参考价值,需要的朋友可以了解下。

算法介绍

概念

     TF-IDF(term frequency–inverse document frequency)是一种用于资讯检索与资讯探勘的常用加权技术。TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。TF-IDF加权的各种形式常被搜寻引擎应用,作为文件与用户查询之间相关程度的度量或评级。除了TF-IDF以外,因特网上的搜寻引擎还会使用基于连结分析的评级方法,以确定文件在搜寻结果中出现的顺序。

原理

在一份给定的文件里,词频(termfrequency,TF)指的是某一个给定的词语在该文件中出现的次数。这个数字通常会被归一化(分子一般小于分母区别于IDF),以防止它偏向长的文件。(同一个词语在长文件里可能会比短文件有更高的词频,而不管该词语重要与否。)

逆向文件频率(inversedocumentfrequency,IDF)是一个词语普遍重要性的度量。某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到。

某一特定文件内的高词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的TF-IDF。因此,TF-IDF倾向于过滤掉常见的词语,保留重要的词语。

TFIDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。TFIDF实际上是:TF*IDF,TF词频(TermFrequency),IDF反文档频率(InverseDocumentFrequency)。TF表示词条在文档d中出现的频率(另一说:TF词频(TermFrequency)指的是某一个给定的词语在该文件中出现的次数)。IDF的主要思想是:如果包含词条t的文档越少,也就是n越小,IDF越大,则说明词条t具有很好的类别区分能力。如果某一类文档C中包含词条t的文档数为m,而其它类包含t的文档总数为k,显然所有包含t的文档数n=m+k,当m大的时候,n也大,按照IDF公式得到的IDF的值会小,就说明该词条t类别区分能力不强。(另一说:IDF反文档频率(InverseDocumentFrequency)是指果包含词条的文档越少,IDF越大,则说明词条具有很好的类别区分能力。)但是实际上,如果一个词条在一个类的文档中频繁出现,则说明该词条能够很好代表这个类的文本的特征,这样的词条应该给它们赋予较高的权重,并选来作为该类文本的特征词以区别与其它类文档。这就是IDF的不足之处.

最近要做领域概念的提取,TFIDF作为一个很经典的算法可以作为其中的一步处理。

计算公式比较简单,如下:

预处理

由于需要处理的候选词大约后3w+,并且语料文档数有1w+,直接挨个文本遍历的话很耗时,每个词处理时间都要一分钟以上。

为了缩短时间,首先进行分词,一个词输出为一行方便统计,分词工具选择的是HanLp。

然后,将一个领域的文档合并到一个文件中,并用“$$$”标识符分割,方便记录文档数。

下面是选择的领域语料(PATH目录下):

代码实现

package edu.heu.lawsoutput;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
 * @ClassName: TfIdf
 * @Description: TODO
 * @author LJH
 * @date 2017年11月12日 下午3:55:15
 */
public class TfIdf {
	static final String PATH = "E:\\corpus";
	// 语料库路径
	public static void main(String[] args) throws Exception {
		String test = "离退休人员";
		// 要计算的候选词
		computeTFIDF(PATH, test);
	}
	/**
  * @param @param path 语料路经
  * @param @param word 候选词
  * @param @throws Exception 
  * @return void 
  */
	static void computeTFIDF(String path, String word) throws Exception {
		File fileDir = new File(path);
		File[] files = fileDir.listFiles();
		// 每个领域出现候选词的文档数
		Map cOntainsKeyMap= new HashMap<>();
		// 每个领域的总文档数
		Map totalDocMap = new HashMap<>();
		// TF = 候选词出现次数/总词数
		Map tfMap = new HashMap<>();
		// scan files
		for (File f : files) {
			// 候选词词频
			double termFrequency = 0;
			// 文本总词数
			double totalTerm = 0;
			// 包含候选词的文档数
			int cOntainsKeyDoc= 0;
			// 词频文档计数
			int totalCount = 0;
			int fileCount = 0;
			// 标记文件中是否出现候选词
			Boolean flag = false;
			FileReader fr = new FileReader(f);
			BufferedReader br = new BufferedReader(fr);
			String s = "";
			// 计算词频和总词数
			while ((s = br.readLine()) != null) {
				if (s.equals(word)) {
					termFrequency++;
					flag = true;
				}
				// 文件标识符
				if (s.equals("$$$")) {
					if (flag) {
						containsKeyDoc++;
					}
					fileCount++;
					flag = false;
				}
				totalCount++;
			}
			// 减去文件标识符的数量得到总词数
			totalTerm += totalCount - fileCount;
			br.close();
			// key都为领域的名字
			containsKeyMap.put(f.getName(), containsKeyDoc);
			totalDocMap.put(f.getName(), fileCount);
			tfMap.put(f.getName(), (double) termFrequency / totalTerm);
			System.out.println("----------" + f.getName() + "----------");
			System.out.println("该领域文档数:" + fileCount);
			System.out.println("候选词出现词数:" + termFrequency);
			System.out.println("总词数:" + totalTerm);
			System.out.println("出现候选词文档总数:" + containsKeyDoc);
			System.out.println();
		}
		//计算TF*IDF
		for (File f : files) {
			// 其他领域包含候选词文档数
			int otherCOntainsKeyDoc= 0;
			// 其他领域文档总数
			int otherTotalDoc = 0;
			double idf = 0;
			double tfidf = 0;
			System.out.println("~~~~~" + f.getName() + "~~~~~");
			Set> cOntainsKeyset= containsKeyMap.entrySet();
			Set> totalDocset = totalDocMap.entrySet();
			Set> tfSet = tfMap.entrySet();
			// 计算其他领域包含候选词文档数
			for (Map.Entry entry : containsKeyset) {
				if (!entry.getKey().equals(f.getName())) {
					otherContainsKeyDoc += entry.getValue();
				}
			}
			// 计算其他领域文档总数
			for (Map.Entry entry : totalDocset) {
				if (!entry.getKey().equals(f.getName())) {
					otherTotalDoc += entry.getValue();
				}
			}
			// 计算idf
			idf = log((float) otherTotalDoc / (otherContainsKeyDoc + 1), 2);
			// 计算tf*idf并输出
			for (Map.Entry entry : tfSet) {
				if (entry.getKey().equals(f.getName())) {
					tfidf = (double) entry.getValue() * idf;
					System.out.println("tfidf:" + tfidf);
				}
			}
		}
	}
	static float log(float value, float base) {
		return (float) (Math.log(value) / Math.log(base));
	}
}

运行结果

测试词为“离退休人员”,中间结果如下:

最终结果:

结论

可以看到“离退休人员”在养老保险和社保领域,tfidf值比较高,可以作为判断是否为领域概念的一个依据。

当然TF-IDF算法虽然很经典,但还是有许多不足,不能单独依赖其结果做出判断。

以上就是本文关于Java实现TFIDF算法代码分享的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:

Java 蒙特卡洛算法求圆周率近似值实例详解

java算法实现红黑树完整代码示例

java实现的各种排序算法代码示例

如有不足之处,欢迎留言指出。


推荐阅读
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • “你永远都不知道明天和‘公司的意外’哪个先来。”疫情期间,这是我们最战战兢兢的心情。但是显然,有些人体会不了。这份行业数据,让笔者“柠檬” ... [详细]
  • 生成对抗式网络GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
    一、GAN原理介绍学习GAN的第一篇论文当然由是IanGoodfellow于2014年发表的GenerativeAdversarialNetworks(论文下载链接arxiv:[h ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 无线认证设置故障排除方法及注意事项
    本文介绍了解决无线认证设置故障的方法和注意事项,包括检查无线路由器工作状态、关闭手机休眠状态下的网络设置、重启路由器、更改认证类型、恢复出厂设置和手机网络设置等。通过这些方法,可以解决无线认证设置可能出现的问题,确保无线网络正常连接和上网。同时,还提供了一些注意事项,以便用户在进行无线认证设置时能够正确操作。 ... [详细]
  • 本文介绍了游戏开发中的人工智能技术,包括定性行为和非定性行为的分类。定性行为是指特定且可预测的行为,而非定性行为则具有一定程度的不确定性。其中,追逐算法是定性行为的具体实例。 ... [详细]
  • JavaScript设计模式之策略模式(Strategy Pattern)的优势及应用
    本文介绍了JavaScript设计模式之策略模式(Strategy Pattern)的定义和优势,策略模式可以避免代码中的多重判断条件,体现了开放-封闭原则。同时,策略模式的应用可以使系统的算法重复利用,避免复制粘贴。然而,策略模式也会增加策略类的数量,违反最少知识原则,需要了解各种策略类才能更好地应用于业务中。本文还以员工年终奖的计算为例,说明了策略模式的应用场景和实现方式。 ... [详细]
  • 本文介绍了PhysioNet网站提供的生理信号处理工具箱WFDB Toolbox for Matlab的安装和使用方法。通过下载并添加到Matlab路径中或直接在Matlab中输入相关内容,即可完成安装。该工具箱提供了一系列函数,可以方便地处理生理信号数据。详细的安装和使用方法可以参考本文内容。 ... [详细]
  • 本文详细介绍了相机防抖的设置方法和使用技巧,包括索尼防抖设置、VR和Stabilizer档位的选择、机身菜单设置等。同时解释了相机防抖的原理,包括电子防抖和光学防抖的区别,以及它们对画质细节的影响。此外,还提到了一些运动相机的防抖方法,如大疆的Osmo Action的Rock Steady技术。通过本文,你将更好地理解相机防抖的重要性和使用技巧,提高拍摄体验。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 无损压缩算法专题——LZSS算法实现
    本文介绍了基于无损压缩算法专题的LZSS算法实现。通过Python和C两种语言的代码实现了对任意文件的压缩和解压功能。详细介绍了LZSS算法的原理和实现过程,以及代码中的注释。 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • 本文介绍了数模国赛的报名参加方法,包括学校报名和自己报名的途径。同时给出了建模竞赛的建议,重在历练的同时掌握方法以及弥补自己的短板。此外,还分享了论文的结构和模型求解部分的注意事项,包括数学命题的表述规范和计算方法的原理等。 ... [详细]
author-avatar
15-Sports
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有