本文实例讲述了.NET下文本相似度算法余弦定理和SimHash浅析及应用。分享给大家供大家参考。具体分析如下:
余弦相似性
原理:首先我们先把两段文本分词,列出来所有单词,其次我们计算每个词语的词频,最后把词语转换为向量,这样我们就只需要计算两个向量的相似程度.
我们简单表述如下
文本1:我/爱/北京/天安门/ 经过分词求词频得出向量(伪向量) [1,1,1,1]
文本2:我们/都爱/北京/天安门/ 经过分词求词频得出向量(伪向量) [1,0,1,2]
我们可以把它们想象成空间中的两条线段,都是从原点([0, 0, ...])出发,指向不同的方向。两条线段之间形成一个夹角,如果夹角为0度,意味着方向相同、线段重合;如果夹角为90度,意味着形成直角,方向完全不相似;如果夹角为180度,意味着方向正好相反。因此,我们可以通过夹角的大小,来判断向量的相似程度。夹角越小,就代表越相似。
C#核心算法:
public class TFIDFMeasure { private string[] _docs; private string[][] _ngramDoc; private int _numDocs=0; private int _numTerms=0; private ArrayList _terms; private int[][] _termFreq; private float[][] _termWeight; private int[] _maxTermFreq; private int[] _docFreq; public class TermVector { public static float ComputeCosineSimilarity(float[] vector1, float[] vector2) { if (vector1.Length != vector2.Length) throw new Exception("DIFER LENGTH"); float denom=(VectorLength(vector1) * VectorLength(vector2)); if (denom == 0F) return 0F; else return (InnerProduct(vector1, vector2) / denom); } public static float InnerProduct(float[] vector1, float[] vector2) { if (vector1.Length != vector2.Length) throw new Exception("DIFFER LENGTH ARE NOT ALLOWED"); float result=0F; for (int i=0; i < vector1.Length; i++) result += vector1[i] * vector2[i]; return result; } public static float VectorLength(float[] vector) { float sum=0.0F; for (int i=0; i < vector.Length; i++) sum=sum + (vector[i] * vector[i]); return (float)Math.Sqrt(sum); } } private IDictionary _wordsIndex=new Hashtable() ; public TFIDFMeasure(string[] documents) { _docs=documents; _numDocs=documents.Length ; MyInit(); } private void GeneratNgramText() { } private ArrayList GenerateTerms(string[] docs) { ArrayList uniques=new ArrayList() ; _ngramDoc=new string[_numDocs][] ; for (int i=0; i < docs.Length ; i++) { Tokeniser tokenizer=new Tokeniser() ; string[] words=tokenizer.Partition(docs[i]); for (int j=0; j < words.Length ; j++) if (!uniques.Contains(words[j]) ) uniques.Add(words[j]) ; } return uniques; }private static object AddElement(IDictionary collection, object key, object newValue) { object element=collection[key]; collection[key]=newValue; return element; } private int GetTermIndex(string term) { object index=_wordsIndex[term]; if (index == null) return -1; return (int) index; } private void MyInit() { _terms=GenerateTerms (_docs ); _numTerms=_terms.Count ; _maxTermFreq=new int[_numDocs] ; _docFreq=new int[_numTerms] ; _termFreq =new int[_numTerms][] ; _termWeight=new float[_numTerms][] ; for(int i=0; i < _terms.Count ; i++) { _termWeight[i]=new float[_numDocs] ; _termFreq[i]=new int[_numDocs] ; AddElement(_wordsIndex, _terms[i], i); } GenerateTermFrequency (); GenerateTermWeight(); } private float Log(float num) { return (float) Math.Log(num) ;//log2 } private void GenerateTermFrequency() { for(int i=0; i < _numDocs ; i++) { string curDoc=_docs[i]; IDictionary freq=GetWordFrequency(curDoc); IDictionaryEnumerator enums=freq.GetEnumerator() ; _maxTermFreq[i]=int.MinValue ; while (enums.MoveNext()) { string word=(string)enums.Key; int wordFreq=(int)enums.Value ; int termIndex=GetTermIndex(word); _termFreq [termIndex][i]=wordFreq; _docFreq[termIndex] ++; if (wordFreq > _maxTermFreq[i]) _maxTermFreq[i]=wordFreq; } } }
private void GenerateTermWeight() { for(int i=0; i < _numTerms ; i++) { for(int j=0; j < _numDocs ; j++) _termWeight[i][j]=ComputeTermWeight (i, j); } } private float GetTermFrequency(int term, int doc) { int freq=_termFreq [term][doc]; int maxfreq=_maxTermFreq[doc]; return ( (float) freq/(float)maxfreq ); } private float GetInverseDocumentFrequency(int term) { int df=_docFreq[term]; return Log((float) (_numDocs) / (float) df ); } private float ComputeTermWeight(int term, int doc) { float tf=GetTermFrequency (term, doc); float idf=GetInverseDocumentFrequency(term); return tf * idf; } private float[] GetTermVector(int doc) { float[] w=new float[_numTerms] ; for (int i=0; i < _numTerms; i++) w[i]=_termWeight[i][doc]; return w; } public float GetSimilarity(int doc_i, int doc_j) { float[] vector1=GetTermVector (doc_i); float[] vector2=GetTermVector (doc_j); return TermVector.ComputeCosineSimilarity(vector1, vector2); } private IDictionary GetWordFrequency(string input) { string convertedInput=input.ToLower() ; Tokeniser tokenizer=new Tokeniser() ; String[] words=tokenizer.Partition(convertedInput); Array.Sort(words); String[] distinctWords=GetDistinctWords(words); IDictionary result=new Hashtable(); for (int i=0; i < distinctWords.Length; i++) { object tmp; tmp=CountWords(distinctWords[i], words); result[distinctWords[i]]=tmp; } return result; } private string[] GetDistinctWords(String[] input) { if (input == null) return new string[0]; else { ArrayList list=new ArrayList() ; for (int i=0; i < input.Length; i++) if (!list.Contains(input[i])) // N-GRAM SIMILARITY? list.Add(input[i]); return Tokeniser.ArrayListToArray(list) ; } }
private int CountWords(string word, string[] words) { int itemIdx=Array.BinarySearch(words, word); if (itemIdx > 0) while (itemIdx > 0 && words[itemIdx].Equals(word)) itemIdx--; int count=0; while (itemIdx < words.Length && itemIdx >= 0) { if (words[itemIdx].Equals(word)) count++; itemIdx++; if (itemIdx < words.Length) if (!words[itemIdx].Equals(word)) break; } return count; } }
希望本文所述对大家的.net程序设计有所帮助。
问题内容: 我计算了两个文档的tf / idf值。以下是tf / idf值: 这些文件就像: 如何使用这些值来计算余弦相似度? 我知道我应该计算点积,然后找到距离并除以点积。如何使用我的值来计算? 还有一个问题: 两个文档的字数相同是否重要? 问题答案: a * b是点积 一些细节: 是。在某种程度上,a和b必须具有相同的长度。但是a和b通常具有稀疏表示,您只需要存储非零条目,就可以更快地计算范数
问题内容: 假设您在数据库中按以下方式构造了一个表: 为了清楚起见,应输出: 请注意,由于向量存储在数据库中,因此我们仅需要存储非零条目。在此示例中,我们只有两个向量$ v_ {99} =(4,3,4,0)$和$ v_ {1234} =(0,5,2,3)$都在$ \ mathbb {R}中^ 4 $。 这些向量的余弦相似度应为$ \ displaystyle \ frac {23} {\ sqrt
本文向大家介绍余弦相似性计算及python代码实现过程解析,包括了余弦相似性计算及python代码实现过程解析的使用技巧和注意事项,需要的朋友参考一下 A:西米喜欢健身 B:超超不爱健身,喜欢打游戏 step1:分词 A:西米/喜欢/健身 B:超超/不/喜欢/健身,喜欢/打/游戏 step2:列出两个句子的并集 西米/喜欢/健身/超超/不/打/游戏 step3:计算词频向量 A:[1,1,1,0,
本文向大家介绍Python 余弦相似度与皮尔逊相关系数 计算实例,包括了Python 余弦相似度与皮尔逊相关系数 计算实例的使用技巧和注意事项,需要的朋友参考一下 夹角余弦(Cosine) 也可以叫余弦相似度。 几何中夹角余弦可用来衡量两个向量方向的差异,机器学习中借用这一概念来衡量样本向量之间的差异。 (1)在二维空间中向量A(x1,y1)与向量B(x2,y2)的夹角余弦公式: (2) 两个n维
我试图用余弦相似性来找出两个文本文件的相似性。当我提供文本时,我可以发现这一点。但我想在阅读完电脑中的文本文件后得到结果。
问题内容: 如何找到向量之间的余弦相似度? 我需要找到相似性来衡量两行文本之间的相关性。 例如,我有两个句子: 用户界面系统 用户界面机 …及其在tF-idf之后的向量,然后使用LSI进行标准化,例如 和。 如何测量这些向量之间的相似性? 问题答案: 我最近在大学的信息检索部门做了一些tf-idf的工作。我使用了这种余弦相似度方法,该方法使用Jama:Java Matrix Package 。 有