Similarity.cs
上传用户:zhangkuixh
上传日期:2013-09-30
资源大小:5473k
文件大小:13k
源码类别:

搜索引擎

开发平台:

C#

  1. /*
  2.  * Copyright 2004 The Apache Software Foundation
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  * 
  8.  * http://www.apache.org/licenses/LICENSE-2.0
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. using System;
  17. using Field = Lucene.Net.Documents.Field;
  18. using IndexReader = Lucene.Net.Index.IndexReader;
  19. using IndexWriter = Lucene.Net.Index.IndexWriter;
  20. using Term = Lucene.Net.Index.Term;
  21. using SmallFloat = Lucene.Net.Util.SmallFloat;
  22. namespace Lucene.Net.Search
  23. {
  24. /// <summary>Expert: Scoring API.
  25. /// <p>Subclasses implement search scoring.
  26. /// 
  27. /// <p>The score of query <code>q</code> for document <code>d</code> is defined
  28. /// in terms of these methods as follows:
  29. /// 
  30. /// <table cellpadding="0" cellspacing="0" border="0">
  31. /// <tr>
  32. /// <td valign="middle" align="right" rowspan="2">score(q,d) =<br></td>
  33. /// <td valign="middle" align="center">
  34. /// <big><big><big><big><big>&Sigma;</big></big></big></big></big></td>
  35. /// <td valign="middle"><small>
  36. /// ( {@link #Tf(int) tf}(t in d) *
  37. /// {@link #Idf(Term,Searcher) idf}(t)^2 *
  38. /// {@link Query#getBoost getBoost}(t in q) *
  39. /// {@link Field#getBoost getBoost}(t.field in d) *
  40. /// {@link #LengthNorm(String,int) lengthNorm}(t.field in d) )
  41. /// </small></td>
  42. /// <td valign="middle" rowspan="2">&nbsp;*
  43. /// {@link #Coord(int,int) coord}(q,d) *
  44. /// {@link #QueryNorm(float) queryNorm}(sumOfSqaredWeights)
  45. /// </td>
  46. /// </tr>
  47. /// <tr>
  48. /// <td valign="top" align="right">
  49. /// <small>t in q</small>
  50. /// </td>
  51. /// </tr>
  52. /// </table>
  53. /// 
  54. /// <p> where
  55. /// 
  56. /// <table cellpadding="0" cellspacing="0" border="0">
  57. /// <tr>
  58. /// <td valign="middle" align="right" rowspan="2">sumOfSqaredWeights =<br></td>
  59. /// <td valign="middle" align="center">
  60. /// <big><big><big><big><big>&Sigma;</big></big></big></big></big></td>
  61. /// <td valign="middle"><small>
  62. /// ( {@link #Idf(Term,Searcher) idf}(t) *
  63. /// {@link Query#getBoost getBoost}(t in q) )^2
  64. /// </small></td>
  65. /// </tr>
  66. /// <tr>
  67. /// <td valign="top" align="right">
  68. /// <small>t in q</small>
  69. /// </td>
  70. /// </tr>
  71. /// </table>
  72. /// 
  73. /// <p> Note that the above formula is motivated by the cosine-distance or dot-product
  74. /// between document and query vector, which is implemented by {@link DefaultSimilarity}.
  75. /// 
  76. /// </summary>
  77. /// <seealso cref="SetDefault(Similarity)">
  78. /// </seealso>
  79. /// <seealso cref="IndexWriter.SetSimilarity(Similarity)">
  80. /// </seealso>
  81. /// <seealso cref="Searcher.SetSimilarity(Similarity)">
  82. /// </seealso>
  83. [Serializable]
  84. public abstract class Similarity
  85. {
  86. /// <summary>The Similarity implementation used by default. </summary>
  87. private static Similarity defaultImpl = new DefaultSimilarity();
  88. /// <summary>Set the default Similarity implementation used by indexing and search
  89. /// code.
  90. /// 
  91. /// </summary>
  92. /// <seealso cref="Searcher.SetSimilarity(Similarity)">
  93. /// </seealso>
  94. /// <seealso cref="IndexWriter.SetSimilarity(Similarity)">
  95. /// </seealso>
  96. public static void  SetDefault(Similarity similarity)
  97. {
  98. Similarity.defaultImpl = similarity;
  99. }
  100. /// <summary>Return the default Similarity implementation used by indexing and search
  101. /// code.
  102. /// 
  103. /// <p>This is initially an instance of {@link DefaultSimilarity}.
  104. /// 
  105. /// </summary>
  106. /// <seealso cref="Searcher.SetSimilarity(Similarity)">
  107. /// </seealso>
  108. /// <seealso cref="IndexWriter.SetSimilarity(Similarity)">
  109. /// </seealso>
  110. public static Similarity GetDefault()
  111. {
  112. return Similarity.defaultImpl;
  113. }
  114. /// <summary>Cache of decoded bytes. </summary>
  115. private static readonly float[] NORM_TABLE = new float[256];
  116. /// <summary>Decodes a normalization factor stored in an index.</summary>
  117. /// <seealso cref="EncodeNorm(float)">
  118. /// </seealso>
  119. public static float DecodeNorm(byte b)
  120. {
  121. return NORM_TABLE[b & 0xFF]; // & 0xFF maps negative bytes to positive above 127
  122. }
  123. /// <summary>Returns a table for decoding normalization bytes.</summary>
  124. /// <seealso cref="EncodeNorm(float)">
  125. /// </seealso>
  126. public static float[] GetNormDecoder()
  127. {
  128. return NORM_TABLE;
  129. }
  130. /// <summary>Computes the normalization value for a field given the total number of
  131. /// terms contained in a field.  These values, together with field boosts, are
  132. /// stored in an index and multipled into scores for hits on each field by the
  133. /// search code.
  134. /// 
  135. /// <p>Matches in longer fields are less precise, so implementations of this
  136. /// method usually return smaller values when <code>numTokens</code> is large,
  137. /// and larger values when <code>numTokens</code> is small.
  138. /// 
  139. /// <p>That these values are computed under {@link
  140. /// IndexWriter#AddDocument(Lucene.Net.document.Document)} and stored then using
  141. /// {@link #EncodeNorm(float)}.  Thus they have limited precision, and documents
  142. /// must be re-indexed if this method is altered.
  143. /// 
  144. /// </summary>
  145. /// <param name="fieldName">the name of the field
  146. /// </param>
  147. /// <param name="numTokens">the total number of tokens contained in fields named
  148. /// <i>fieldName</i> of <i>doc</i>.
  149. /// </param>
  150. /// <returns> a normalization factor for hits on this field of this document
  151. /// 
  152. /// </returns>
  153. /// <seealso cref="Field.SetBoost(float)">
  154. /// </seealso>
  155. public abstract float LengthNorm(System.String fieldName, int numTokens);
  156. /// <summary>Computes the normalization value for a query given the sum of the squared
  157. /// weights of each of the query terms.  This value is then multipled into the
  158. /// weight of each query term.
  159. /// 
  160. /// <p>This does not affect ranking, but rather just attempts to make scores
  161. /// from different queries comparable.
  162. /// 
  163. /// </summary>
  164. /// <param name="sumOfSquaredWeights">the sum of the squares of query term weights
  165. /// </param>
  166. /// <returns> a normalization factor for query weights
  167. /// </returns>
  168. public abstract float QueryNorm(float sumOfSquaredWeights);
  169. /// <summary>Encodes a normalization factor for storage in an index.
  170. /// 
  171. /// <p>The encoding uses a three-bit mantissa, a five-bit exponent, and
  172. /// the zero-exponent point at 15, thus
  173. /// representing values from around 7x10^9 to 2x10^-9 with about one
  174. /// significant decimal digit of accuracy.  Zero is also represented.
  175. /// Negative numbers are rounded up to zero.  Values too large to represent
  176. /// are rounded down to the largest representable value.  Positive values too
  177. /// small to represent are rounded up to the smallest positive representable
  178. /// value.
  179. /// 
  180. /// </summary>
  181. /// <seealso cref="Field.SetBoost(float)">
  182. /// </seealso>
  183. /// <seealso cref="SmallFloat">
  184. /// </seealso>
  185. public static byte EncodeNorm(float f)
  186. {
  187. return (byte) SmallFloat.FloatToByte315(f);
  188. }
  189. /// <summary>Computes a score factor based on a term or phrase's frequency in a
  190. /// document.  This value is multiplied by the {@link #Idf(Term, Searcher)}
  191. /// factor for each term in the query and these products are then summed to
  192. /// form the initial score for a document.
  193. /// 
  194. /// <p>Terms and phrases repeated in a document indicate the topic of the
  195. /// document, so implementations of this method usually return larger values
  196. /// when <code>freq</code> is large, and smaller values when <code>freq</code>
  197. /// is small.
  198. /// 
  199. /// <p>The default implementation calls {@link #Tf(float)}.
  200. /// 
  201. /// </summary>
  202. /// <param name="freq">the frequency of a term within a document
  203. /// </param>
  204. /// <returns> a score factor based on a term's within-document frequency
  205. /// </returns>
  206. public virtual float Tf(int freq)
  207. {
  208. return Tf((float) freq);
  209. }
  210. /// <summary>Computes the amount of a sloppy phrase match, based on an edit distance.
  211. /// This value is summed for each sloppy phrase match in a document to form
  212. /// the frequency that is passed to {@link #Tf(float)}.
  213. /// 
  214. /// <p>A phrase match with a small edit distance to a document passage more
  215. /// closely matches the document, so implementations of this method usually
  216. /// return larger values when the edit distance is small and smaller values
  217. /// when it is large.
  218. /// 
  219. /// </summary>
  220. /// <seealso cref="PhraseQuery.SetSlop(int)">
  221. /// </seealso>
  222. /// <param name="distance">the edit distance of this sloppy phrase match
  223. /// </param>
  224. /// <returns> the frequency increment for this match
  225. /// </returns>
  226. public abstract float SloppyFreq(int distance);
  227. /// <summary>Computes a score factor based on a term or phrase's frequency in a
  228. /// document.  This value is multiplied by the {@link #Idf(Term, Searcher)}
  229. /// factor for each term in the query and these products are then summed to
  230. /// form the initial score for a document.
  231. /// 
  232. /// <p>Terms and phrases repeated in a document indicate the topic of the
  233. /// document, so implementations of this method usually return larger values
  234. /// when <code>freq</code> is large, and smaller values when <code>freq</code>
  235. /// is small.
  236. /// 
  237. /// </summary>
  238. /// <param name="freq">the frequency of a term within a document
  239. /// </param>
  240. /// <returns> a score factor based on a term's within-document frequency
  241. /// </returns>
  242. public abstract float Tf(float freq);
  243. /// <summary>Computes a score factor for a simple term.
  244. /// 
  245. /// <p>The default implementation is:<pre>
  246. /// return idf(searcher.docFreq(term), searcher.maxDoc());
  247. /// </pre>
  248. /// 
  249. /// Note that {@link Searcher#MaxDoc()} is used instead of
  250. /// {@link IndexReader#NumDocs()} because it is proportional to
  251. /// {@link Searcher#DocFreq(Term)} , i.e., when one is inaccurate,
  252. /// so is the other, and in the same direction.
  253. /// 
  254. /// </summary>
  255. /// <param name="term">the term in question
  256. /// </param>
  257. /// <param name="searcher">the document collection being searched
  258. /// </param>
  259. /// <returns> a score factor for the term
  260. /// </returns>
  261. public virtual float Idf(Term term, Searcher searcher)
  262. {
  263. return Ldf(searcher.DocFreq(term), searcher.MaxDoc());
  264. }
  265. /// <summary>Computes a score factor for a phrase.
  266. /// 
  267. /// <p>The default implementation sums the {@link #Idf(Term,Searcher)} factor
  268. /// for each term in the phrase.
  269. /// 
  270. /// </summary>
  271. /// <param name="terms">the terms in the phrase
  272. /// </param>
  273. /// <param name="searcher">the document collection being searched
  274. /// </param>
  275. /// <returns> a score factor for the phrase
  276. /// </returns>
  277. public virtual float Idf(System.Collections.ICollection terms, Searcher searcher)
  278. {
  279. float idf = 0.0f;
  280. System.Collections.IEnumerator i = terms.GetEnumerator();
  281. while (i.MoveNext())
  282. {
  283. idf += Idf((Term) i.Current, searcher);
  284. }
  285. return idf;
  286. }
  287. /// <summary>Computes a score factor based on a term's document frequency (the number
  288. /// of documents which contain the term).  This value is multiplied by the
  289. /// {@link #Tf(int)} factor for each term in the query and these products are
  290. /// then summed to form the initial score for a document.
  291. /// 
  292. /// <p>Terms that occur in fewer documents are better indicators of topic, so
  293. /// implementations of this method usually return larger values for rare terms,
  294. /// and smaller values for common terms.
  295. /// 
  296. /// </summary>
  297. /// <param name="docFreq">the number of documents which contain the term
  298. /// </param>
  299. /// <param name="numDocs">the total number of documents in the collection
  300. /// </param>
  301. /// <returns> a score factor based on the term's document frequency
  302. /// </returns>
  303. public abstract float Ldf(int docFreq, int numDocs);
  304. /// <summary>Computes a score factor based on the fraction of all query terms that a
  305. /// document contains.  This value is multiplied into scores.
  306. /// 
  307. /// <p>The presence of a large portion of the query terms indicates a better
  308. /// match with the query, so implementations of this method usually return
  309. /// larger values when the ratio between these parameters is large and smaller
  310. /// values when the ratio between them is small.
  311. /// 
  312. /// </summary>
  313. /// <param name="overlap">the number of query terms matched in the document
  314. /// </param>
  315. /// <param name="maxOverlap">the total number of terms in the query
  316. /// </param>
  317. /// <returns> a score factor based on term overlap with the query
  318. /// </returns>
  319. public abstract float Coord(int overlap, int maxOverlap);
  320. static Similarity()
  321. {
  322. {
  323. for (int i = 0; i < 256; i++)
  324. NORM_TABLE[i] = SmallFloat.Byte315ToFloat((byte) i);
  325. }
  326. }
  327. }
  328. }