Performance MATLAB中自然语言处理的性能问题

Performance MATLAB中自然语言处理的性能问题,performance,matlab,dictionary,nlp,Performance,Matlab,Dictionary,Nlp,对于一个类,我正在处理原始文本文档(我们的示例包括可以从古腾堡项目下载的小说),并将它们转换为字典数据结构。对于每个单词,我需要知道它出现在哪个段落中,以及在每个段落中出现多少次 程序大致可分为以下几部分: 将文档拆分为单词,删除空格、逗号、句点等 对于每个文档,迭代单词。查字典。如果单词存在,请更新其条目。如果不存在,请创建一个新条目 我之所以使用MATLAB,是因为我的其余工作都在MATLAB中,我不想处理其他语言/环境。事实证明MATLAB有一些非常好的字符串处理函数。然而,我对我的代码运

对于一个类,我正在处理原始文本文档(我们的示例包括可以从古腾堡项目下载的小说),并将它们转换为字典数据结构。对于每个单词,我需要知道它出现在哪个段落中,以及在每个段落中出现多少次

程序大致可分为以下几部分:

  • 将文档拆分为单词,删除空格、逗号、句点等
  • 对于每个文档,迭代单词。查字典。如果单词存在,请更新其条目。如果不存在,请创建一个新条目
  • 我之所以使用MATLAB,是因为我的其余工作都在MATLAB中,我不想处理其他语言/环境。事实证明MATLAB有一些非常好的字符串处理函数。然而,我对我的代码运行的速度感到不安。我上面提到的第一部分不是问题;我使用了一个
    parfor
    循环,它运行得非常快。第二部分是我的问题所在

    我创建此词典的最初尝试是使用structs,这是一种MATLAB内置的数据类型。其想法是创建一个名为
    dictionary
    的结构,其字段名为实际单词,例如
    dictionary.The
    dictionary.gnome
    用于单词'The'和'gnome'。如果单词是有效的字段名(例如,它不能是压缩名),则此方法有效。但它运行缓慢,所以我寻求了一个不同的解决方案。我的下一个尝试是使用
    containers.Map
    ,这是MATLAB的哈希映射或字典对象的等价物。(我的一位同事告诉我,MATLAB在查找结构的字段名方面有点效率低下,而哈希表有O(1)个查找时间。)然而,进行这种替换实际上降低了我的性能

    在这一点上,我觉得我在优化我的代码方面做了一些相当实质性的尝试,并且开始怀疑MATLAB是否真的是一个明智的选择。我基本上是想弄清楚这种慢度是MATLAB的产物,还是我是一个糟糕的程序员(通常MATLAB在线性代数、数组和矩阵方面的速度相当快)。与其让别人阅读我的代码,我将非常感谢社区对以下任一方面提供的任何反馈:

    • 是否有人在MATLAB或类似语言(如Python)中执行此类操作(即语言处理)?如果是这样的话,我想尝试对我的一些时间进行基准测试。(我有一台MacBook,2.8GHz处理器,目前每秒大约有10-20K个字。)

    • 如果我切换到像java或C++那样的编译语言,我会得到更好的结果吗?大致估计,有什么改进

    我的独特观点: 如果你的项目可以很好地分为(1)文本、数据处理和(2)数学分析,我会用Java或Python来完成前者。(注意:我不是NLP成员。)

    MATLAB要么速度惊人(例如,使用BLAS/LAPACK库的矩阵运算),要么速度惊人,具体取决于您正在做什么

    Matlab中没有高性能的HashMap解决方案。与C++或java中的方法相比,使用容器。map并不快。(我听说有人提倡使用struct、fieldname hack作为在Matlab中获得更快映射性能的技巧。)

    快速、肮脏、极不精确的测试: 在容器中插入100万个随机生成的唯一字符串。在我的机器上映射大约需要30秒:

    tic();
    for i=1:1000000
        m(x{i}) = i;
    end
    toc();
    Elapsed time is 38.781537 seconds.
    
    另一方面,调用java虚拟机并运行下面的代码花费我的机器不到2秒:

    HashMap<String, Double> hm = new HashMap<String, Double>();
    Random r = new Random();
    for(long i = 0; i < 1000000; i++) {
        hm.put(Double.toString(r.nextDouble()), r.nextDouble());
    }
    
    mgunn@odysseus:~/MATLAB/delme/container_test$ time java ctest
    1.697u 0.151s 0:00.91 202.1%    0+0k 0+1io 0pf+0w
    
    补充意见 为了获得最佳性能,很难打败高度优化的c/c++代码。除非你非常熟悉c/c++(即使如此),否则你最终会在内存管理等方面遇到麻烦

    对于学术编码来说,优秀与正常性能通常不是什么问题。获得正确的代码比速度更重要

    Java或Python是更容易编写代码的语言,Java倾向于在这两种语言中具有更好的性能(但我不是这里的专家)

    tic();
    h = java.util.HashMap;
    for i=1:1000000
        h.put(x{i},i);
    end
    toc();
    Elapsed time is 53.177989 seconds.