一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - JAVA教程 - Java實現TFIDF算法代碼分享

Java實現TFIDF算法代碼分享

2021-02-05 11:33沒課割綠地 JAVA教程

這篇文章主要介紹了Java實現TFIDF算法代碼分享,對算法進行了簡單介紹,概念,原理,以及實現代碼的分享,具有一定參考價值,需要的朋友可以了解下。

算法介紹

概念

     tf-idf(term frequency–inverse 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作為一個很經典的算法可以作為其中的一步處理。

計算公式比較簡單,如下:

Java實現TFIDF算法代碼分享

預處理

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

為了縮短時間,首先進行分詞,一個詞輸出為一行方便統計,分詞工具選擇的是hanlp。

然后,將一個領域的文檔合并到一個文件中,并用“$$$”標識符分割,方便記錄文檔數。

Java實現TFIDF算法代碼分享

下面是選擇的領域語料(path目錄下):

Java實現TFIDF算法代碼分享

代碼實現

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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));
    }
}

運行結果

測試詞為“離退休人員”,中間結果如下:

Java實現TFIDF算法代碼分享

最終結果:

Java實現TFIDF算法代碼分享

結論

可以看到“離退休人員”在養老保險和社保領域,tfidf值比較高,可以作為判斷是否為領域概念的一個依據。

當然tf-idf算法雖然很經典,但還是有許多不足,不能單獨依賴其結果做出判斷。

以上就是本文關于java實現tfidf算法代碼分享的全部內容,希望對大家有所幫助。如有不足之處,歡迎留言指出。

原文鏈接:http://www.cnblogs.com/justcooooode/p/7831157.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本肉体xxxx | 亚洲娇小videos | 精品视频中文字幕 | 91国内精品| 天作谜案免费完整版在线观看 | 91高清国产经典在线观看 | 55夜色66夜亚州精品站 | 亚洲精品无码不卡在线观看 | 色老板最新网站视频地址 | 日本在线www | 成人尤物| 95在线观看精品视频 | 操bb视频 | 亚洲风情无码免费视频 | 国色天香社区视频免费高清在线观看 | 插入影院| 成人国产精品一级毛片视频 | 超91在线 | 亚欧精品在线观看 | 亚洲精品久久麻豆蜜桃 | 国产日产国无高清码2020 | 欧美人妖另类性hd | 婷婷综合缴情亚洲五月伊 | 欧美日韩色图 | 国产成人精品第一区二区 | 天美视频在线 | 成人免费视频一区二区三区 | 羞羞答答免费人成黄页在线观看国产 | 久久水蜜桃亚洲AV无码精品偷窥 | 欧美性高清另类videosex死尸 | 天堂色 | a∨79成人网 | 岛国在线播放v片免费 | 韩国三级在线观看 完整版 韩国三级视频网站 | 9自拍视频在线观看 | 久久免费看少妇级毛片蜜臀 | 精品香蕉99久久久久网站 | 日本免费三片在线观看 | 我强进了老师身体在线观看 | 久久人妻无码毛片A片麻豆 久久热这里只有 精品 | 美艳教师刘艳第三部166 |