新普京娱乐平台Java实现TFIDF算法。Java实现TFIDF算法。

算法介绍

前不久设做领域概念的提,TFIDF作为一个十分经典的算法可以看成内部的相同步处理。

有关TFIDF算法的介绍好参见这篇博客http://www.ruanyifeng.com/blog/2013/03/tf-idf.html。

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

 新普京娱乐平台 1

算法介绍

多年来一经开领域概念的领到,TFIDF作为一个老经典的算法可以用作内部的如出一辙步处理。

关于TFIDF算法的介绍好参照这篇博客http://www.ruanyifeng.com/blog/2013/03/tf-idf.html。

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

 新普京娱乐平台 2

预处理

出于用处理的候选词大约后3w+,并且语料文档数有1w+,直接挨个文本遍历的语很耗时,每个词处理时还设同分钟以上。

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

然后,将一个世界的文档合并到一个文书中,并因此“$$$”标识符分割,方便记录文档数。

新普京娱乐平台 3

下面是选项的小圈子语料(PATH目录下):

新普京娱乐平台 4

预处理

由用处理的候选词大约后3w+,并且语料文档数有1w+,直接挨个文本遍历的口舌非常耗时,每个词处理时都要平等分钟以上。

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

接下来,将一个天地的文档合并及一个文件被,并就此“$$$”标识符分割,方便记录文档数。

新普京娱乐平台 5

下是挑的世界语料(PATH目录下):

新普京娱乐平台 6

代码实现

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<String, Integer> containsKeyMap = new HashMap<>();
        // 每个领域的总文档数
        Map<String, Integer> totalDocMap = new HashMap<>();
        // TF = 候选词出现次数/总词数
        Map<String, Double> 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<Map.Entry<String, Integer>> containsKeyset = containsKeyMap.entrySet();
            Set<Map.Entry<String, Integer>> totalDocset = totalDocMap.entrySet();
            Set<Map.Entry<String, Double>> tfSet = tfMap.entrySet();

            // 计算其他领域包含候选词文档数
            for (Map.Entry<String, Integer> entry : containsKeyset) {
                if (!entry.getKey().equals(f.getName())) {
                    otherContainsKeyDoc += entry.getValue();
                }
            }

            // 计算其他领域文档总数
            for (Map.Entry<String, Integer> entry : totalDocset) {
                if (!entry.getKey().equals(f.getName())) {
                    otherTotalDoc += entry.getValue();
                }
            }

            // 计算idf
            idf = log((float) otherTotalDoc / (otherContainsKeyDoc + 1), 2);

            // 计算tf*idf并输出
            for (Map.Entry<String, Double> 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));
    }
}            

代码实现

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<String, Integer> containsKeyMap = new HashMap<>();
        // 每个领域的总文档数
        Map<String, Integer> totalDocMap = new HashMap<>();
        // TF = 候选词出现次数/总词数
        Map<String, Double> 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<Map.Entry<String, Integer>> containsKeyset = containsKeyMap.entrySet();
            Set<Map.Entry<String, Integer>> totalDocset = totalDocMap.entrySet();
            Set<Map.Entry<String, Double>> tfSet = tfMap.entrySet();

            // 计算其他领域包含候选词文档数
            for (Map.Entry<String, Integer> entry : containsKeyset) {
                if (!entry.getKey().equals(f.getName())) {
                    otherContainsKeyDoc += entry.getValue();
                }
            }

            // 计算其他领域文档总数
            for (Map.Entry<String, Integer> entry : totalDocset) {
                if (!entry.getKey().equals(f.getName())) {
                    otherTotalDoc += entry.getValue();
                }
            }

            // 计算idf
            idf = log((float) otherTotalDoc / (otherContainsKeyDoc + 1), 2);

            // 计算tf*idf并输出
            for (Map.Entry<String, Double> 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));
    }
}            

运转结果 

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

新普京娱乐平台 7

 最终结果:

新普京娱乐平台 8

运作结果 

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

新普京娱乐平台 9

 最终结果:

新普京娱乐平台 10

结论

足见到“离退休人员”在养老保险和社保领域,tfidf值比较强,可以当作判断是否为世界概念的一个基于。

自TF-IDF算法虽然很经典,但还是出成百上千不足,不克独依赖其结果做出判断。

森论文提出了改良措施,本文只是实现了极基本的算法。

要出任何思路以及设法欢迎讨论。


转载请注明原文链接:http://www.cnblogs.com/justcooooode/p/7831157.html

结论

可看看“离退休人员”在养老保险和社保领域,tfidf值比较强,可以用作判断是否为世界概念的一个基于。

理所当然TF-IDF算法虽然充分经典,但还是产生很多欠缺,不克独依赖其结果做出判断。

多论文提出了改良方式,本文只是实现了最好中心的算法。

比方有另外思路与设法欢迎讨论。


转载请注明原文链接:http://www.cnblogs.com/justcooooode/p/7831157.html

Post Author: admin

发表评论

电子邮件地址不会被公开。 必填项已用*标注