导航:首页 > 编程语言 > 相似度计算java

相似度计算java

发布时间:2023-05-17 16:51:45

‘壹’ 推荐系统:怎样实现内容相似推荐

很多产品想要加入推荐系统模块,最简单的就是做内容相似推荐,虽然技术简单但是效果却很好,对于增加用户粘性、提升用户留存有较多的效果,甚至很多产品后来加入了很多推荐模块之后,还是发现导流效果最好的依然是内容的相似推荐。

比如看完了一片《python怎样读取MySQL》之后,在相似推荐中看到了一片题目为《Python操作MySQL的效果优化》的文章,很自然的就像多深入了解一下,于是就点进去看一看,那么对于整个网站来说,就会降低跳出率,增加用户的留存,是一个很好的用户体验。

实现一个内容相似推荐的方案比较简单,大体上包含以下步骤:

1、获取内容数据,比如标题、关键字、分类、甚至全文本;

一般文档、数据等内容都存储于mysql,可以使用python/java等语言直接读取mysql导出到文件.txt格式,或者直接用shell的mysql -e sql > data.txt的方式导出。

一般情况下,全文本内容太散,不会作为候选字段,但是有些视频之类的实体,因为标题和简介文字太少,如果有详情全文本的话,也可以加入候选数据字段。

2、对内容数据做中文分词;

如果是python语言,可以使用“结巴分词”,地址为: https://github.com/fxsjy/jieba

或者可以直接使用网络云的中文分词,网络的NLP自然语言处理技术还是很厉害的。

3、提取内容数据的关键词;

当分词之后,分词结果中包含很多“的”、“也”等无意义的词语,这些词语不能称之为关键词,一般会通过TF/IDF的方法计算每个词语的权重,将一个文档的所有词语的TF/IDF权重倒序排列,取TOPN个作为关键词;

如果使用的是jieba分词,那么直接就自带了提取关键词的支持;当然也可以自己计算,TF就是计算一篇文章中每个词语出现的次数拦仿、IDF就是这个词语在所有文章中出现的次数,TF除以IDF就是权重值;

4、将关键词映射成数字向量;

我们最终的目标是计算文档之间的相似度,要计算相似度那就需要把内容映射成向量,第一步就是先把每个词语映射成向量,映射的方式有几种:

使用one hot方法映射成向量

自己训练word2vec密度向量;

使用业界的训练好的word2vec向量

一般情况下,自己的数据集比较小,效果会比业界的word2vec效果差一些,比如这里推荐腾讯开源的200维度全网word2vec向量,地址在: https://ai.tencent.com/ailab/nlp/embedding.html

5、计算文档粒度的数字向量;

得到每个词语的向量之后,通过加权平均的方式可以计算整个文档的向量;

权重可以使用每个词语的频率次数归一化,或者直接平均即可;

6、计算文档之间的相似度;

使用cosin算法就能够计算文档向量之间的相似度;

cosin算法很简单,java、python自己实现就可以,也可用https://scikit-learn.org或者http://surpriselib.com/中的相似度计算模块直接调用实现。

计算完之后,对于每个文档,将它跟每个文档的相似度做倒序排列,比如TOP 30个作为推荐的结果集合。

7、将文档的相似度关系存入简衡纤mysql/redis等缓存;

第6步骤会得到一个这样的结果:(文档ID、相拦链似文档ID列表),将这样的数据直接存入mysql或者redis,key就是文档ID,value是相似文档ID列表即可。

8、当页面展示一个内容的时候,提取相似推荐进行展示;

当用户访问一个页面的时候,后端服务python/java从缓存redis或者mysql中根据展示的页面的文档ID,提取相似ID列表;

因为前几步骤是提前计算好的列表,这里也可能做一些过滤已下线的事情,然后根据ID提取对应的标题、简介等信息,组装成相似推荐列表返回给前端即可;

总结

以上就是离线计算相似推荐的步骤,其实还可以用在线的方式进行,把这个问题按照搜索的架构实现即可,新来一个文档就分词、计算关键词列表存储,然后每次访问的时候根据关键词列表查询相同关键词列表的文档也可以实现。

当相似内容推荐上线后,就能够不断积累一些用户点击、查看文档的行为数据,基于行为数据就能训练协同过滤的模型,实现内容不相似但是行为相似的协同过滤推荐。

‘贰’ java如何实现超过10w条文本数据的相似度计算

最简单的、最节省性能的方法是建立字典。 字典的索引就是字本身,遍历字符串,没遇到一个字就加入到字典中,加入的时候判断下,如果索引存在则加1,不存在则创建,然后在取字典最大值,大于6就报错。 上面说的字典可以用java中的hashMap实现。

‘叁’ java学到哪才可以检测两个文本的相似度

学到IO流可以比较文本了, 不过用IO比较文本比较麻烦, 而且效率低

如果要效率高的话, 就需要学
linux + thread + progress

这样子可以通过java调用linux命令
linux中有一个comm -12命令来实现比较两个文件的共同数据, 生成一个新文本。 拿到新文本的大小/旧文本的大小, 旧可以粗略计算出相似度, 而且效率极其高
如果文本有上百万行数据的话, 用IO可能要十几个小时才有结果, 但是linux命令只需要1分钟左右就可以出结果

‘肆’ 怎样用python或者是java计算文本相似度

第一步:把每个网页文本分词,成为词包(bag of words)。
第三步:统计网页(文档)总数M。
第三步:统计第一个网页词数N,计算第一个网页第一个词在该网页中出现的次数n,再找出该词在所有文档中出现的次数m。则该词的tf-idf 为:n/N * 1/(m/M) (还有其它的归一化公式,这里是最基本最直观的公式)
第四步:重复第三步,计算出一个网页所有词的tf-idf 值。
第五步:重复第四步,计算出所有网页每个词的tf-idf 值。
3、处理用户查询
第一步:对用户查询进行分词。
第二步:根据网页库(文档)的数据,计算用户查询中每个词的tf-idf 值。
4、相似度的计算
使用余弦相似度来计算用户查询和每个网页之间的夹角。夹角越小,越相似。

‘伍’ 如何使用Java实现屏幕找图功能

测试代码

[java] view plain
public static void main(String[] args) throws Exception {
findImage4FullScreen(ImageCognition.SIM_ACCURATE_VERY);
}

public static void findImage4FullScreen(int sim) throws Exception {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int w = (int) screenSize.getWidth();
int h = 200;

Robot robot = new Robot();
BufferedImage screenImg = robot.createScreenCapture(new Rectangle(0, 0,
w, h));//对屏幕指定范围进行截图,保存到BufferedImage中
OutputStream out = new FileOutputStream("data/images/screen.png");
ImageIO.write(screenImg, "png", out);//将截到的BufferedImage写到本地

InputStream in = new FileInputStream("data/images/search.png");
BufferedImage searchImg = ImageIO.read(in);//将要查找的本地图读到BufferedImage

//图片识别工具类
ImageCognition ic = new ImageCognition();

List<CoordBean> list = ic.imageSearch(screenImg, searchImg, sim);
for (CoordBean coordBean : list) {
System.out.println("找到图片,坐标是" + coordBean.getX() + ","
+ coordBean.getY());

//标注找到的图的位置
Graphics g = screenImg.getGraphics();
g.setColor(Color.BLACK);
g.drawRect(coordBean.getX(), coordBean.getY(),
searchImg.getWidth(), searchImg.getHeight());
g.setFont(new Font(null, Font.BOLD, 20));
g.drawString("←找到的图片在这里",
coordBean.getX() + searchImg.getWidth() + 5,
coordBean.getY() + 10 + searchImg.getHeight() / 2);
out = new FileOutputStream("data/images/result.png");
ImageIO.write(screenImg, "png", out);
}
}

额外的类

CoordBean

package cn.xt.imgCongnition;

public class CoordBean {

private int x;
private int y;

/**
* 获取x坐标
*
* @return x坐标
*/
public int getX() {
return x;
}

public void setX(int x) {
this.x = x;
}

/**
* 获取y坐标
*
* @return
*/
public int getY() {
return y;
}

public void setY(int y) {
this.y = y;
}

}

RgbImageComparerBean

package cn.xt.imgCongnition;

/**
* RGB 相关,图片相似度计算时使用
*
*/
public class RgbImageComparerBean {

/****** 颜色值数组,第一纬度为x坐标,第二纬度为y坐标 ******/
private int colorArray[][];

/*** 是否忽略此点,若为true,则不纳入比较的像素行列。 ***/
private boolean ignorePx[][];

/**** 图片的宽高 ****/
private int imgWidth;
private int imgHeight;

// 图片的像素总数
private int pxCount;

/**
* 获取图像的二维数组组成
*
* @return 图像的二维数组
*/
public int[][] getColorArray() {
return colorArray;
}

/**
* 要对比的像素总数,会自动筛选掉不对比的颜色
*
* @param pxCount
*/
public void setPxCount(int pxCount) {
this.pxCount = pxCount;
}

/**
* 设置颜色二维数组
*
* @param colorArray
* 颜色二维数组,一维为x轴,二维为y轴
*/
public void setColorArray(int[][] colorArray) {
this.colorArray = colorArray;
this.imgWidth = this.colorArray.length;
this.imgHeight = this.colorArray[0].length;
this.pxCount = this.imgWidth * this.imgHeight;
}

/**
* 是否忽略此点,若为true,则不纳入像素比较行列。
*
* @return 具体x,y坐标的那个像素点
*/
public boolean[][] getIgnorePx() {
return ignorePx;
}

/**
* 是否忽略此点,若为true,则不纳入像素比较行列。
*
* @param ignorePx
* 具体x,y坐标的那个像素点
*/
public void setIgnorePx(boolean[][] ignorePx) {
this.ignorePx = ignorePx;
}

/**
* 获取图像的宽度
*
* @return 图像宽度
*/
public int getImgWidth() {
return imgWidth;
}

/**
* 获取图像的高度
*
* @return 图像高度
*/
public int getImgHeight() {
return imgHeight;
}

/**
* 获取图像里像素的总数
*
* @return
*/
public int getPxCount() {
return pxCount;
}

}

‘陆’ java 在console行输入一串String后回车,仍无法停止。 下面的程序是计算相似度的,当用户输入关键字后

1.代码如下:
importjava.io.File;
importjava.io.FileNotFoundException;
importjava.util.HashSet;
importjava.util.Scanner;
importjava.util.Set;

publicclassQurey{

publicstaticvoidmain(String[]args)throws缓手仔FileNotFoundException{
System.out.println("pleaseenterafiletoreadfrom:");
Scannerin=newScanner(System.in);
Stringfilename=in.next();
Set<String>textkeywords=readWords(filename);
//in.close();
System.out
.println(",1toquit:");
Set<String>keywords=newHashSet<String>();
Scannerinput=newScanner(System.in);
//correcthere
Stringtemp;
while(!(temp=input.next()).equals("1")){
keywords.add(temp.toLowerCase());
}
intqIntersectD=0;
for(Stringword:keywords){
if(textkeywords.contains(word)){
qIntersectD++;
}
}
doubleSimilarity=0;
Similarity=qIntersectD
/(Math.sqrt(textkeywords.size())*Math.sqrt(keywords.size()));
System.out.println(":"
+Similarity);
}

publicstaticSet<String>readWords(Stringfilename)
throwsFileNotFoundException{
Set<String>扰汪words=newHashSet<String>();
Scannerin=newScanner(newFile(filename));
in.useDelimiter("[^a-zA-Z]+"薯搭);
while(in.hasNext()){
words.add(in.next().toLowerCase());
}
in.close();
returnwords;
}
}

2.运行结果:

‘柒’ 如何计算多个文本的相似度java程序,利用向量

String text1 = "我爱学习";
String text2 = "我爱读书";
String text3 = "他是黑客";
TextSimilarity textSimilarity = new CosineTextSimilarity();
double score1pk1 = textSimilarity.similarScore(text1, text1);
double score1pk2 = textSimilarity.similarScore(text1, text2);
double score1pk3 = textSimilarity.similarScore(text1, text3);
double score2pk2 = textSimilarity.similarScore(text2, text2);
double score2pk3 = textSimilarity.similarScore(text2, text3);
double score3pk3 = textSimilarity.similarScore(text3, text3);
System.out.println(text1+" 和 "+text1+" 的相似度分值:"+score1pk1);
System.out.println(text1+" 和 "+text2+" 的相似度分值:"+score1pk2);
System.out.println(text1+" 和 "+text3+" 的相似度分值:"+score1pk3);
System.out.println(text2+" 和 "+text2+" 的相似度分值:"+score2pk2);
System.out.println(text2+" 和 "+text3+" 的相似度分值:"+score2pk3);
System.out.println(text3+" 和 "+text3+" 的相似度分值:"+score3pk3);

运行结果如下:
我爱学习 和 我爱学习 的相似度分值:1.0
我爱学习 和 我爱读书 的相似度分值:0.4
我爱学习 和 他是黑客 的相似度分值:0.0
我爱读书 和 我爱读书 的相似度分值:1.0
我爱读书 和 他是黑客 的相似度分值:0.0
他是黑客 和 他是黑客 的相似度分值:1.0

方式二:简单共有词,通过计算两篇文档有多少个相同的词来评估他们的相似度
实现类:org.apdplat.word.analysis.SimpleTextSimilarity
用法如下:
String text1 = "我爱学习";
String text2 = "我爱读书";
String text3 = "他是黑客";
TextSimilarity textSimilarity = new SimpleTextSimilarity();
double score1pk1 = textSimilarity.similarScore(text1, text1);
double score1pk2 = textSimilarity.similarScore(text1, text2);
double score1pk3 = textSimilarity.similarScore(text1, text3);
double score2pk2 = textSimilarity.similarScore(text2, text2);
double score2pk3 = textSimilarity.similarScore(text2, text3);
double score3pk3 = textSimilarity.similarScore(text3, text3);
System.out.println(text1+" 和 "+text1+" 的相似度分值:"+score1pk1);
System.out.println(text1+" 和 "+text2+" 的相似度分值:"+score1pk2);
System.out.println(text1+" 和 "+text3+" 的相似度分值:"+score1pk3);
System.out.println(text2+" 和 "+text2+" 的相似度分值:"+score2pk2);
System.out.println(text2+" 和 "+text3+" 的相似度分值:"+score2pk3);
System.out.println(text3+" 和 "+text3+" 的相似度分值:"+score3pk3);

运行结果如下:
我爱学习 和 我爱学习 的相似度分值:1.0
我爱学习 和 我爱读书 的相似度分值:0.5
我爱学习 和 他是黑客 的相似度分值:0.0
我爱读书 和 我爱读书 的相似度分值:1.0
我爱读书 和 他是黑客 的相似度分值:0.0
他是黑客 和 他是黑客 的相似度分值:1.0

‘捌’ java版 opencv 图像对比相似度怎么实现

没有专门的函数,你要自己写 以前写过一个,先转HSV,只考虑HS两维,再求颜色直方图,最后根据两个图像对应直方图上的距离就可以了,通过这个可以计算相似度

‘玖’ 文本相似度算法-Jaro distance

给定两个灶指衡文本串 , ,他们的Joro距离定义为:

match 的字符数:
分别来自 , 的字符,当他们相同或者距离小于 ,则被认为是 match 的。

比如: =“DIXON”, =“DICKSONX”

中的逗滑每一个字符都会与 中距离 内的字符进行比较。将所有 match 的字符隐做串,需要替调换顺序才能匹配的总数除以二就是transpositions的大小 。这里两个字符串中匹配的分别是:"DION",“DION",所以 。
另外 =4, =8,
则:

参考:
https://rosettacode.org/wiki/Jaro_distance#Java

阅读全文

与相似度计算java相关的资料

热点内容
遵义联通服务器地址是什么 浏览:27
ansys约束命令流 浏览:812
解压软件电脑版如何下载 浏览:791
闪电匕首算法球 浏览:692
linuxredis停止命令 浏览:670
大麦账号怎么加密 浏览:113
穿越火线怎么找服务器 浏览:526
秘密加密社交软件app 浏览:256
c语言编译器怎么找文件 浏览:835
数学不好能编程吗 浏览:254
微云里的视频加密 浏览:41
3大加密货币交易平台 浏览:647
钣金激光切割机编程 浏览:496
vivo手机手电筒app在哪里 浏览:787
单片机晶振电路电容 浏览:887
穿越火线河南一区服务器云主机 浏览:41
文件夹与快捷方式显示一致 浏览:879
幻影服务器怎么看金钱 浏览:349
小米手机怎么用app减肥 浏览:893
本机如何与云服务器互通 浏览:652