最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實(shí)現(xiàn)TFIDF算法代碼分享

 更新時(shí)間:2017年11月15日 08:51:20   作者:沒(méi)課割綠地  
這篇文章主要介紹了Java實(shí)現(xiàn)TFIDF算法代碼分享,對(duì)算法進(jìn)行了簡(jiǎn)單介紹,概念,原理,以及實(shí)現(xiàn)代碼的分享,具有一定參考價(jià)值,需要的朋友可以了解下。

算法介紹

概念

     TF-IDF(term frequency–inverse document frequency)是一種用于資訊檢索與資訊探勘的常用加權(quán)技術(shù)。TF-IDF是一種統(tǒng)計(jì)方法,用以評(píng)估一字詞對(duì)于一個(gè)文件集或一個(gè)語(yǔ)料庫(kù)中的其中一份文件的重要程度。字詞的重要性隨著它在文件中出現(xiàn)的次數(shù)成正比增加,但同時(shí)會(huì)隨著它在語(yǔ)料庫(kù)中出現(xiàn)的頻率成反比下降。TF-IDF加權(quán)的各種形式常被搜尋引擎應(yīng)用,作為文件與用戶查詢之間相關(guān)程度的度量或評(píng)級(jí)。除了TF-IDF以外,因特網(wǎng)上的搜尋引擎還會(huì)使用基于連結(jié)分析的評(píng)級(jí)方法,以確定文件在搜尋結(jié)果中出現(xiàn)的順序。

原理

在一份給定的文件里,詞頻(termfrequency,TF)指的是某一個(gè)給定的詞語(yǔ)在該文件中出現(xiàn)的次數(shù)。這個(gè)數(shù)字通常會(huì)被歸一化(分子一般小于分母區(qū)別于IDF),以防止它偏向長(zhǎng)的文件。(同一個(gè)詞語(yǔ)在長(zhǎng)文件里可能會(huì)比短文件有更高的詞頻,而不管該詞語(yǔ)重要與否。)

逆向文件頻率(inversedocumentfrequency,IDF)是一個(gè)詞語(yǔ)普遍重要性的度量。某一特定詞語(yǔ)的IDF,可以由總文件數(shù)目除以包含該詞語(yǔ)之文件的數(shù)目,再將得到的商取對(duì)數(shù)得到。

某一特定文件內(nèi)的高詞語(yǔ)頻率,以及該詞語(yǔ)在整個(gè)文件集合中的低文件頻率,可以產(chǎn)生出高權(quán)重的TF-IDF。因此,TF-IDF傾向于過(guò)濾掉常見(jiàn)的詞語(yǔ),保留重要的詞語(yǔ)。

TFIDF的主要思想是:如果某個(gè)詞或短語(yǔ)在一篇文章中出現(xiàn)的頻率TF高,并且在其他文章中很少出現(xiàn),則認(rèn)為此詞或者短語(yǔ)具有很好的類別區(qū)分能力,適合用來(lái)分類。TFIDF實(shí)際上是:TF*IDF,TF詞頻(TermFrequency),IDF反文檔頻率(InverseDocumentFrequency)。TF表示詞條在文檔d中出現(xiàn)的頻率(另一說(shuō):TF詞頻(TermFrequency)指的是某一個(gè)給定的詞語(yǔ)在該文件中出現(xiàn)的次數(shù))。IDF的主要思想是:如果包含詞條t的文檔越少,也就是n越小,IDF越大,則說(shuō)明詞條t具有很好的類別區(qū)分能力。如果某一類文檔C中包含詞條t的文檔數(shù)為m,而其它類包含t的文檔總數(shù)為k,顯然所有包含t的文檔數(shù)n=m+k,當(dāng)m大的時(shí)候,n也大,按照IDF公式得到的IDF的值會(huì)小,就說(shuō)明該詞條t類別區(qū)分能力不強(qiáng)。(另一說(shuō):IDF反文檔頻率(InverseDocumentFrequency)是指果包含詞條的文檔越少,IDF越大,則說(shuō)明詞條具有很好的類別區(qū)分能力。)但是實(shí)際上,如果一個(gè)詞條在一個(gè)類的文檔中頻繁出現(xiàn),則說(shuō)明該詞條能夠很好代表這個(gè)類的文本的特征,這樣的詞條應(yīng)該給它們賦予較高的權(quán)重,并選來(lái)作為該類文本的特征詞以區(qū)別與其它類文檔。這就是IDF的不足之處.

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

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

預(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ù)。

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

代碼實(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é)果如下:

最終結(jié)果:

結(jié)論

可以看到“離退休人員”在養(yǎng)老保險(xiǎn)和社保領(lǐng)域,tfidf值比較高,可以作為判斷是否為領(lǐng)域概念的一個(gè)依據(jù)。

當(dāng)然TF-IDF算法雖然很經(jīng)典,但還是有許多不足,不能單獨(dú)依賴其結(jié)果做出判斷。

以上就是本文關(guān)于Java實(shí)現(xiàn)TFIDF算法代碼分享的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:

Java 蒙特卡洛算法求圓周率近似值實(shí)例詳解

java算法實(shí)現(xiàn)紅黑樹(shù)完整代碼示例

java實(shí)現(xiàn)的各種排序算法代碼示例

如有不足之處,歡迎留言指出。

相關(guān)文章

  • Java提示缺少返回語(yǔ)句的解決辦法

    Java提示缺少返回語(yǔ)句的解決辦法

    在本篇文章里小編給大家分享了關(guān)于Java提示缺少返回語(yǔ)句的解決辦法以及相關(guān)知識(shí)點(diǎn),需要的朋友們參考下。
    2019-07-07
  • 如何解決SpringBoot2.6及之后版本取消了循環(huán)依賴的支持問(wèn)題

    如何解決SpringBoot2.6及之后版本取消了循環(huán)依賴的支持問(wèn)題

    循環(huán)依賴指的是兩個(gè)或者多個(gè)bean之間相互依賴,形成一個(gè)閉環(huán),SpringBoot從2.6.0開(kāi)始默認(rèn)不允許出現(xiàn)Bean循環(huán)引用,解決方案包括在全局配置文件設(shè)置允許循環(huán)引用存在、在SpringApplicationBuilder添加設(shè)置允許循環(huán)引用、構(gòu)造器注入
    2024-10-10
  • MyBatis獲取插入記錄的自增長(zhǎng)字段值(ID)

    MyBatis獲取插入記錄的自增長(zhǎng)字段值(ID)

    本文分步驟給大家介紹了MyBatis獲取插入記錄的自增長(zhǎng)字段值的方法,在文中給大家提到了mybatis返回插入數(shù)據(jù)的自增長(zhǎng)id,需要的朋友可以參考下
    2017-11-11
  • Java異步編程的5種異步實(shí)現(xiàn)方式詳解

    Java異步編程的5種異步實(shí)現(xiàn)方式詳解

    這篇文章主要介紹了Java異步編程的5種異步實(shí)現(xiàn)方式詳解,異步編程是程序并發(fā)運(yùn)行的一種手段,它允許多個(gè)事件同時(shí)發(fā)生,當(dāng)程序調(diào)用需要長(zhǎng)時(shí)間運(yùn)行的方法時(shí),它不會(huì)阻塞當(dāng)前的執(zhí)行流程,程序可以繼續(xù)運(yùn)行,需要的朋友可以參考下
    2024-01-01
  • Java 讀寫(xiě)鎖源碼分析

    Java 讀寫(xiě)鎖源碼分析

    這篇文章主要介紹了Java 讀寫(xiě)鎖的相關(guān)資料,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2021-01-01
  • SpringBootWeb?入門(mén)了解?Swagger?的具體使用

    SpringBootWeb?入門(mén)了解?Swagger?的具體使用

    這篇文章主要介紹了SpringBootWeb?入門(mén)了解?Swagger?的具體使用,Swagger?框架可以根據(jù)已經(jīng)實(shí)現(xiàn)的方法或者類,通過(guò)頁(yè)面的方式直觀清晰的查看或者進(jìn)行測(cè)試該方法,需要的朋友可以參考下
    2024-08-08
  • FeignClient支持運(yùn)行時(shí)動(dòng)態(tài)指定URL方式

    FeignClient支持運(yùn)行時(shí)動(dòng)態(tài)指定URL方式

    在實(shí)際開(kāi)發(fā)中,我們經(jīng)常通過(guò)FeignClient接口調(diào)用三方API,當(dāng)面對(duì)不同的環(huán)境對(duì)應(yīng)不同的地址時(shí),可以通過(guò)配置文件和占位符來(lái)切換,但在同一個(gè)環(huán)境中需要調(diào)用不同地址的相同接口時(shí),這種方法就失效了,此時(shí),可以通過(guò)實(shí)現(xiàn)RequestInterceptor接口來(lái)動(dòng)態(tài)切換地址
    2024-11-11
  • SpringBoot底層注解詳解

    SpringBoot底層注解詳解

    這篇文章主要介紹了SpringBoot底層注解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-05-05
  • Java 必知必會(huì)的 URL 和 URLConnection使用

    Java 必知必會(huì)的 URL 和 URLConnection使用

    這篇文章主要介紹了Java 必知必會(huì)的 URL 和 URLConnection使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Spring Boot實(shí)戰(zhàn)之發(fā)送郵件示例代碼

    Spring Boot實(shí)戰(zhàn)之發(fā)送郵件示例代碼

    本篇文章主要介紹了Spring Boot實(shí)戰(zhàn)之發(fā)送郵件示例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下。
    2017-03-03

最新評(píng)論

电白县| 周口市| 瑞丽市| 余干县| 江华| 右玉县| 行唐县| 吉水县| 大田县| 平江县| 渝中区| 平罗县| 武定县| 高陵县| 府谷县| 赤水市| 瑞丽市| 洛宁县| 阿拉善右旗| 长阳| 梓潼县| 慈溪市| 娱乐| 普格县| 濉溪县| 龙井市| 宁强县| 延吉市| 西安市| 达拉特旗| 大荔县| 休宁县| 连平县| 隆尧县| 奉节县| 双辽市| 平乐县| 通河县| 灵石县| 荥阳市| 安宁市|