『壹』 推薦系統:怎樣實現內容相似推薦
很多產品想要加入推薦系統模塊,最簡單的就是做內容相似推薦,雖然技術簡單但是效果卻很好,對於增加用戶粘性、提升用戶留存有較多的效果,甚至很多產品後來加入了很多推薦模塊之後,還是發現導流效果最好的依然是內容的相似推薦。
比如看完了一片《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