您现在的位置是:亿华云 > 系统运维
Hanlp分词实例:Java实现TFIDF算法
亿华云2025-10-05 04:40:15【系统运维】6人已围观
简介算法介绍 最近要做领域概念的提取,
算法介绍
最近要做领域概念的词实提取, TFIDF 作为一个很经典的实算法算法可以作为其中的一步处理。
关于 TFIDF 算法的词实介绍可以参考这篇博客 http://www.ruanyifeng.com/blog/2013/03/tf-idf.html 。
计算公式比较简单,实算法如下:
预处理
由于需要处理的候选词大约后 3w+ ,并且语料文档数有 1w+ ,实算法直接挨个文本遍历的词实话很耗时,每个词处理时间都要一分钟以上。实算法
为了缩短时间,词实首先进行分词,实算法一个词输出为一行方便统计,云服务器词实分词工具选择的实算法是 HanLp 。
然后,词实将一个领域的实算法文档合并到一个文件中,并用 “$$$” 标识符分割,词实方便记录文档数。
下面是选择的领域语料( PATH 目录下):
代码实现
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));
}
}
运行结果
测试词为 “ 离退休人员 ” ,中间结果如下:
最终结果:
结论
可以看到 “ 离退休人员 ” 在养老保险和社保领域, tfidf 值比较高,可以作为判断是否为领域概念的一个依据。当然 TF-IDF 算法虽然很经典,但还是有许多不足,不能单独依赖其结果做出判断。很多论文提出了改进方法,本文只是实现了最基本的算法。如果有其他思路和想法欢迎讨论。香港云服务器
很赞哦!(6784)
上一篇: 第五步:重复第四步,直到找到正确的纪录。
下一篇: CNAME:对应解析的记录值为域名地址
相关文章
- 3、不明先知,根据相关征兆预测可能发生的事件,以便提前做好准备,赶紧注册相关域名。;不差钱域名;buchaqian抢先注册,就是这种敏感类型。预言是最敏感的状态。其次,你应该有眼力。所谓眼力,就是善于从社会上时不时出现的各种热点事件中获取与事件相关的域名资源。眼力的前提是对域名领域的熟悉和丰富的知识。
- Java多线程编程 — 锁优化
- Python轻松查看微信撤回消息,秘密无处可藏
- 精讲Spring Boot—— 入门+进阶+实例
- a、变更前的公司证件扫描件(代码证或者营业执照)及联系人身份证复印件、变更后的公司证件扫描件(代码证或者营业执照)及新的联系人身份证复印件;身份证复印件需本人签名,公司证件复印件需加盖公章。
- 用于Web开发的TOP5机器学习框架盘点
- 网络 | 如何设计一个亿级API网关?
- 分析JavaScript的数据类型与变量
- 小白注册网站域名该怎么办?有什么步骤?
- 写给 PHP 程序员的信号处理教程