【问题标题】:Performance Issues With Natural Language Processing in MATLABMATLAB 中自然语言处理的性能问题
【发布时间】:2016-04-06 21:44:03
【问题描述】:

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

流程大致可以分为

  1. 将文档分成单词,删除空格、逗号、句点等。
  2. 对于每个文档,遍历单词。查字典。如果该词存在,则更新其条目。如果不存在,请创建一个新条目。

我正在做这个 MATLAB,因为我的其余工作都在 MATLAB 中,我不想处理另一种语言/环境。事实证明 MATLAB 有一些非常好的字符串处理函数。但是,我对我的代码运行速度有多慢感到不安。我上面提到的第一部分没有问题;我使用parfor 循环,它运行得非常快。第二部分是我的问题所在。

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

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

  • 有没有人在 MATLAB 或类似语言(例如 Python)中做这种类型的事情(即语言处理)?如果是这样,我想尝试对我的一些时间进行基准测试。 (我有一台 MacBook,2.8 GHz 处理器,目前我每秒可以处理 10-20K 字。)

  • 如果我切换到 Java 或 C++ 之类的编译语言,是否可以获得更好的结果?大致估计,有什么样的改进?

【问题讨论】:

    标签: performance matlab dictionary nlp


    【解决方案1】:

    我的独特观点:

    如果您的项目可以很好地划分为 (1) 文本、数据处理和 (2) 数学分析,我会使用 Java 或 Python 完成所有前者。 (注意:我不是 NLP 人。)

    MATLAB 要么快得惊人(例如,使用 BLAS/LAPACK 库的矩阵运算)要么慢得令人震惊,具体取决于正是您在做什么。

    Matlab 中没有高性能的 HashMap 解决方案。与您可以在 C++ 或 Java 中执行的操作相比,使用 containers.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
    

    从 MATLAB 访问 Java 对象也有很多开销...

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

    其他 cmets

    要获得最佳性能,高度优化的 c/c++ 代码是无与伦比的。除非您非常熟悉 c/c++(即使如此),否则您最终会对内存管理等感到头疼......

    对于学术编码,优秀与良好的性能通常不是什么大问题。让代码正确比速度更重要。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多