搜索引擎优化 TF_IDF之Java实现
实现之前,我们要事先说明一些问题:
我们用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实现的更多相关文章
- angularjs应用prerender.io 搜索引擎优化实践
上一篇博文(http://www.cnblogs.com/ideal-lx/p/5625428.html)介绍了单页面搜索引擎优化的原理,以及介绍了两个开源框架的优劣.prerender框架的工作原理 ...
- 知道吗?9个搜索引擎优化(SEO)最佳实践
作为网页设计师,搜索引擎优化重要吗?我们知道,网站设计是把屏幕上平淡无奇变成令人愉快的美感,更直观地辨认信息.这也是人与人之间在沟通想法,这样的方式一直在演变.穴居人拥有洞穴壁画,古埃及人有象形文字, ...
- 总结的一些网站利于搜索引擎优化的小常识及SEO优化
网站利于搜索引擎优化的小常识 1. 尽量用独立IP和空间原因:同IP下其他网站受罚,可能会对你站有影响.如果你的站和很多垃圾.色情站同在一个服务器,搜索引擎会喜欢吗? 2. 做不同内容网站时,避免使用 ...
- Linkedin工程师是如何优化他们的Java代码的(转)
英文原文:LinkedIn Feed: Faster with Less JVM Garbage 最近在刷各大公司的技术博客的时候,我在Linkedin的技术博客上面发现了一篇很不错博文.这篇博文介绍 ...
- 网络爬虫与搜索引擎优化(SEO)
爬虫及爬行方式 爬虫有很多名字,比如web机器人.spider等,它是一种可以在无需人类干预的情况下自动进行一系列web事务处理的软件程序.web爬虫是一种机器人,它们会递归地对各种信息性的web站点 ...
- SEO搜索引擎优化(一)
什么是SEO呢 英文为"Search Engine Optimization",中文名为"搜索引擎优化".SEO是指通过对网站进行站内优化和修复(网站Web结构 ...
- Linkedin工程师是如何优化他们的Java代码的
http://greenrobot.me/devpost/java-faster-less-jvm-garbage/ Linkedin工程师是如何优化他们的Java代码的 最近在刷各大公司的技术博客的 ...
- 《SEO教程:搜索引擎优化入门与进阶(第3版)》
<SEO教程:搜索引擎优化入门与进阶(第3版)> 基本信息 作者: 吴泽欣 丛书名: 图灵原创 出版社:人民邮电出版社 ISBN:9787115357014 上架时间:2014-7-1 出 ...
- 网站优化不等于搜索引擎优化SEO
对于SEO相信搞网络营销的人基本上都知道这个名词,英文全称为search engine optimization,中文一般叫搜索引擎优化,也有的叫搜索引擎定位(Search Engine Positi ...
随机推荐
- 容器————priority_queue
#include <queue> 与queue不同的是可以自定义其中数据的优先级,让优先级高的先出队列. 优先队列具有队列的所有特性,包括基本操作,只是在这基础上添加了内部的一个排序,它本 ...
- Least Common Ancestors
/* Least Common Ancestors * Au: Small_Ash */ #include <bits/stdc++.h> using namespace std; con ...
- 20175203 2018-2019-2《Java程序设计》第四周学习总结
## 教材学习内容总结 第五章内容知识点总结: 子类父类的定义格式: class 子类名 extends 父类名 { } 定义子类时用extends Object类是所有类的祖先类,即最原始类. 子类 ...
- ListView 分页显示(转载+修改)下
通过实践发现,尚大大在判断”上一页“按钮和”下一页按钮“是否可用的地方,有问题: 原代码: public void checkButton(){ //索引值小于等于0,表示不能向前翻页了,以经到了第一 ...
- (转)图文详解MyEclipse中新建Maven webapp项目的步骤
转:https://blog.csdn.net/ClementAD/article/details/46592557 MyEclipse中创建新的Maven项目(webapp目录结构)过程如下: ...
- 2018icpc南京/gym101981 A Adrien and Austin 博弈
题意: n个连续排列的石子,每次只许拿连续的(中间没有空格)的k个,问你谁必胜 题解: 简单博弈,特判总数为0,k=1两种情况,其他情况先拿必胜,方法是拿掉中间的,然后对方怎么拿你镜面拿就行. #in ...
- RabbitMQ(七)心跳控制 -- heartbeat
https://blog.csdn.net/jiao_fuyou/article/details/23186407
- Eclipes更改字体颜色
有图有真像 更改字体大小
- 2019牛客多校第七场C-Governing sand(线段树+枚举)
Governing sand 题目传送门 解题思路 枚举每一种高度作为最大高度,则需要的最小花费的钱是:砍掉所有比这个高度高的树的所有花费+砍掉比这个高度低的树里最便宜的m棵树的花费,m为高度低的里面 ...
- 7.Jmeter 快速入门教程--录制复杂web测试脚本
Jmeter的功能简单,不需要有脚本语言的编写经验,纯图形界面添加测试场景, 用起来上手很快.但是如果手动添加每一个web(http/https)请求,费时又费力.而且有可能最后手动编写的和实际发的请 ...