本文参考自: 原文地址

文章原地址:https://blog.csdn.net/lionel_fengj/article/details/53699903(侵权立删)

TF-IDF算法

TF-IDF(词频-逆文档频率)算法是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。该算法在数据挖掘、文本处理和信息检索等领域得到了广泛的应用,如从一篇文章中找到它的关键词。

TFIDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。TF-IDF实际上就是 TF*IDF,其中 TF(Term Frequency),表示词条在文章Document 中出现的频率;IDF(Inverse Document Frequency),其主要思想就是,如果包含某个词 Word的文档越少,则这个词的区分度就越大,也就是 IDF 越大。对于如何获取一篇文章的关键词,我们可以计算这边文章出现的所有名词的 TF-IDF,TF-IDF越大,则说明这个名词对这篇文章的区分度就越高,取 TF-IDF 值较大的几个词,就可以当做这篇文章的关键词。

计算步骤

  1. 计算词频(TF)

    词频=某个词在文章中的出现次数文章总次数词频=某个词在文章中的出现次数文章总次数

  2. 计算逆文档频率(IDF)

    逆文档频率=log语料库的文档总数包含该词的文档数+1逆文档频率=log⁡语料库的文档总数包含该词的文档数+1

  3. 计算词频-逆文档频率(TF-IDF) 
    词频−逆文档频率=词频∗逆文档频率词频−逆文档频率=词频∗逆文档频率

代码示例

为了建立自己的语料库,我从网上爬了100个 url 存放在本地的 txt 文件中, 
存放格式如下: 
 
这就相当于存放了100篇文章,即语料库的的文档总数是100。

  • TF-IDF 算法代码
package com.myapp.ml.nlp;import org.ansj.domain.Term;
import org.ansj.splitWord.analysis.ToAnalysis;
import org.ansj.util.FilterModifWord;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;/** * Created by lionel on 16/12/15. */
public class TFIDFAlgorithm {/** * 根据文件路径,文件中存放的100个网址的 url,获取 url 路径列表 * * @param path 本地文件路径 * @return 路径列表 */public List<String> readUrlFromText(String path) {if (StringUtils.isBlank(path)) {return null;}List<String> urls = new ArrayList<String>();try {BufferedReader reader = new BufferedReader(new FileReader(path));String line;while ((line = reader.readLine()) != null) {urls.add(line.trim());}} catch (IOException e) {e.printStackTrace();}return urls;}/** * 利用 Jsoup 工具,根据网址获取网页文本 * * @param url 网址 * @return 网页文本 */public String getTextFromUrl(String url) {if (StringUtils.isBlank(url)) {return null;}String text = "";try {Document document = Jsoup.connect(url).get();text = document.text();} catch (IOException e) {e.printStackTrace();}return text.replace(" ", "");}/** * 运用 ansj 给文本分词 * * @param text 文本内容 * @return 分词结果 */public List<Term> parse(String text) {if (StringUtils.isBlank(text)) {return null;}List<Term> terms = FilterModifWord.modifResult(ToAnalysis.parse(text));if (terms == null || terms.size() == 0) {return null;}return terms;}/** * 计算一篇文章分词后除去标点符号后词的总数 * * @param terms 分词后的集合 * @return 一篇文章分词后除去标点符号后词的总数 */private Integer countWord(List<Term> terms) {if (terms == null || terms.size() == 0) {return null;}for (int i = 0; i < terms.size(); i++) {if ("null".equals(terms.get(i).getNatureStr()) || terms.get(i).getNatureStr().startsWith("w")) {terms.remove(i);}}return terms.size();}/** * 计算词频 IF * * @param word 词 * @param terms 分词结果集合 * @return IF */public double computeTF(String word, List<Term> terms) {if (StringUtils.isBlank(word)) {return 0.0;}int count = 0;for (Term term : terms) {if (term.getName().equals(word)) {count += 1;}}return (double) count / countWord(terms);}/** * 统计词语的逆文档频率 IDF * * @param path 存放 url 的文件路径 * @param word IDF */public double computeIDF(String path, String word) {if (StringUtils.isBlank(path) || StringUtils.isBlank(word)) {return 0.0;}List<String> urls = readUrlFromText(path);int count = 1;for (String url : urls) {String text = getTextFromUrl(url);if (text.contains(word)) {count += 1;}}return Math.log10((double) urls.size() / count);}/** * 计算词频-逆文档频率 TF—IDF * * @param filePath 存放url的文件路径 * @param terms 分词结果集合 * @param word 词 * @return TF—IDF */public Double computeTFIDF(String filePath, List<Term> terms, String word) {return computeTF(word, terms) * computeIDF(filePath, word);}
}
  • 测试代码
package com.myapp.ml.nlp;import org.ansj.domain.Term;
import org.junit.Test;import java.util.List;/** *测试词语“语言”的 TF-IDF * Created by lionel on 16/12/15. */
public class TFIDFAlgorithmTest {@Testpublic void test() {TFIDFAlgorithm tfidfAlgorithm = new TFIDFAlgorithm();String filePath = "/Users/lionel/PycharmProjects/python-app/com/pythonapp/spider/output.txt";String url = "http://baike.baidu.com/item/Java/85979";String word = "语言";List<Term> terms = tfidfAlgorithm.parse(tfidfAlgorithm.getTextFromUrl(url));System.out.println("[【" + word + "】词频 ] " + tfidfAlgorithm.computeTF(word, terms));System.out.println("[【" + word + "】逆文档频率 ] " + tfidfAlgorithm.computeIDF(filePath, word));System.out.println("[【" + word + "】词频-逆文档频率 ] "+tfidfAlgorithm.computeTFIDF(filePath,terms,word));}
}
  • 测试结果 

本篇博客描述的是我对 TF-IDF 算法的理解,代码是对算法过程简单的实现,若有失偏颇,还请指出。

TF-IDF算法java实现【转载】相关推荐

  1. 关键词提取算法—TF/IDF算法

    关键词提取算法一般可分为有监督学习和无监督学习两类. 有监督的关键词提取方法可以通过分类的方式进行,通过构建一个较为完善的词表,然后判断每个文档与词表中的每个词的匹配程度,以类似打标签的方式,达到关键 ...

  2. 随笔_从《芳华》影评到TF/IDF算法

     前两天看好多<芳华>的影评说:为什么好人没好报?于是感叹一堆世态炎凉,人性丑陋什么的.我觉得这问题是:为什么中央空调(对谁都温暖)往往不被看好.  先说说TF/IDF算法,这是一种信息处 ...

  3. 搜索引擎:文本分类——TF/IDF算法

    原理 TFIDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类.TFIDF实际上是:TF * IDF,TF ...

  4. bm25算法Java代码_BM25算法在Lucene中的应用

    Lucene是apache软件基金会jakarta项目组的一个子项目,是一个用Java写的全文检索引擎工具包,可以方便的集成到系统中提以提供高效的检索能力,Lucene核心功能分为建索和检索两部分.而 ...

  5. tfidf算法 python_tf–idf算法解释及其python代码实现(下)

    tf–idf算法python代码实现 这是我写的一个tf-idf的简单实现的代码,我们知道tfidf=tf*idf,所以可以分别计算tf和idf值在相乘,首先我们创建一个简单的语料库,作为例子,只有四 ...

  6. 文本聚类算法Java实现

    蛙蛙推荐:蛙蛙教你文本聚类 摘要:文本聚类是搜索引擎和语义web的基本技术,这次本蛙和大家一起学习一下简单的文本聚类算法,可能不能直接用于实际应用中,但对于想学搜索技术的初学者还是有一定入门作用的.这 ...

  7. tf-idf词向量和bow_使用词袋Bow和TF IDF进行多标签分类

    tf-idf词向量和bow 1.加载数据 (1. Load the data) For this study, we are using Kaggle data for Toxic Comment C ...

  8. 推特雪花算法 java实现

    2019独角兽企业重金招聘Python工程师标准>>> package twiter.snowflake;/*** twitter的snowflake算法 -- java实现*/ p ...

  9. 快速排序算法 java 实现

    快速排序算法 java 实现 快速排序算法Java实现 白话经典算法系列之六 快速排序 快速搞定 各种排序算法的分析及java实现 算法概念 快速排序是C.R.A.Hoare于1962年提出的一种划分 ...

  10. tf/idf_Neo4j:带密码的TF / IDF(和变体)

    tf/idf 几周前,我写了一篇博客文章,介绍了如何使用scikit-learn在HIMYM成绩单上运行TF / IDF,以按情节找到最重要的短语,然后我很好奇在Neo4j中很难做到. 我首先将Wik ...

最新文章

  1. C语言数据结构(大话数据结构——笔记3)第五章:串(字符串)
  2. Linux shell关系运算
  3. Nginx 配置 SSL 证书步骤小记
  4. 怎么获取web开发怎么获取手机的唯一标识_PYTHON实现北京住宅小区数据抓取-(Web服务API-地点检索服务)
  5. 语音识别结合应用场景 各位大咖也有一些精彩论点
  6. E-BERT: 电商领域语言模型优化实践
  7. 在C#中如何读取枚举值的描述属性
  8. scala连接mongodb_MongoDB 的用户配置与基于Scala的使用
  9. 有没有可以干一辈子的工作?
  10. excel表格横向纵向变换_Excel操作技巧:简单3步,搞定数据统计和分析!
  11. 《TPM原理及应用指南》深入研读 —— TPM介绍
  12. Kubernets 污点与容忍
  13. 【Java工程中出现问题】XXX has been compiled by a more recent version of the Java Runtime
  14. 机械臂matlab运动学仿真,matlab建立机械臂运动学仿真
  15. 清除composite里的子控件
  16. 矩阵与坐标系的映射关系
  17. oracle 并行查询
  18. 智能家居产品的信息安全认证与法律合规之路
  19. t420i升级固态硬盘提升_小体积、大性能、台式机笔记本升级可选,酷兽M.2 SSD固态硬盘测评...
  20. Python+OpenCV图像处理(五)——图像阈值和二值化

热门文章

  1. Python多项逻辑回归用LogisticRegression识别英文字母数据集letter-recognition.data
  2. python如何提问并回答_如何提问 - nashviller - 博客园
  3. contextual Attention
  4. php fpm ondemand,AMH中PHP运行模式设置php-fpm为ondemand模式
  5. zynq-7000系列基于zynq-zed的vivado初步设计之linux下控制PL扩展的UART
  6. SAP ABAP 输出设备设置 LP01
  7. [NLP]OpenNLP介绍
  8. 阿里面试题:设计相关的系统对外提供商品实时价格获取功能
  9. 鬼使神差的给宝宝办了大米的卡
  10. Linux驱动之设备树(设备树下的LED驱动实验)