字典与嵌套字典...约700万个词汇定义(MULTITEXT v5)

问题描述 投票:0回答:1

我正在使用lexical资源文本文件,格式为MULTITEXT v5格式,实际上如下所示:

Chew Chew Vme1s 0 0.000000

咀嚼咀嚼Vme3p 0 0.000000

咀嚼Vmp-pn 0 0.000000

咀嚼Vmp-sf 45 0.000081

咀嚼咀嚼Vmp-pf 11 0.000020

咀嚼Vmp-pm 66 0.000119

耐嚼嚼Vmp-sn 10 0.000018

Chew Chew Appmsann 0 0.000000

Chew Chew Appmsnn 0 0.000000

Chew Chew Appmsvn 0 0.000000

格式含义:

[变形词] [引理形式] [语法上下文] ...和我不使用的tf-idf信息

因此,在典型情况下,我必须匹配〜5000个各种[变形词]以检索[引理形式],更重要的是:[语法上下文] s,其中单个[变形词]实际上可能有更多匹配行(如žvakan的情况。搜索的词汇资源大约有7百万行。

到目前为止,我尝试将完整文件加载到List中,然后使用Parallel.ForEach对每行(List项)运行所有~5000 Regex。正则表达式用于灵活地通过[引理形式]查询或仅使用单词的一部分,但为了表现我可以放弃它。花了30分钟才找到大约350个条目。所以,显然我的方法是完全错误的。

现在我正在考虑将完整的文件加载到Dictionary中,其中键将是[inflected word](所以我放弃了灵活性)但我想知道:

  • 是否有意义(更长的执行时间)嵌套这样的两个字典:

字典<[第一个字母],字典<[隐含字],列表<[定义行] >>>

它会做什么更好然后加载到:

字典<[inflected word],List <[定义行] >>

  • 有更好的主意吗?

我没有使用ConcurrentDictionary,因为在使用开始之前,内容只被写入数据结构一次。

我的偏好仅仅是查询执行时间 - RAM似乎不是问题 - 目前的代码我有19Gb的RAM可用,而且我有8个核CPU,所以对并行执行的任何评论也是受欢迎的。

如果有人想知道:这是一个自然语言处理应用程序。

c# dictionary nlp
1个回答
1
投票

我又改变了主意。换上新头。决定最好的方法是递归hashset。当找不到密钥时,需要升级代码以处理异常。我认为这更有效,因为它会自动进行递归。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] inputs = {
                                  "žvakah žvakati Vme1s 0 0.000000",
                                  "žvakahu žvakati Vme3p 0 0.000000",
                                  "žvakala žvakati Vmp-pn 0 0.000000",
                                  "žvakala žvakati Vmp-sf 45 0.000081",
                                  "žvakale žvakati Vmp-pf 11 0.000020",
                                  "žvakali žvakati Vmp-pm 66 0.000119",
                                  "žvakalo žvakati Vmp-sn 10 0.000018",
                                  "žvakan žvakati Appmsann 0 0.000000",
                                  "žvakan žvakati Appmsnn 0 0.000000",
                                  "žvakan žvakati Appmsvn 0 0.000000"
                              };

            LexicalResource resource = new LexicalResource();

            foreach (string input in inputs)
            {
                resource.Add(input);
            }

            //look up in dictionary
           KeyValuePair<int,decimal> lookup = resource.Get("žvakale žvakati Vmp-pf");

        }
    }

    public class LexicalResource
    {
        public string lexical { get; set; }
        public HashSet<LexicalResource> hash { get; set; }
        public KeyValuePair<int, decimal> value { get; set; }

        public LexicalResource() { }
        public void Add(string lexical)
        {
            string[] tempArray = lexical.Split(new char[] { ' ' });
            AddRecursively(this, tempArray);
        }
        public KeyValuePair<int, decimal> Get(string lexical)
        {
            string[] tempArray = lexical.Split(new char[] { ' ' });
            return GetRecursive(this, tempArray);
        }

        KeyValuePair<int, decimal> GetRecursive(LexicalResource resource, string[] lexicon)
        {
            KeyValuePair<int, decimal> results = new KeyValuePair<int, decimal>();

            int numberChildren = lexicon.Length;
            if (numberChildren == 0)
            {
                results = resource.value;
            }
            else
            {
                LexicalResource child = resource.hash.Where(x => x.lexical == lexicon[0]).FirstOrDefault();
                results = GetRecursive(child, lexicon.Skip(1).ToArray());
            }

            return results;
        }

        void AddRecursively(LexicalResource resource, string[] lexicon)
        {
            lexical = lexicon[0];
            int numberChildren = lexicon.Length;
            if (numberChildren == 2)
            {
                resource.value = new KeyValuePair<int, decimal>(int.Parse(lexicon[0]), decimal.Parse(lexicon[1]));
            }
            else
            {
                if (resource.hash == null)
                {
                    resource.hash = new HashSet<LexicalResource>();
                }
                LexicalResource child = resource.hash.Where(x => x.lexical == lexicon[0]).FirstOrDefault();
                if (child == null)
                {
                    child = new LexicalResource();
                    resource.hash.Add(child);
                }
                AddRecursively(child, lexicon.Skip(1).ToArray());
            }
        }

    }

}
© www.soinside.com 2019 - 2024. All rights reserved.