实现之前,我们要事先说明一些问题:

我们用Redis对数据进行持久化,存两种形式的MAP:

key值为term,value值为含有该term的url
key值为url,value值为map,记录term及在文章中出现的次数
总的计算公式如下:

1.计算词频TF
这里通过给出url地址,获取搜索词term在此url中的数量,计算出TF

获取url中的词汇总数

/**
* @Author Ragty
* @Description 获取url中的词汇总数
* @Date 11:18 2019/6/4
**/
public Integer getWordCount(String url) {
String redisKey = urlSetKey(url);
Map<String,String> map = jedis.hgetAll(redisKey);
Integer count = 0;

for(Map.Entry<String, String> entry: map.entrySet()) {
count += Integer.valueOf(entry.getValue());
}
return count;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

返回搜索项在url中出现的次数

/**
* @Author Ragty
* @Description 返回搜索项在url中出现的次数
* @Date 22:12 2019/5/14
**/
public Integer getTermCount(String url,String term) {
String redisKey = urlSetKey(url);
String count = jedis.hget(redisKey,term);
return new Integer(count);
}
1
2
3
4
5
6
7
8
9
10

获取搜索词的词频

/**
* @Author Ragty
* @Description 获取搜索词的词频(Term Frequency)
* @Date 11:25 2019/6/4
**/
public BigDecimal getTermFrequency(String url,String term) {
if (!isIndexed(url)) {
System.out.println("Doesn't indexed.");
return null;
}

Integer documentCount = getWordCount(url);
Integer termCount = getTermCount(url,term);
return documentCount==0 ? new BigDecimal(0) : new BigDecimal(termCount).divide(new BigDecimal(documentCount),6,BigDecimal.ROUND_HALF_UP);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

2.计算逆文档频率
计算逆文档频率,需要计算文档总数,以及包含该搜索词的文章数

获取redis索引文章的总数

/**
* @Author Ragty
* @Description 获取redis索引文章的总数
* @Date 19:46 2019/6/5
**/
public Integer getUrlCount() {
Integer count = 0;
count = urlSetKeys().size();
return count;
}
1
2
3
4
5
6
7
8
9
10

获取含有搜索词的文章数

/**
* @Author Ragty
* @Description 获取含有搜索词的文章数
* @Date 22:42 2019/6/5
**/
public Integer getUrlTermCount(String term) {
Integer count = 0;
count = getUrls(term).size();
return count;
}
1
2
3
4
5
6
7
8
9
10

计算逆文档频率IDF(InverseDocumnetFrequency)

/**
* @Author Ragty
* @Description 计算逆文档频率IDF(InverseDocumnetFrequency)
* @Date 23:32 2019/6/5
**/
public BigDecimal getInverseDocumentFrequency(String term) {
Integer totalUrl = getUrlCount();
Integer urlTermCount = getUrlTermCount(term);
Double xx = new BigDecimal(totalUrl).divide(new BigDecimal(urlTermCount),6,BigDecimal.ROUND_HALF_UP).doubleValue();
BigDecimal idf = new BigDecimal(Math.log10(xx));
return idf;
}
1
2
3
4
5
6
7
8
9
10
11
12

3.获取TF-IDF
/**
* @Author Ragty
* @Description 获取tf-idf值
* @Date 23:34 2019/6/5
**/
public BigDecimal getTFIDF(String url,String term) {
BigDecimal tf = getTermFrequency(url, term);
BigDecimal idf = getInverseDocumentFrequency(term);
BigDecimal tfidf =tf.multiply(idf);
return tfidf;
}
1
2
3
4
5
6
7
8
9
10
11

4.数据测试
这里我采用我自己爬取的部分数据,进行一下简单的测试(可能因为数据集的原因导致部分结果不准确)

测试类方法:

/**
* @Author Ragty
* @Description 获取tfidf下的相关性
* @Date 8:47 2019/6/6
**/
private static BigDecimal getRelevance(String url,String term,JedisIndex index) {
BigDecimal tfidf = index.getTFIDF(url,term);
return tfidf;
}

/**
* @Author Ragty
* @Description 执行搜索
* @Date 23:49 2019/5/30
**/
public static WikiSearch search(String term,JedisIndex index) {
Map<String,BigDecimal> map = new HashMap<String, BigDecimal>();
Set<String> urls = index.getUrls(term);

for (String url: urls) {
BigDecimal tfidf = getRelevance(url,term,index).setScale(6,BigDecimal.ROUND_HALF_UP);
map.put(url,tfidf);
}

return new WikiSearch(map);
}

/**
* @Author Ragty
* @Description 按搜索项频率顺序打印内容
* @Date 13:46 2019/5/30
**/
private void print() {
List<Entry<String,BigDecimal>> entries = sort();
for(Entry<String,BigDecimal> entry: entries) {
System.out.println(entry.getKey()+" "+entry.getValue());
}
}

/**
* @Author Ragty
* @Description 根据相关性对数据排序
* @Date 13:54 2019/5/30
**/
public List<Entry<String,BigDecimal>> sort(){
List<Entry<String,BigDecimal>> entries = new LinkedList<Entry<String, BigDecimal>>(map.entrySet());

Comparator<Entry<String,BigDecimal>> comparator = new Comparator<Entry<String, BigDecimal>>() {
@Override
public int compare(Entry<String, BigDecimal> o1, Entry<String, BigDecimal> o2) {
return o2.getValue().compareTo(o1.getValue());
}
};

Collections.sort(entries,comparator);
return entries;
}
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

测试代码:

public static void main(String[] args) throws IOException {
Jedis jedis = JedisMaker.make();
JedisIndex index = new JedisIndex(jedis);

// search for the first term
String term1 = "java";
System.out.println("Query: " + term1);
WikiSearch search1 = search(term1, index);
search1.print();

// search for the second term
String term2 = "programming";
System.out.println("Query: " + term2);
WikiSearch search2 = search(term2, index);
search2.print();

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

测试结果:

Query: java
https://baike.baidu.com/item/LiveScript 0.029956
https://baike.baidu.com/item/Java/85979 0.019986
https://baike.baidu.com/item/Brendan%20Eich 0.017188
https://baike.baidu.com/item/%E7%94%B2%E9%AA%A8%E6%96%87/471435 0.013163
https://baike.baidu.com/item/Sun/69463 0.005504
https://baike.baidu.com/item/Rhino 0.004401
https://baike.baidu.com/item/%E6%8E%92%E7%89%88%E5%BC%95%E6%93%8E 0.003452
https://baike.baidu.com/item/javascript 0.002212
https://baike.baidu.com/item/js/10687961 0.002212
https://baike.baidu.com/item/%E6%BA%90%E7%A0%81 0.002205
https://baike.baidu.com/item/%E6%BA%90%E7%A0%81/344212 0.002205
https://baike.baidu.com/item/%E8%84%9A%E6%9C%AC%E8%AF%AD%E8%A8%80 0.001989
https://baike.baidu.com/item/SQL 0.001779
https://baike.baidu.com/item/PHP/9337 0.001503
https://baike.baidu.com/item/iOS/45705 0.001499
https://baike.baidu.com/item/Netscape 0.000863
https://baike.baidu.com/item/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F 0.000835
https://baike.baidu.com/item/Mac%20OS%20X 0.000521
https://baike.baidu.com/item/C%E8%AF%AD%E8%A8%80 0.000318

Query: programming
https://baike.baidu.com/item/C%E8%AF%AD%E8%A8%80 0.004854
https://baike.baidu.com/item/%E8%84%9A%E6%9C%AC%E8%AF%AD%E8%A8%80 0.002529
---------------------

搜索引擎优化 TF_IDF之Java实现的更多相关文章

  1. angularjs应用prerender.io 搜索引擎优化实践

    上一篇博文(http://www.cnblogs.com/ideal-lx/p/5625428.html)介绍了单页面搜索引擎优化的原理,以及介绍了两个开源框架的优劣.prerender框架的工作原理 ...

  2. 知道吗?9个搜索引擎优化(SEO)最佳实践

    作为网页设计师,搜索引擎优化重要吗?我们知道,网站设计是把屏幕上平淡无奇变成令人愉快的美感,更直观地辨认信息.这也是人与人之间在沟通想法,这样的方式一直在演变.穴居人拥有洞穴壁画,古埃及人有象形文字, ...

  3. 总结的一些网站利于搜索引擎优化的小常识及SEO优化

    网站利于搜索引擎优化的小常识 1. 尽量用独立IP和空间原因:同IP下其他网站受罚,可能会对你站有影响.如果你的站和很多垃圾.色情站同在一个服务器,搜索引擎会喜欢吗? 2. 做不同内容网站时,避免使用 ...

  4. Linkedin工程师是如何优化他们的Java代码的(转)

    英文原文:LinkedIn Feed: Faster with Less JVM Garbage 最近在刷各大公司的技术博客的时候,我在Linkedin的技术博客上面发现了一篇很不错博文.这篇博文介绍 ...

  5. 网络爬虫与搜索引擎优化(SEO)

    爬虫及爬行方式 爬虫有很多名字,比如web机器人.spider等,它是一种可以在无需人类干预的情况下自动进行一系列web事务处理的软件程序.web爬虫是一种机器人,它们会递归地对各种信息性的web站点 ...

  6. SEO搜索引擎优化(一)

    什么是SEO呢 英文为"Search Engine Optimization",中文名为"搜索引擎优化".SEO是指通过对网站进行站内优化和修复(网站Web结构 ...

  7. Linkedin工程师是如何优化他们的Java代码的

    http://greenrobot.me/devpost/java-faster-less-jvm-garbage/ Linkedin工程师是如何优化他们的Java代码的 最近在刷各大公司的技术博客的 ...

  8. 《SEO教程:搜索引擎优化入门与进阶(第3版)》

    <SEO教程:搜索引擎优化入门与进阶(第3版)> 基本信息 作者: 吴泽欣 丛书名: 图灵原创 出版社:人民邮电出版社 ISBN:9787115357014 上架时间:2014-7-1 出 ...

  9. 网站优化不等于搜索引擎优化SEO

    对于SEO相信搞网络营销的人基本上都知道这个名词,英文全称为search engine optimization,中文一般叫搜索引擎优化,也有的叫搜索引擎定位(Search Engine Positi ...

随机推荐

  1. IDEA2019.1.3最新破解方式

    版本2019.1.3 1.下载破解JAR,放入IDEA的bin文件夹中     链接:https://pan.baidu.com/s/1N1BHeJ0-mmFIWbrh5h4k-g     提取码:g ...

  2. 如何让EditText不能自动获取焦点(转)

    转载地址:http://blog.csdn.net/subaohao/article/details/9043895 在activity中放置了1个或1个以上的EditText,进入该activity ...

  3. MacBook Pro 快捷键2

    Mac 键盘快捷键 您可以按下组合键来实现通常需要鼠标.触控板或其他输入设备才能完成的操作.   要使用键盘快捷键,请按住一个或多个修饰键,同时按快捷键的最后一个键.例如,要使用快捷键 Command ...

  4. HTML5: HTML5 Web SQL 数据库

    ylbtech-HTML5: HTML5 Web SQL 数据库 1.返回顶部 1. HTML5 Web SQL 数据库 Web SQL 数据库 API 并不是 HTML5 规范的一部分,但是它是一个 ...

  5. python requests函数封装方法

    python  requests函数封装方法 上代码 import requests import json """ 封装request请求, 1.post:my_pos ...

  6. selenium自动化测试时,chrome 出现“Chrome 正受到自动测试软件的控制”的解决办法

    背景 使用selenium自动化测试的时候,启动浏览器出现'Chrome正在受到自动软件的控制'的问题,修改方法有两种. 一.在浏览器配置里加个参数,忽略掉这个警告提示语:disable_infoba ...

  7. Forgery CodeForces - 1059B

    一道印章刻印的题目: 具体要求:有一个固定的3*3的印章,给你一个墨迹问能用这个印章印出墨迹吗?(一个像素可以多次被上色) 输入:第一行是墨迹的行列规模,接下来是墨迹 输出:If Andrey can ...

  8. C/S and B/S

    C/S结构,即Client/Server(客户机/服务器)结构,是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端,降低了系统的通讯开销,可以充分利用两端硬件环境的优势. ...

  9. Axon 3.0.x 框架简介官方文档

    因为需要用到,但是在网上对应的资料实在是很少,只有迎着头皮看官网文档并配合翻译器.如有误导多多包涵. Axon 什么是 Axon Axon Framework 通过支持开发人员应用命令查询责任隔离(C ...

  10. Linux部分常用命令详解(二)

    date 命令详解 date命令可以按照指定格式显示日期,只键入date则以默认格式显示当前时间 例如: 如果需要以指定的格式显示日期,可以使用“+”开头的字符串指定其格式,详细格式如下: %n : ...