算法介绍

概念

TF-IDF(term frequencyCinverse 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算法代码分享的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:

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

tfidf处理代码_Java实现TFIDF算法代码分享相关推荐

  1. MATLAB代码:全面ADMM算法代码,实现了三种ADMM迭代方式

    MATLAB代码:全面ADMM算法代码,实现了三种ADMM迭代方式 关键词:综合能源 分布式协同优化 交替方向乘子法 最优潮流 参考文档:<基于串行和并行ADMM算法的电_气能量流分布式协同优化 ...

  2. java的一段排序代码_Java常见排序算法——快速排序

    概念: 通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分小,则可分别对这两部分记录继续进行排序,直到整个序列有序. 原理: 在数据集之中,选择一个元素作为"基准 ...

  3. java代码实现希尔排序_Java希尔排序算法代码实现

    Java希尔排序算法代码实现 时间:2017-08-30     来源:华清远见JAVA学院 什么是Java希尔排序算法呢? 希尔排序算法实际上是一种分组插入的排序算法,又被称为缩小增量排序.今天华清 ...

  4. 高斯模糊java代码_Java实现高斯模糊算法处理图像

    高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop.GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪声以及降低细节层次 ...

  5. 高斯模糊java代码_Java 实现高斯模糊算法

    接上篇文章<高斯模糊算法的原理>,本文我们借助 java 来实现高斯模糊算法,并使用高斯模糊算法处理实际图片. 高斯模糊就是图像和高斯函数的卷积.等价于傅里叶变换后乘上高斯函数再逆变换回来 ...

  6. 迷宫java代码_java写的迷宫代码

    迷宫代码: 截图如下: packagecom.zxl.maze;/** 抽象类表示选择不同的算法*/ public abstract classAbstractMap {/** 得到数据*/ publ ...

  7. java全面的计算器代码_Java实现计算器的代码

    用java 实现的计算器,原理看代码注释,具体内容如下 public class mycalculator { public static void main(string[] args) { str ...

  8. java调c++代码_Java中调用C++代码的实现 | 学步园

    JNI为  Java Native Interface 即Java本地接口,使用此种方式可以对C/C++代码进行调用,其在本质上是对C/C++生成的动态库进行调用而不是直接对C/C++代码进行调用 J ...

  9. java 反射 代码_java反射机制学习代码

    根据 http://www.iteye.com/topic/137944 文档进行学习 代码如下: package reflectTest; import java.lang.reflect.*; i ...

最新文章

  1. SSD数据可靠性问题分析
  2. [导入]几种流行的AJAX框架jQuery,Mootools,Dojo,Ext JS的对比
  3. 如何高效的阅读Hadoop源代码?Hadoop的源代码写的怎么样?
  4. mysql查看系统运行日志文件_mysql自身运行日志文件详解
  5. Dapr微服务应用开发系列5:发布订阅构建块
  6. 在.NET Core中设计自己的服务宿主(Service Hosting)框架
  7. ODP 使用 ArrayBind 时可能会遇到的巨坑 'System.IConvertible' 的解决方法
  8. css3中的变形(transform)、过渡(transtion)、动画(animation)
  9. eclipse上的.properties文件中文编辑显示问题
  10. 基于JAVA+SpringMVC+Mybatis+MYSQL的网上商城系统
  11. 移动机器人速度空间对比分析
  12. 关联规则挖掘算法_关联规则的挖掘与应用——Apriori和CBA算法
  13. 2018-2019-1 20165319 《信息安全系统设计基础》第八周学习总结
  14. FireFox下竟然对HTML注释与IE下有不同的解析
  15. ZendStudio 安装
  16. 【转】performSelector延时调用导致的内存泄露
  17. python设置word背景色_python 绘图的背景颜色不要_项目分享|5步教你用Python制作朋友圈个性签名...
  18. MYSQL的开题报告题目,开题报告的选题意义.docx
  19. Docker学习(六):docker compose容器编排
  20. android 百度地图获取两个坐标的实际路线距离

热门文章

  1. 【内核隔离开启内存完整性已关闭不兼容的驱动程序驱动程序卸载】
  2. Android 内核加载fw通用方法分析
  3. 记录一次Extmail 邮件服务器崩盘事件
  4. 计算机如何安装cpu风扇,CPU风扇安装过程图解
  5. Ubuntu学习 wc
  6. 纯CSS实现Table固定表头和首列
  7. 建立一个带头结点的线性链表,用以存放输入的二进制数,链表的每一个节点的data域存放一个二进制位。并在此链表上实现对二进制数加1的运算;
  8. 测试新版Android Studio的手机镜像效果
  9. stc15w系列单片机——TCRT5000(寻迹传感器)与光敏传感器(附代码)
  10. 初识神经网络——损失函数