1. 程式人生 > >如何比較兩個文字的相似度 .

如何比較兩個文字的相似度 .

目標

嘗試了一下把PageRank演算法結合了文字相似度計算。直覺上是想把一個list裡,和大家都比較靠攏的文字可能最後的PageRank值會比較大。因為如果最後計算的PageRank值大,說明有比較多的文字和他的相似度值比較高,或者有更多的文字向他靠攏。這樣是不是就可以得到一些相對核心的文字,或者相對代表性的文字?如果是要在整堆文本里切分一些關鍵的詞做token,那麼每個token在每份文本里的權重就可以不一樣,那麼是否就可以得到比較核心的token,來給這些文字打標籤?當然,分詞切詞的時候都是要用工具過濾掉stopword的。

我也只是想嘗試一下這個想法,就簡單實現了整個過程。可能實現上還有問題。我的結果是最後大家的PageRank值都非常接近。如:

[java] view plaincopyprint?
  1. 5.6267420679583525.6267420664276585.6267420704959785.6267420567682155.626742079766638
5.626742067958352, 5.626742066427658, 5.626742070495978, 5.626742056768215, 5.626742079766638

選5,10,20,50都差不多。都非常接近。主要在設定PageRank定製迭代的那個DISTANCE值,值越接近0,迭代次數越多,經過很多次遊走之後,文字之間的關係都很相近,各自的pagerank值相差不大。如果調成0.5這樣的級別,可能迭代了4次左右就停下來了,互相之間差距會大一些。具體看自己的需求來控制這個距離引數了

程式碼實現

文字之間的相似度計算用的是餘弦距離,先雜湊過。下面是計算兩個List<String>的餘弦距離程式碼:

[java] view plaincopyprint?
  1. package dcd.academic.recommend;  
  2. import java.util.ArrayList;  
  3. import java.util.HashMap;  
  4. import java.util.Iterator;  
  5. import java.util.Map;  
  6. import dcd.academic.util.StdOutUtil;  
  7. public
    class CosineDis {  
  8. publicstaticdouble getSimilarity(ArrayList<String> doc1, ArrayList<String> doc2) {  
  9. if (doc1 != null && doc1.size() > 0 && doc2 != null && doc2.size() > 0) {  
  10.             Map<Long, int[]> AlgorithmMap = new HashMap<Long, int[]>();  
  11. for (int i = 0; i < doc1.size(); i++) {  
  12.                 String d1 = doc1.get(i);  
  13. long sIndex = hashId(d1);  
  14. int[] fq = AlgorithmMap.get(sIndex);  
  15. if (fq != null) {  
  16.                     fq[0]++;  
  17.                 } else {  
  18.                     fq = newint[2];  
  19.                     fq[0] = 1;  
  20.                     fq[1] = 0;  
  21.                     AlgorithmMap.put(sIndex, fq);  
  22.                 }  
  23.             }  
  24. for (int i = 0; i < doc2.size(); i++) {  
  25.                 String d2 = doc2.get(i);  
  26. long sIndex = hashId(d2);  
  27. int[] fq = AlgorithmMap.get(sIndex);  
  28. if (fq != null) {  
  29.                     fq[1]++;  
  30.                 } else {  
  31.                     fq = newint[2];  
  32.                     fq[0] = 0;  
  33.                     fq[1] = 1;  
  34.                     AlgorithmMap.put(sIndex, fq);  
  35.                 }  
  36.             }  
  37.             Iterator<Long> iterator = AlgorithmMap.keySet().iterator();  
  38. double sqdoc1 = 0;  
  39. double sqdoc2 = 0;  
  40. double denominator = 0;  
  41. while (iterator.hasNext()) {  
  42. int[] c = AlgorithmMap.get(iterator.next());  
  43.                 denominator += c[0] * c[1];  
  44.                 sqdoc1 += c[0] * c[0];  
  45.                 sqdoc2 += c[1] * c[1];  
  46.             }  
  47. return denominator / Math.sqrt(sqdoc1 * sqdoc2);  
  48.         } else {  
  49. return0;  
  50.         }  
  51.     }  
  52. publicstaticlong hashId(String s) {  
  53. long seed = 131// 31 131 1313 13131 131313 etc.. BKDRHash
  54. long hash = 0;  
  55. for (int i = 0; i < s.length(); i++) {  
  56.             hash = (hash * seed) + s.charAt(i);  
  57.         }  
  58. return hash;  
  59.     }  
  60. publicstaticvoid main(String[] args) {  
  61.         ArrayList<String> t1 = new ArrayList<String>();  
  62.         ArrayList<String> t2 = new ArrayList<String>();  
  63.         t1.add("sa");  
  64.         t1.add("dfg");  
  65.         t1.add("df");  
  66.         t2.add("gfd");  
  67.         t2.add("sa");  
  68.         StdOutUtil.out(getSimilarity(t1, t2));  
  69.     }  
  70. }  
package dcd.academic.recommend;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import dcd.academic.util.StdOutUtil;

public class CosineDis {

	public static double getSimilarity(ArrayList<String> doc1, ArrayList<String> doc2) {
		if (doc1 != null && doc1.size() > 0 && doc2 != null && doc2.size() > 0) {

			Map<Long, int[]> AlgorithmMap = new HashMap<Long, int[]>();

			for (int i = 0; i < doc1.size(); i++) {
				String d1 = doc1.get(i);
				long sIndex = hashId(d1);
				int[] fq = AlgorithmMap.get(sIndex);
				if (fq != null) {
					fq[0]++;
				} else {
					fq = new int[2];
					fq[0] = 1;
					fq[1] = 0;
					AlgorithmMap.put(sIndex, fq);
				}
			}

			for (int i = 0; i < doc2.size(); i++) {
				String d2 = doc2.get(i);
				long sIndex = hashId(d2);
				int[] fq = AlgorithmMap.get(sIndex);
				if (fq != null) {
					fq[1]++;
				} else {
					fq = new int[2];
					fq[0] = 0;
					fq[1] = 1;
					AlgorithmMap.put(sIndex, fq);
				}

			}

			Iterator<Long> iterator = AlgorithmMap.keySet().iterator();
			double sqdoc1 = 0;
			double sqdoc2 = 0;
			double denominator = 0;
			while (iterator.hasNext()) {
				int[] c = AlgorithmMap.get(iterator.next());
				denominator += c[0] * c[1];
				sqdoc1 += c[0] * c[0];
				sqdoc2 += c[1] * c[1];
			}

			return denominator / Math.sqrt(sqdoc1 * sqdoc2);
		} else {
			return 0;
		}
	}

	public static long hashId(String s) {
		long seed = 131; // 31 131 1313 13131 131313 etc.. BKDRHash
		long hash = 0;
		for (int i = 0; i < s.length(); i++) {
			hash = (hash * seed) + s.charAt(i);
		}
		return hash;
	}

	public static void main(String[] args) {
		ArrayList<String> t1 = new ArrayList<String>();
		ArrayList<String> t2 = new ArrayList<String>();
		t1.add("sa");
		t1.add("dfg");
		t1.add("df");

		t2.add("gfd");
		t2.add("sa");
		
		StdOutUtil.out(getSimilarity(t1, t2));
	}
}

利用上面這個類,根據文字之間的相似度,為每份文字計算得到一個向量(最後要歸一一下),用來初始化PageRank的起始矩陣。我用的資料是我solr裡的論文標題+摘要的文字,我是通過SolrjHelper這個類去取得了一個List<String>。你想替換的話把這部分換成自己想測試的String列就可以了。下面是讀取資料,生成向量給PageRank類的程式碼:

[java] view plaincopyprint?
  1. package dcd.academic.recommend;  
  2. import java.io.IOException;  
  3. import java.net.UnknownHostException;  
  4. import java.util.ArrayList;  
  5. import java.util.List;  
  6. import dcd.academic.mongodb.MyMongoClient;  
  7. import dcd.academic.solrj.SolrjHelper;  
  8. import dcd.academic.util.StdOutUtil;  
  9. import dcd.academic.util.StringUtil;  
  10. import com.mongodb.BasicDBList;  
  11. import com.mongodb.BasicDBObject;  
  12. import com.mongodb.DBCollection;  
  13. import com.mongodb.DBCursor;  
  14. import com.mongodb.DBObject;  
  15. publicclass BtwPublication {  
  16. publicstaticfinalint NUM = 20;  
  17. publicstaticvoid main(String[] args) throws IOException{  
  18.         BtwPublication bp = new BtwPublication();  
  19. //bp.updatePublicationForComma();
  20.         PageRank pageRank = new PageRank(bp.getPagerankS("random"));  
  21.         pageRank.doPagerank();  
  22.     }  
  23. publicdouble getDist(String pub1, String pub2) throws IOException {  
  24. if (pub1 != null && pub2 != null) {  
  25.             ArrayList<String> doc1 = StringUtil.getTokens(pub1);  
  26.             ArrayList<String> doc2 = StringUtil.getTokens(pub2);  
  27. return CosineDis.getSimilarity(doc1, doc2);  
  28.         } else {  
  29. return0;  
  30.         }  
  31.     }  
  32. //  public List<Map<String, String>> getPubs(String name) {
  33. //      
  34. //  }
  35. public List<List<Double>> getPagerankS(String text) throws IOException {  
  36.         SolrjHelper helper = new SolrjHelper(1);  
  37.         List<String> pubs = helper.getPubsByTitle(text, 0, NUM);  
  38.         List<List<Double>> s = new ArrayList<List<Double>>();  
  39. for (String pub : pubs) {  
  40.             List<Double> tmp_row = new ArrayList<Double>();  
  41. double total = 0.0;  
  42. for (String other : pubs) {  
  43. if (!pub.equals(other)) {  
  44. double tmp = getDist(pub, other);  
  45.                     tmp_row.add(tmp);  
  46.                     total += tmp;  
  47.                 } else {  
  48.                     tmp_row.add(0.0);  
  49.                 }  
  50.             }  
  51.             s.add(getNormalizedRow(tmp_row, total));  
  52.         }  
  53. return s;  
  54.     }  
  55. public List<Double> getNormalizedRow(List<Double> row, double d) {  
  56.         List<Double> res = new ArrayList<Double>();  
  57. for (int i = 0; i < row.size(); i ++) {  
  58.             res.add(row.get(i) / d);  
  59.         }  
  60.         StdOutUtil.out(res.toString());  
  61. return res;  
  62.     }  
  63. }  
package dcd.academic.recommend;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import dcd.academic.mongodb.MyMongoClient;
import dcd.academic.solrj.SolrjHelper;
import dcd.academic.util.StdOutUtil;
import dcd.academic.util.StringUtil;

import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;

public class BtwPublication {
	
	public static final int NUM = 20;
	
	public static void main(String[] args) throws IOException{
		BtwPublication bp = new BtwPublication();
		//bp.updatePublicationForComma();
		PageRank pageRank = new PageRank(bp.getPagerankS("random"));
		pageRank.doPagerank();
	}
	
	public double getDist(String pub1, String pub2) throws IOException {
		if (pub1 != null && pub2 != null) {
			ArrayList<String> doc1 = StringUtil.getTokens(pub1);
			ArrayList<String> doc2 = StringUtil.getTokens(pub2);
			return CosineDis.getSimilarity(doc1, doc2);
		} else {
			return 0;
		}
	}
	
//	public List<Map<String, String>> getPubs(String name) {
//		
//	}
	
	public List<List<Double>> getPagerankS(String text) throws IOException {
		SolrjHelper helper = new SolrjHelper(1);
		List<String> pubs = helper.getPubsByTitle(text, 0, NUM);
		List<List<Double>> s = new ArrayList<List<Double>>();
		for (String pub : pubs) {
			List<Double> tmp_row = new ArrayList<Double>();
			double total = 0.0;
			for (String other : pubs) {
				if (!pub.equals(other)) {
					double tmp = getDist(pub, other);
					tmp_row.add(tmp);
					total += tmp;
				} else {
					tmp_row.add(0.0);
				}
			}
			s.add(getNormalizedRow(tmp_row, total));
		}
		return s;
	}
	
	public List<Double> getNormalizedRow(List<Double> row, double d) {
		List<Double> res = new ArrayList<Double>();
		for (int i = 0; i < row.size(); i ++) {
			res.add(row.get(i) / d);
		}
		StdOutUtil.out(res.toString());
		return res;
	}
}

最後這個是PageRank類,部分引數可以自己再設定:

[java] view plaincopyprint?
  1. package dcd.academic.recommend;  
  2. import java.util.ArrayList;  
  3. import java.util.List;  
  4. import java.util.Random;  
  5. import dcd.academic.util.StdOutUtil;  
  6. publicclass PageRank {  
  7. privatestaticfinaldouble ALPHA = 0.85;  
  8. privatestaticfinaldouble DISTANCE = 0.0000001;  
  9. privatestaticfinaldouble MUL = 10;  
  10. publicstaticint SIZE;  
  11. publicstatic List<List<Double>> s;  
  12.     PageRank(List<List<Double>> s) {  
  13. this.SIZE = s.get(0).size();  
  14. this.s = s;  
  15.     }  
  16. publicstaticvoid doPagerank() {  
  17.         List<Double> q = new ArrayList<Double>();  
  18. for (int i = 0; i < SIZE; i ++) {  
  19.             q.add(new Random().nextDouble()*MUL);  
  20.         }  
  21.         System.out.println("初始的向量q為:");  
  22.         printVec(q);  
  23.         System.out.println("初始的矩陣G為:");  
  24.         printMatrix(getG(ALPHA));  
  25.         List<Double> pageRank = calPageRank(q, ALPHA);  
  26.         System.out.println("PageRank為:");  
  27.         printVec(pageRank);  
  28.         System.out.println();  
  29.     }  
  30. /** 
  31.      * 列印輸出一個矩陣 
  32.      *  
  33.      * @param m 
  34.      */
  35. publicstaticvoid printMatrix(List<List<Double>> m) {  
  36. for (int i = 0; i < m.size(); i++) {  
  37. for (int j = 0; j < m.get(i).size(); j++) {  
  38.                 System.out.print(m.get(i).get(j) + ", ");  
  39.             }  
  40.             System.out.println();  
  41.         }  
  42.     }  
  43. /** 
  44.      * 列印輸出一個向量 
  45.      *  
  46.      * @param v 
  47.      */
  48. publicstaticvoid printVec(List<Double> v) {  
  49. for (int i = 0; i < v.size(); i++) {  
  50.             System.out.print(v.get(i) + ", ");  
  51.         }  
  52.         System.out.println();  
  53.     }  
  54. /** 
  55.      * 獲得一個初始的隨機向量q 
  56.      *  
  57.      * @param n 
  58.      *            向量q的維數 
  59.      * @return 一個隨機的向量q,每一維是0-5之間的隨機數 
  60.      */
  61. publicstatic List<Double> getInitQ(int n) {  
  62.         Random random = new Random();  
  63.         List<Double> q = new ArrayList<Double>();  
  64. for (int i = 0; i < n; i++) {  
  65.             q.add(new Double(5 * random.nextDouble()));  
  66.         }  
  67. return q;  
  68.     }  
  69. /** 
  70.      * 計算兩個向量的距離 
  71.      *  
  72.      * @param q1 
  73.      *            第一個向量 
  74.      * @param q2 
  75.      *            第二個向量 
  76.      * @return 它們的距離 
  77.      */
  78. publicstaticdouble calDistance(List<Double> q1, List<Double> q2) {  
  79. double sum = 0;  
  80. if (q1.size() != q2.size()) {  
  81. return -1;  
  82.         }  
  83. for (int i = 0; i < q1.size(); i++) {  
  84.             sum += Math.pow(q1.get(i).doubleValue() - q2.get(i).doubleValue(),  
  85. 2);  
  86.         }  
  87. return Math.sqrt(sum);  
  88.     }  
  89. /** 
  90.      * 計算pagerank 
  91.      *  
  92.      * @param q1 
  93.      *            初始向量 
  94.      * @param a 
  95.      *            alpha的值 
  96.      * @return pagerank的結果 
  97.      */
  98. publicstatic List<Double> calPageRank(List<Double> q1, double a) {  
  99.         List<List<Double>> g = getG(a);  
  100.         List<Double> q = null;  
  101. while (true) {  
  102.             q = vectorMulMatrix(g, q1);  
  103. double dis = calDistance(q, q1);  
  104.             System.out.println(dis);  
  105. if (dis <= DISTANCE) {  
  106.                 System.out.println("q1:");  
  107.                 printVec(q1);  
  108.                 System.out.println("q:");  
  109.                 printVec(q);  
  110. break;  
  111.             }  
  112.             q1 = q;  
  113.         }  
  114. return q;  
  115.     }  
  116. /** 
  117.      * 計算獲得初始的G矩陣 
  118.      *  
  119.      * @param a 
  120.      *            為alpha的值,0.85 
  121.      * @return 初始矩陣G 
  122.      */
  123. publicstatic List<List<Double>> getG(double a) {  
  124.         List<List<Double>> aS = numberMulMatrix(s, a);  
  125.         List<List<Double>> nU = numberMulMatrix(getU(), (1 - a) / SIZE);  
  126.         List<List<Double>> g = addMatrix(aS, nU);  
  127. return g;  
  128.     }  
  129. /** 
  130.      * 計算一個矩陣乘以一個向量 
  131.      *  
  132.      * @param m 
  133.      *            一個矩陣 
  134.      * @param v 
  135.      *            一個向量 
  136.      * @return 返回一個新的向量 
  137.      */
  138. publicstatic List<Double> vectorMulMatrix(List<List<Double>> m,  
  139.             List<Double> v) {  
  140. if (m == null || v == null || m.size() <= 0
  141.                 || m.get(0).size() != v.size()) {  
  142. returnnull;  
  143.         }  
  144.         List<Double> list = new ArrayList<Double>();  
  145. for (int i = 0; i < m.size(); i++) {  
  146. double sum = 0;  
  147. for (int j = 0; j < m.get(i).size(); j++) {  
  148. double temp = m.get(i).get(j).doubleValue()  
  149.                         * v.get(j).doubleValue();  
  150.                 sum += temp;  
  151.             }  
  152.             list.add(sum);  
  153.         }  
  154. return list;  
  155.     }  
  156. /** 
  157.      * 計算兩個矩陣的和 
  158.      *  
  159.      * @param list1 
  160.      *            第一個矩陣 
  161.      * @param list2 
  162.      *            第二個矩陣 
  163.      * @return 兩個矩陣的和 
  164.      */
  165. publicstatic List<List<Double>> addMatrix(List<List<Double>> list1,  
  166.             List<List<Double>> list2) {  
  167.         List<List<Double>> list = new ArrayList<List<Double>>();  
  168. if (list1.size() != list2.size() || list1.size() <= 0
  169.                 || list2.size() <= 0) {  
  170. returnnull;  
  171.         }  
  172. for (int i = 0; i < list1.size(); i++) {  
  173.             list.add(new ArrayList<Double>());  
  174. for (int j = 0; j < list1.get(i).size(); j++) {  
  175. double temp = list1.get(i).get(j).doubleValue()  
  176.                         + list2.get(i).get(j).doubleValue();  
  177.                 list.get(i).add(new Double(temp));  
  178.             }  
  179.         }  
  180. return list;  
  181.     }  
  182. /** 
  183.      * 計算一個數乘以矩陣 
  184.      *  
  185.      * @param s 
  186.      *            矩陣s 
  187.      * @param a 
  188.      *            double型別的數 
  189.      * @return 一個新的矩陣 
  190.      */
  191. publicstatic List<List<Double>> numberMulMatrix(List<List<Double>> s,  
  192. double a) {  
  193.         List<List<Double>> list = new ArrayList<List<Double>>();  
  194. for (int i = 0; i < s.size(); i++) {  
  195.             list.add(new ArrayList<Double>());  
  196. for (int j = 0; j < s.get(i).size(); j++) {  
  197. double temp = a * s.get(i).get(j).doubleValue();  
  198.                 list.get(i).add(new Double(temp));  
  199.             }  
  200.         }  
  201. return list;  
  202.     }  
  203. /** 
  204.      * 初始化U矩陣,全1 
  205.      *  
  206.      * @return U 
  207.      */
  208. publicstatic List<List<Double>> getU() {  
  209.         List<Double> row = new ArrayList<Double>();  
  210. for (int i = 0; i < SIZE; i ++) {  
  211.             row.add(new Double(1));  
  212.         }  
  213.         List<List<Double>> s = new ArrayList<List<Double>>();  
  214. for (int j = 0; j < SIZE; j ++) {  
  215.             s.add(row);  
  216.         }  
  217. return s;  
  218.     }  
  219. }  
package dcd.academic.recommend;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import dcd.academic.util.StdOutUtil;

public class PageRank {
	private static final double ALPHA = 0.85;
	private static final double DISTANCE = 0.0000001;
	private static final double MUL = 10;
	
	public static int SIZE;
	public static List<List<Double>> s;
	
	PageRank(List<List<Double>> s) {
		this.SIZE = s.get(0).size();
		this.s = s;
	}
	
	public static void doPagerank() {
		List<Double> q = new ArrayList<Double>();
		for (int i = 0; i < SIZE; i ++) {
			q.add(new Random().nextDouble()*MUL);
		}
		System.out.println("初始的向量q為:");
		printVec(q);
		System.out.println("初始的矩陣G為:");
		printMatrix(getG(ALPHA));
		List<Double> pageRank = calPageRank(q, ALPHA);
		System.out.println("PageRank為:");
		printVec(pageRank);
		System.out.println();
	}

	/**
	 * 列印輸出一個矩陣
	 * 
	 * @param m
	 */
	public static void printMatrix(List<List<Double>> m) {
		for (int i = 0; i < m.size(); i++) {
			for (int j = 0; j < m.get(i).size(); j++) {
				System.out.print(m.get(i).get(j) + ", ");
			}
			System.out.println();
		}
	}

	/**
	 * 列印輸出一個向量
	 * 
	 * @param v
	 */
	public static void printVec(List<Double> v) {
		for (int i = 0; i < v.size(); i++) {
			System.out.print(v.get(i) + ", ");
		}
		System.out.println();
	}

	/**
	 * 獲得一個初始的隨機向量q
	 * 
	 * @param n
	 *            向量q的維數
	 * @return 一個隨機的向量q,每一維是0-5之間的隨機數
	 */
	public static List<Double> getInitQ(int n) {
		Random random = new Random();
		List<Double> q = new ArrayList<Double>();
		for (int i = 0; i < n; i++) {
			q.add(new Double(5 * random.nextDouble()));
		}
		return q;
	}

	/**
	 * 計算兩個向量的距離
	 * 
	 * @param q1
	 *            第一個向量
	 * @param q2
	 *            第二個向量
	 * @return 它們的距離
	 */
	public static double calDistance(List<Double> q1, List<Double> q2) {
		double sum = 0;

		if (q1.size() != q2.size()) {
			return -1;
		}

		for (int i = 0; i < q1.size(); i++) {
			sum += Math.pow(q1.get(i).doubleValue() - q2.get(i).doubleValue(),
					2);
		}
		return Math.sqrt(sum);
	}

	/**
	 * 計算pagerank
	 * 
	 * @param q1
	 *            初始向量
	 * @param a
	 *            alpha的值
	 * @return pagerank的結果
	 */
	public static List<Double> calPageRank(List<Double> q1, double a) {

		List<List<Double>> g = getG(a);
		List<Double> q = null;
		while (true) {
			q = vectorMulMatrix(g, q1);
			double dis = calDistance(q, q1);
			System.out.println(dis);
			if (dis <= DISTANCE) {
				System.out.println("q1:");
				printVec(q1);
				System.out.println("q:");
				printVec(q);
				break;
			}
			q1 = q;
		}
		return q;
	}

	/**
	 * 計算獲得初始的G矩陣
	 * 
	 * @param a
	 *            為alpha的值,0.85
	 * @return 初始矩陣G
	 */
	public static List<List<Double>> getG(double a) {
		List<List<Double>> aS = numberMulMatrix(s, a);
		List<List<Double>> nU = numberMulMatrix(getU(), (1 - a) / SIZE);
		List<List<Double>> g = addMatrix(aS, nU);
		return g;
	}

	/**
	 * 計算一個矩陣乘以一個向量
	 * 
	 * @param m
	 *            一個矩陣
	 * @param v
	 *            一個向量
	 * @return 返回一個新的向量
	 */
	public static List<Double> vectorMulMatrix(List<List<Double>> m,
			List<Double> v) {
		if (m == null || v == null || m.size() <= 0
				|| m.get(0).size() != v.size()) {
			return null;
		}

		List<Double> list = new ArrayList<Double>();
		for (int i = 0; i < m.size(); i++) {
			double sum = 0;
			for (int j = 0; j < m.get(i).size(); j++) {
				double temp = m.get(i).get(j).doubleValue()
						* v.get(j).doubleValue();
				sum += temp;
			}
			list.add(sum);
		}

		return list;
	}

	/**
	 * 計算兩個矩陣的和
	 * 
	 * @param list1
	 *            第一個矩陣
	 * @param list2
	 *            第二個矩陣
	 * @return 兩個矩陣的和
	 */
	public static List<List<Double>> addMatrix(List<List<Double>> list1,
			List<List<Double>> list2) {
		List<List<Double>> list = new ArrayList<List<Double>>();
		if (list1.size() != list2.size() || list1.size() <= 0
				|| list2.size() <= 0) {
			return null;
		}
		for (int i = 0; i < list1.size(); i++) {
			list.add(new ArrayList<Double>());
			for (int j = 0; j < list1.get(i).size(); j++) {
				double temp = list1.get(i).get(j).doubleValue()
						+ list2.get(i).get(j).doubleValue();
				list.get(i).add(new Double(temp));
			}
		}
		return list;
	}

	/**
	 * 計算一個數乘以矩陣
	 * 
	 * @param s
	 *            矩陣s
	 * @param a
	 *            double型別的數
	 * @return 一個新的矩陣
	 */
	public static List<List<Double>> numberMulMatrix(List<List<Double>> s,
			double a) {
		List<List<Double>> list = new ArrayList<List<Double>>();

		for (int i = 0; i < s.size(); i++) {
			list.add(new ArrayList<Double>());
			for (int j = 0; j < s.get(i).size(); j++) {
				double temp = a * s.get(i).get(j).doubleValue();
				list.get(i).add(new Double(temp));
			}
		}
		return list;
	}

	/**
	 * 初始化U矩陣,全1
	 * 
	 * @return U
	 */
	public static List<List<Double>> getU() {
		List<Double> row = new ArrayList<Double>();
		for (int i = 0; i < SIZE; i ++) {
			row.add(new Double(1));
		}

		List<List<Double>> s = new ArrayList<List<Double>>();
		for (int j = 0; j < SIZE; j ++) {
			s.add(row);
		}
		return s;
	}
}

下面是我一次實驗結果的資料,我設定了五分文字,這樣看起來比較短:

[html] view plaincopyprint?
  1. [0.0, 0.09968643574761415, 0.2601130421632277, 0.31094706119099713, 0.32925346089816093]  
  2. [0.1315115598803241, 0.0, 0.23650307622882252, 0.2827229880685279, 0.34926237582232544]  
  3. [0.13521235055030142, 0.09318868159350341, 0.0, 0.3996835314966943, 0.3719154363595009]  
  4. [0.1389453620825689, 0.0957614822411479, 0.34357346750710194, 0.0, 0.4217196881691813]  
  5. [0.14612484353723476, 0.11749453142051332, 0.31752920814285096, 0.4188514168994011, 0.0]  
  6. 初始的向量q為:  
  7. 8.007763265073303, 3.1232982446687387, 1.1722525763669134, 5.906625842576609, 9.019220483814852,   
  8. 初始的矩陣G為:  
  9. 0.030000000000000006, 0.11473347038547205, 0.2510960858387436, 0.2943050020123476, 0.30986544176343683,   
  10. 0.14178482589827548, 0.030000000000000006, 0.23102761479449913, 0.2703145398582487, 0.3268730194489766,   
  11. 0.1449304979677562, 0.10921037935447789, 0.030000000000000006, 0.36973100177219015, 0.3461281209055758,   
  12. 0.14810355777018358, 0.11139725990497573, 0.3220374473810367, 0.030000000000000006, 0.38846173494380415,   
  13. 0.15420611700664955, 0.12987035170743633, 0.29989982692142336, 0.38602370436449096, 0.030000000000000006,   
  14. 8.215210604296416  
  15. 2.1786836521210637  
  16. 0.6343362349619535  
  17. 0.19024536572818584  
  18. 0.05836227176176904  
  19. 0.018354791916908083  
  20. 0.0059297512567364945  
  21. 0.0019669982458251243  
  22. 6.679891158687752E-4  
  23. 2.312017647733628E-4  
  24. 8.117199104238135E-5  
  25. 2.8787511843006215E-5  
  26. 1.0279598478348542E-5  
  27. 3.6872987746593366E-6  
  28. 1.3264993458811192E-6  
  29. 4.780938295685138E-7  
  30. 1.7251588746973008E-7  
  31. 6.229666266632005E-8  
  32. q1:  
  33. 5.62674207030434, 5.626742074589739, 5.626742063777632, 5.626742101012727, 5.626742037269133,   
  34. q:  
  35. 5.626742067958352, 5.626742066427658, 5.626742070495978, 5.626742056768215, 5.626742079766638,   
  36. PageRank為:  
  37. 5.626742067958352, 5.626742066427658, 5.626742070495978, 5.626742056768215, 5.626742079766638,  

相關推薦

java中利用hanlp比較文字相似的步驟

使用 HanLP - 漢語言處理包 來處理,他能處理很多事情,如分詞、呼叫分詞器、命名實體識別、人名識別、地名識別、詞性識別、篇章

如何比較文字相似 .

目標 嘗試了一下把PageRank演算法結合了文字相似度計算。直覺上是想把一個list裡,和大家都比較靠攏的文字可能最後的PageRank值會比較大。因為如果最後計算的PageRank值大,說明有比較多的文字和他的相似度值比較高,或者有更多的文字向他靠攏。這樣是不是就可以得到一些相對核心的文字,或者相對代表

JAVA比較張圖相似

利用直方圖原理比較2張圖片相似度 package com.uiwho.com; import javax.imageio.*; import java.awt.image.*; import java.awt.*;//Color import java.io.*; publi

DOS命令比較文字檔案txt的內容差異

將需要比較的文字檔案放置在同一個資料夾下。 如把a.txt、b.txt、c.txt放在資料夾/home/q/compare下。 1、開啟windows,輸入cmd,開啟DOS視窗。進入檔案目錄/home/q/compare下。 2、如果比較a.txt和b.txt兩個檔案。輸

檔案輸入輸出 c++ 比較文字內容

先看一個小程式: #include <fstream> #include <iostream> using namespace std; int main(){ ofstream op("text1.txt"); o

計算字串相似的演算法

該方法是使用的Levenshtein演算法的一個實現。  簡單介紹下Levenshtein Distance(LD):LD 可能衡量兩字串的相似性。它們的距離就是一個字串轉換成那一個字串過程中的新增、刪除、修改數值。     舉例: 如果str1="test",st

Python 連接MongoDB並比較字符串相似的簡單示例

tab diff port pycharm 步驟 mil microsoft pymongo tro 本文介紹一個示例:使用 pymongo 連接 MongoDB,查詢MongoDB中的 字符串 記錄,並比較字符串之間的相似度。 一,Python連接MongoDB 大致步驟

C#比較字符串的相似【轉】

出現 href 單詞 mar 情況 base 程序代碼 RR 字符 原文地址:http://www.2cto.com/kf/201202/121170.html 我們在做數據系統的時候,經常會用到模糊搜索,但是,數據庫提供的模糊搜索並不具備按照相關度進行排序的功能

用docsim/doc2vec/LSH比較文件之間的相似

在我們做文字處理的時候,經常需要對兩篇文件是否相似做處理或者根據輸入的文件,找出最相似的文件。 如需轉載,請註明出處。 幸好gensim提供了這樣的工具,具體的處理思路如下,對於中文文字的比較,先需要做分詞處理,根據分詞的結果生成一個字典,然後再根據字典把原文件轉化成向量。

opencv java小應用:比較圖片的相似

package com.company; import org.opencv.core.*; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import org.opencv.objdetect.Casc

liunx-shell比較資料夾下的文字內容

兩個資料夾下面的檔案個數及其名稱完全一樣,但是內容有的可能不一樣,這個指令碼遍歷資料夾下的所有子資料夾,包括巢狀多層的,然後使用linux系統的diff命令對兩個名稱一樣的檔案進行比較,指令碼如下: #!/bin/sh if [ $# -ne 2 ] then    

python張圖相似比較

#!/usr/bin/python # -*- coding: utf-8 -*- import cv2   import numpy as np   from PIL import Image,ImageFilter def make_regalur_image(img,

文字相似計算的幾距離公式(歐氏距離、餘弦相似、Jaccard距離、編輯距離)

本文主要講一下文字相似度計算的幾個距離公式,主要包括:歐氏距離、餘弦相似度、Jaccard距離、編輯距離。 距離計算在文字很多場景下都可以用到,比如:聚類、K近鄰、機器學習中的特徵、文字相似度等等。接下來就一一介紹一下: 假設兩個文字X=(x1, x2, x3,...xn)

java程式碼比較字串的相似程度

直接上程式碼,相信你一看就會用。 public class Test { public static void main(String[] args) { String s

TF-IDF比較文字相似

文字相似度 TF-IDF 演算法 如果某個詞在給定文件中很少出現,但是在給定文件中的某一篇文章中出現的次數很大, 該詞在很大程度上反映了該文章的特性,我們稱該詞為這篇文章的關鍵字 參考連結:http://www.ruanyifeng.com/blog/2013/

shell腳本-比較整數大小

shell開發shell腳本分別實現以腳本傳參以及read讀入的方式比較2個整數大小。用條件表達式(禁止if)進行判斷並以屏幕輸出的方式提醒用戶比較結果。註意:一共是開發2個腳本。當用腳本傳參以及read讀入的方式需要對變量是否為數字、並且傳參個數不對給予提示。read讀入方式#!/bin/bash read

計算張圖片相似的方法總結

title rac 相似度 無法 tween hive any 明顯 embed python工具包-pyssim 簡介 python工具包,用來計算圖像之間的結構相似性 (Structural Similarity Image Metric: SSIM)。結構相似性介紹

比較整數的大小

比較兩個整數的大小 linux test if shell腳本練習比較兩個整數的大小說明:使用if條件從句比較兩個整數的大小。使用傳參方法時,需要對傳參個數及傳入的參數是否是整數進行判斷。思路第一,先判斷輸入的是兩個數,對輸入個數進行判斷;第二,再判斷輸入的兩個數是整數;第三,最後比較兩個數的大小。

LR中用C語言比較字符串變量

nat [] 變量 end put tar 字符串 init rmi 以下腳本,定義兩個一樣的字符數組,對比後,打印出result的值: Action() { int result; char string1[] = "We can see the st

比較對象屬性及屬性值

bject ace ive args main authorize code pre cer import java.lang.reflect.Method; private static Object getFieldValue(Object thisClass, St