TF-IDF理解及其Java实现代码实例

TF-IDF

前言

前段时间,又具体看了自己以前整理的TF-IDF,这里把它发布在博客上,知识就是需要不断的重复的,否则就感觉生疏了。

TF-IDF理解

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

TF公式:

以上式子中是该词在文件中的出现次数,而分母则是在文件中所有字词的出现次数之和。

IDF公式:

|D|:语料库中的文件总数

:包含词语 ti 的文件数目(即 ni,j不等于0的文件数目)如果该词语不在语料库中,就会导致被除数为零,因此一般情况下使用

然后

TF-IDF实现(Java)

这里采用了外部插件IKAnalyzer-2012.jar,用其进行分词

具体代码如下:

package tfidf;
import java.io.*;
import java.util.*;
import org.wltea.analyzer.lucene.IKAnalyzer;
public class ReadFiles {
	/**
   * @param args
   */
	private static ArrayList<String> FileList = new ArrayList<String>();
	// the list of file
	//get list of file for the directory, including sub-directory of it
	public static List<String> readDirs(String filepath) throws FileNotFoundException, IOException
	  {
		try
		    {
			File file = new File(filepath);
			if(!file.isDirectory())
			      {
				System.out.println("输入的[]");
				System.out.println("filepath:" + file.getAbsolutePath());
			} else
			      {
				String[] flist = file.list();
				for (int i = 0; i < flist.length; i++)
				        {
					File newfile = new File(filepath + "\\" + flist[i]);
					if(!newfile.isDirectory())
					          {
						FileList.add(newfile.getAbsolutePath());
					} else if(newfile.isDirectory()) //if file is a directory, call ReadDirs
					{
						readDirs(filepath + "\\" + flist[i]);
					}
				}
			}
		}
		catch(FileNotFoundException e)
		    {
			System.out.println(e.getMessage());
		}
		return FileList;
	}
	//read file
	public static String readFile(String file) throws FileNotFoundException, IOException
	  {
		StringBuffer strSb = new StringBuffer();
		//String is constant, StringBuffer can be changed.
		InputStreamReader inStrR = new InputStreamReader(new FileInputStream(file), "gbk");
		//byte streams to character streams
		BufferedReader br = new BufferedReader(inStrR);
		String line = br.readLine();
		while(line != null){
			strSb.append(line).append("\r\n");
			line = br.readLine();
		}
		return strSb.toString();
	}
	//word segmentation
	public static ArrayList<String> cutWords(String file) throws IOException{
		ArrayList<String> words = new ArrayList<String>();
		String text = ReadFiles.readFile(file);
		IKAnalyzer analyzer = new IKAnalyzer();
		words = analyzer.split(text);
		return words;
	}
	//term frequency in a file, times for each word
	public static HashMap<String, Integer> normalTF(ArrayList<String> cutwords){
		HashMap<String, Integer> resTF = new HashMap<String, Integer>();
		for (String word : cutwords){
			if(resTF.get(word) == null){
				resTF.put(word, 1);
				System.out.println(word);
			} else{
				resTF.put(word, resTF.get(word) + 1);
				System.out.println(word.toString());
			}
		}
		return resTF;
	}
	//term frequency in a file, frequency of each word
	public static HashMap<String, float> tf(ArrayList<String> cutwords){
		HashMap<String, float> resTF = new HashMap<String, float>();
		int wordLen = cutwords.size();
		HashMap<String, Integer> intTF = ReadFiles.normalTF(cutwords);
		Iterator iter = intTF.entrySet().iterator();
		//iterator for that get from TF
		while(iter.hasNext()){
			Map.Entry entry = (Map.Entry)iter.next();
			resTF.put(entry.getKey().toString(), float.parsefloat(entry.getValue().toString()) / wordLen);
			System.out.println(entry.getKey().toString() + " = "+ float.parsefloat(entry.getValue().toString()) / wordLen);
		}
		return resTF;
	}
	//tf times for file
	public static HashMap<String, HashMap<String, Integer>> normalTFAllFiles(String dirc) throws IOException{
		HashMap<String, HashMap<String, Integer>> allNormalTF = new HashMap<String, HashMap<String,Integer>>();
		List<String> filelist = ReadFiles.readDirs(dirc);
		for (String file : filelist){
			HashMap<String, Integer> dict = new HashMap<String, Integer>();
			ArrayList<String> cutwords = ReadFiles.cutWords(file);
			//get cut word for one file
			dict = ReadFiles.normalTF(cutwords);
			allNormalTF.put(file, dict);
		}
		return allNormalTF;
	}
	//tf for all file
	public static HashMap<String,HashMap<String, float>> tfAllFiles(String dirc) throws IOException{
		HashMap<String, HashMap<String, float>> allTF = new HashMap<String, HashMap<String, float>>();
		List<String> filelist = ReadFiles.readDirs(dirc);
		for (String file : filelist){
			HashMap<String, float> dict = new HashMap<String, float>();
			ArrayList<String> cutwords = ReadFiles.cutWords(file);
			//get cut words for one file
			dict = ReadFiles.tf(cutwords);
			allTF.put(file, dict);
		}
		return allTF;
	}
	public static HashMap<String, float> idf(HashMap<String,HashMap<String, float>> all_tf){
		HashMap<String, float> resIdf = new HashMap<String, float>();
		HashMap<String, Integer> dict = new HashMap<String, Integer>();
		int docNum = FileList.size();
		for (int i = 0; i < docNum; i++){
			HashMap<String, float> temp = all_tf.get(FileList.get(i));
			Iterator iter = temp.entrySet().iterator();
			while(iter.hasNext()){
				Map.Entry entry = (Map.Entry)iter.next();
				String word = entry.getKey().toString();
				if(dict.get(word) == null){
					dict.put(word, 1);
				} else {
					dict.put(word, dict.get(word) + 1);
				}
			}
		}
		System.out.println("IDF for every word is:");
		Iterator iter_dict = dict.entrySet().iterator();
		while(iter_dict.hasNext()){
			Map.Entry entry = (Map.Entry)iter_dict.next();
			float value = (float)Math.log(docNum / float.parsefloat(entry.getValue().toString()));
			resIdf.put(entry.getKey().toString(), value);
			System.out.println(entry.getKey().toString() + " = " + value);
		}
		return resIdf;
	}
	public static void tf_idf(HashMap<String,HashMap<String, float>> all_tf,HashMap<String, float> idfs){
		HashMap<String, HashMap<String, float>> resTfIdf = new HashMap<String, HashMap<String, float>>();
		int docNum = FileList.size();
		for (int i = 0; i < docNum; i++){
			String filepath = FileList.get(i);
			HashMap<String, float> tfidf = new HashMap<String, float>();
			HashMap<String, float> temp = all_tf.get(filepath);
			Iterator iter = temp.entrySet().iterator();
			while(iter.hasNext()){
				Map.Entry entry = (Map.Entry)iter.next();
				String word = entry.getKey().toString();
				float value = (float)float.parsefloat(entry.getValue().toString()) * idfs.get(word);
				tfidf.put(word, value);
			}
			resTfIdf.put(filepath, tfidf);
		}
		System.out.println("TF-IDF for Every file is :");
		DisTfIdf(resTfIdf);
	}
	public static void DisTfIdf(HashMap<String, HashMap<String, float>> tfidf){
		Iterator iter1 = tfidf.entrySet().iterator();
		while(iter1.hasNext()){
			Map.Entry entrys = (Map.Entry)iter1.next();
			System.out.println("FileName: " + entrys.getKey().toString());
			System.out.print("{");
			HashMap<String, float> temp = (HashMap<String, float>) entrys.getValue();
			Iterator iter2 = temp.entrySet().iterator();
			while(iter2.hasNext()){
				Map.Entry entry = (Map.Entry)iter2.next();
				System.out.print(entry.getKey().toString() + " = " + entry.getValue().toString() + ", ");
			}
			System.out.println("}");
		}
	}
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		String file = "D:/testfiles";
		HashMap<String,HashMap<String, float>> all_tf = tfAllFiles(file);
		System.out.println();
		HashMap<String, float> idfs = idf(all_tf);
		System.out.println();
		tf_idf(all_tf, idfs);
	}
}

结果如下图:

常见问题

没有加入lucene jar包

lucene包和je包版本不适合

总结

以上就是本文关于TF-IDF理解及其Java实现代码实例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:

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

Java算法之堆排序代码示例

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

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

(0)

相关推荐

  • TF-IDF与余弦相似性的应用(一) 自动提取关键词

    TF-IDF与余弦相似性的应用(一):自动提取关键词 这个标题看上去好像很复杂,其实我要谈的是一个很简单的问题. 有一篇很长的文章,我要用计算机提取它的关键词(Automatic Keyphrase extraction),完全不加以人工干预,请问怎样才能正确做到? 这个问题涉及到数据挖掘.文本处理.信息检索等很多计算机前沿领域,但是出乎意料的是,有一个非常简单的经典算法,可以给出令人相当满意的结果.它简单到都不需要高等数学,普通人只用10分钟就可以理解,这就是我今天想要介绍的TF-IDF算法.

  • Java实现TFIDF算法代码分享

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

  • TF-IDF算法解析与Python实现方法详解

    TF-IDF(term frequency–inverse document frequency)是一种用于信息检索(information retrieval)与文本挖掘(text mining)的常用加权技术.比较容易理解的一个应用场景是当我们手头有一些文章时,我们希望计算机能够自动地进行关键词提取.而TF-IDF就是可以帮我们完成这项任务的一种统计方法.它能够用于评估一个词语对于一个文集或一个语料库中的其中一份文档的重要程度. 在一份给定的文件里,词频 (term frequency, T

  • TF-IDF理解及其Java实现代码实例

    TF-IDF 前言 前段时间,又具体看了自己以前整理的TF-IDF,这里把它发布在博客上,知识就是需要不断的重复的,否则就感觉生疏了. TF-IDF理解 TF-IDF(term frequency–inverse document frequency)是一种用于资讯检索与资讯探勘的常用加权技术, TFIDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类.TFIDF实际上是:TF * IDF,TF词频(T

  • java文件下载代码实例(单文件下载和多文件打包下载)

    这篇文章主要介绍了java文件下载代码实例(单文件下载和多文件打包下载),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 最近项目有需要写文件下载相关代码,这边提交记录下相关代码模块,写的不太好,后期再优化相关代码,有好的建议,可留言,谢谢. 1)单文件下载 public String oneFileDownload(HttpServletRequest request,HttpServletResponse response){ //针对需求需

  • 史上最通俗理解的Java死锁代码演示

    死锁的概念 知识储备 对象锁:Java一切皆对象,每个类都有一个class文件.由class文件可以new出对象,我们简单认识 下java对象,对象有个对象头信息,也就是这个对象概述,其中一条信息就是对象锁,也就是我们当前对象有没有被锁定,被哪个引用锁定. synchronized:synchronized是java关键词,如果运用到方法上代表我们锁的是这个方法,如果我们锁的代码块,代表再这个代码块内我们持有这个锁,Java Effective也是提倡减小锁的范围.我们进入同步代码块会加锁,执行

  • Kafka Java Producer代码实例详解

    根据业务需要可以使用Kafka提供的Java Producer API进行产生数据,并将产生的数据发送到Kafka对应Topic的对应分区中,入口类为:Producer Kafka的Producer API主要提供下列三个方法: public void send(KeyedMessage<K,V> message) 发送单条数据到Kafka集群 public void send(List<KeyedMessage<K,V>> messages) 发送多条数据(数据集)到

  • Java编程用栈来求解汉诺塔问题的代码实例(非递归)

    [题目] 汉诺塔问题比较经典,这里修改一下游戏规则:现在限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间.求当塔有N层的时候,打印最优移动过程和最优移动总步数. [解答] 上一篇用的是递归的方法解决这个问题,这里我们用栈来模拟汉诺塔的三个塔,也就是不用递归的方法 原理是这样的:修改后的汉诺塔问题不能让任何塔从左直接移动到右,也不能从右直接移动到左,而是要经过中间,也就是说,实际上能做的动作,只有四个:左->中,中->左,中->右,右->中 用栈

  • Java背包问题求解实例代码

    背包问题主要是指一个给定容量的背包.若干具有一定价值和重量的物品,如何选择物品放入背包使物品的价值最大.其中又分01背包和无限背包,这里主要讨论01背包,即每个物品最多放一个.而无限背包可以转化为01背包. 先说一下算法的主要思想,利用动态规划来解决.每次遍历到的第i个物品,根据w[i]和v[i]来确定是否需要将该物品放入背包中.即对于给定的n个物品,设v[i].w[i]分别为第i个物品的价值和重量,C为背包的容量.再令v[i][j]表示在前i个物品中能够装入容量为j的背包中的最大价值.则我们有

  • Java反射机制实例代码分享

    本文旨在对Java反射机制有一个全面的介绍,希望通过本文,大家会对Java反射的相关内容有一个全面的了解. 阅读本文之前,大家可先行参阅<重新理解Java泛型>. 前言 Java反射机制是一个非常强大的功能,在很多大型项目比如Spring, Mybatis都可以看见反射的身影.通过反射机制我们可以在运行期间获取对象的类型信息,利用这一特性我们可以实现工厂模式和代理模式等设计模式,同时也可以解决Java泛型擦除等令人苦恼的问题.本文我们就从实际应用的角度出发,来应用一下Java的反射机制. 反射

  • Java编程实现从尾到头打印链表代码实例

    问题描述:输入一个链表的头结点,从尾巴到头反过来打印出每个结点的值. 首先定义链表结点 public class ListNode { int val; ListNode next = null; ListNode(int val){ this.val = val; } } 思路1:此题明显想到是利用栈的思想,后进先出,先遍历链表,依次将结点值进栈.最后在遍历栈出栈. public static Stack<Integer> printListReverse_Stack(ListNode li

  • Java探索之Thread+IO文件的加密解密代码实例

    这篇文章向大家分享了几段代码,主要是关于Thread+IO文件的加密解密,下面看看具体代码: 加密启动线程 package com.hz.subsection; import java.io.File; public class enCodeFileThread extends Thread { public Files files; public File file; public File dst; public enCodeFileThread(String name,Files file

  • Java编程小实例—数字时钟的实现代码示例

    本文的实例是Java编程实现一个数字时钟,代码测试可用,练练手吧.代码如下: package me.socketthread; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Calendar; import java.util.GregorianCalenda

随机推荐