Java中怎么實(shí)現(xiàn)一個(gè)TFIDF算法

這篇文章給大家介紹Java中怎么實(shí)現(xiàn)一個(gè)TFIDF算法,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

創(chuàng)新互聯(lián)建站專注于企業(yè)成都全網(wǎng)營(yíng)銷推廣、網(wǎng)站重做改版、江蘇網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5開發(fā)、成都做商城網(wǎng)站、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為江蘇等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

算法介紹

最近要做領(lǐng)域概念的提取,TFIDF作為一個(gè)很經(jīng)典的算法可以作為其中的一步處理。

計(jì)算公式比較簡(jiǎn)單,如下:

Java中怎么實(shí)現(xiàn)一個(gè)TFIDF算法

預(yù)處理

由于需要處理的候選詞大約后3w+,并且語(yǔ)料文檔數(shù)有1w+,直接挨個(gè)文本遍歷的話很耗時(shí),每個(gè)詞處理時(shí)間都要一分鐘以上。

為了縮短時(shí)間,首先進(jìn)行分詞,一個(gè)詞輸出為一行方便統(tǒng)計(jì),分詞工具選擇的是HanLp。

然后,將一個(gè)領(lǐng)域的文檔合并到一個(gè)文件中,并用“$$$”標(biāo)識(shí)符分割,方便記錄文檔數(shù)。

Java中怎么實(shí)現(xiàn)一個(gè)TFIDF算法

下面是選擇的領(lǐng)域語(yǔ)料(PATH目錄下):

Java中怎么實(shí)現(xiàn)一個(gè)TFIDF算法

代碼實(shí)現(xiàn)

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"; // 語(yǔ)料庫(kù)路徑

    public static void main(String[] args) throws Exception {

        String test = "離退休人員"; // 要計(jì)算的候選詞

        computeTFIDF(PATH, test);

    }

    /**

    * @param @param path 語(yǔ)料路經(jīng)

    * @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();

        // 每個(gè)領(lǐng)域出現(xiàn)候選詞的文檔數(shù)

        Map<String, Integer> containsKeyMap = new HashMap<>();

        // 每個(gè)領(lǐng)域的總文檔數(shù)

        Map<String, Integer> totalDocMap = new HashMap<>();

        // TF = 候選詞出現(xiàn)次數(shù)/總詞數(shù)

        Map<String, Double> tfMap = new HashMap<>();

        // scan files

        for (File f : files) {

            // 候選詞詞頻

            double termFrequency = 0;

            // 文本總詞數(shù)

            double totalTerm = 0;

            // 包含候選詞的文檔數(shù)

            int containsKeyDoc = 0;

            // 詞頻文檔計(jì)數(shù)

            int totalCount = 0;

            int fileCount = 0;

            // 標(biāo)記文件中是否出現(xiàn)候選詞

            boolean flag = false;

            FileReader fr = new FileReader(f);

            BufferedReader br = new BufferedReader(fr);

            String s = "";

            // 計(jì)算詞頻和總詞數(shù)

            while ((s = br.readLine()) != null) {

                if (s.equals(word)) {

                    termFrequency++;

                    flag = true;

                }

                // 文件標(biāo)識(shí)符

                if (s.equals("$$$")) {

                    if (flag) {

                        containsKeyDoc++;

                    }

                    fileCount++;

                    flag = false;

                }

                totalCount++;

            }

            // 減去文件標(biāo)識(shí)符的數(shù)量得到總詞數(shù)

            totalTerm += totalCount - fileCount;

            br.close();

            // key都為領(lǐng)域的名字

            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("該領(lǐng)域文檔數(shù):" + fileCount);

            System.out.println("候選詞出現(xiàn)詞數(shù):" + termFrequency);

            System.out.println("總詞數(shù):" + totalTerm);

            System.out.println("出現(xiàn)候選詞文檔總數(shù):" + containsKeyDoc);

            System.out.println();

        }

        //計(jì)算TF*IDF

        for (File f : files) {

            // 其他領(lǐng)域包含候選詞文檔數(shù)

            int otherContainsKeyDoc = 0;

            // 其他領(lǐng)域文檔總數(shù)

            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();

            // 計(jì)算其他領(lǐng)域包含候選詞文檔數(shù)

            for (Map.Entry<String, Integer> entry : containsKeyset) {

                if (!entry.getKey().equals(f.getName())) {

                    otherContainsKeyDoc += entry.getValue();

                }

            }

            // 計(jì)算其他領(lǐng)域文檔總數(shù)

            for (Map.Entry<String, Integer> entry : totalDocset) {

                if (!entry.getKey().equals(f.getName())) {

                    otherTotalDoc += entry.getValue();

                }

            }

            // 計(jì)算idf

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

            // 計(jì)算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));

    }

}

運(yùn)行結(jié)果

測(cè)試詞為“離退休人員”,中間結(jié)果如下:

Java中怎么實(shí)現(xiàn)一個(gè)TFIDF算法

最終結(jié)果:

Java中怎么實(shí)現(xiàn)一個(gè)TFIDF算法

關(guān)于Java中怎么實(shí)現(xiàn)一個(gè)TFIDF算法就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

本文標(biāo)題:Java中怎么實(shí)現(xiàn)一個(gè)TFIDF算法
分享鏈接:http://bm7419.com/article46/gigheg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗(yàn)標(biāo)簽優(yōu)化、品牌網(wǎng)站制作品牌網(wǎng)站建設(shè)、企業(yè)建站網(wǎng)頁(yè)設(shè)計(jì)公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

小程序開發(fā)