【问题标题】:TFIDF calculation in Lucene while restricting time range限制时间范围的 Lucene 中的 TFIDF 计算
【发布时间】:2013-12-18 12:29:42
【问题描述】:

我有很多不同时期的文件。 现在我需要在一段时间内计算文档的 tfidf。 以下是我要做的,例如:

我一年有100万个文本文档,我会把一个月内的文档作为语料库。 我想计算每个月的tfidf,即计算一个月的词频,然后乘以逆文档频率剩余月份

使用lucene对数据(文本、时间等)进行索引,我只是想知道lucene是否可以方便这种场景的计算 我知道 Lucene 可以帮我获取词频和文档频率,但是有没有 API 可以限制时间范围进行计算?

非常感谢。

【问题讨论】:

    标签: lucene tf-idf


    【解决方案1】:

    我有一个使用 Lucene.Net 3.0.3 和有效负载的解决方案。我不确定这是否是使用当前比 .net 端口领先的 java 版本完成此任务的最佳方法。

    它的工作原理是为应该自定义评分的术语分配一个有效负载、一个自定义字节数组,以及一个覆盖 ScorePayload 的自定义相似度来解析字节数组以进行自定义过滤。 (这需要调用此方法的查询,例如 PayloadTermQuery)。

    这个高度人为的示例代码将根据 (id % 3) 对术语进行评分。 (三的倍数为零)。您可以将其与 PositiveScoresOnlyCollector 结合使用,以忽略得分为零的匹配项。

    using System;
    using System.IO;
    using Lucene.Net.Analysis;
    using Lucene.Net.Analysis.Tokenattributes;
    using Lucene.Net.Documents;
    using Lucene.Net.Index;
    using Lucene.Net.Search;
    using Lucene.Net.Search.Payloads;
    using Lucene.Net.Store;
    
    public static class Program {
        public static void Main() {
            var directory = new RAMDirectory();
    
            // Initialization; create 50 documents with payload
            var writer = new IndexWriter(directory, new KeywordAnalyzer(), true, IndexWriter.MaxFieldLength.UNLIMITED);
            for (var i = 0; i < 50; ++i) {
                AddDocument(writer, i, "lorem ipsum etc blah blah");
            }
            writer.Commit();
    
            var searcher = new IndexSearcher(directory, readOnly: true);
            searcher.Similarity = new ShazaamPayloadSimilarity();
    
            // The term we'll be looking for. This should match all documents.
            var term = new Term("Data", "lorem");
            var query = new PayloadTermQuery(term, new MaxPayloadFunction());
            var topDocs = searcher.Search(query, 40);
    
            // This is a bad example of a FieldCache usage.
            var iValues = FieldCache_Fields.DEFAULT.GetStrings(searcher.IndexReader, "Id");
            foreach (var scoreDoc in topDocs.ScoreDocs) {
                Console.WriteLine("Score: {0:0.0000}  i={1}", scoreDoc.Score, iValues[scoreDoc.Doc]);
            }
    
            Console.ReadLine();
        }
    
        public static void AddDocument(IndexWriter writer, Int32 id, String data) {
            var payload = BitConverter.GetBytes(id);
            var analyzer = new ShazaamPayloadAnalyzer(payload);
            var textReader = new StringReader(data);
    
            var document = new Document();
            document.Add(new Field("Id", id.ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED));
            document.Add(new Field("Data", analyzer.TokenStream(null, textReader)));
    
            writer.AddDocument(document);
        }
    }
    
    public class ShazaamPayloadAnalyzer : Analyzer {
        private readonly Byte[] _value;
    
        public ShazaamPayloadAnalyzer(Byte[] value) {
            _value = value;
        }
    
        public override TokenStream TokenStream(String fieldName, TextReader reader) {
            TokenStream result = new WhitespaceTokenizer(reader);
            result = new ShazaamPayloadFilter(result, _value);
            return result;
        }
    }
    
    public class ShazaamPayloadFilter : TokenFilter {
        private readonly byte[] _payload;
        private readonly IPayloadAttribute _payloadAttr;
    
        public ShazaamPayloadFilter(TokenStream input, Byte[] payload)
            : base(input) {
            _payload = payload;
            _payloadAttr = AddAttribute<IPayloadAttribute>();
        }
    
        public override Boolean IncrementToken() {
            if (input.IncrementToken()) {
                _payloadAttr.Payload = new Payload(_payload);
                return true;
            }
    
            return false;
        }
    }
    
    public class ShazaamPayloadSimilarity : DefaultSimilarity {
        public override Single ScorePayload(Int32 docId, String fieldName, Int32 start, Int32 end, Byte[] payload, Int32 offset, Int32 length) {
            var originalValue = BitConverter.ToInt32(payload, startIndex: 0);
    
            // Advanced logic ahead!
            return (originalValue % 3);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-30
      相关资源
      最近更新 更多