1

我使用 wordnet 相似性 java api 来测量两个同义词集之间的相似性,如下所示:

 public class WordNetSimalarity {
 private static ILexicalDatabase db = new NictWordNet();
 private static RelatednessCalculator[] rcs = {
                 new HirstStOnge(db), new LeacockChodorow(db), new Lesk(db),  new WuPalmer(db), 
                 new Resnik(db), new JiangConrath(db), new Lin(db), new Path(db)
                 };

 public static double computeSimilarity( String word1, String word2 ) {
         WS4JConfiguration.getInstance().setMFS(true);
         double s=0;
         for ( RelatednessCalculator rc : rcs ) {
                 s = rc.calcRelatednessOfWords(word1, word2);
                // System.out.println( rc.getClass().getName()+"\t"+s );
         }

        return s;
 } 

主班

      public static void main(String[] args) {
         long t0 = System.currentTimeMillis();

         File source = new File ("TagsFiltered.txt");
         File target = new File ("fich4.txt");
         ArrayList<String> sList= new ArrayList<>();

         try {
             if (!target.exists()) target.createNewFile();
            Scanner scanner = new Scanner(source);
            PrintStream psStream= new PrintStream(target);
            while (scanner.hasNext()) {
                sList.add(scanner.nextLine());                  
            }
            for (int i = 0; i < sList.size(); i++) {
            for (int j = i+1; j < sList.size(); j++) {
                psStream.println(sList.get(i)+" "+sList.get(j)+" "+WordNetSimalarity.computeSimilarity(sList.get(i), sList.get(j)));
            }
        }   

            psStream.close();
        } catch (Exception e) {e.printStackTrace();
        }


         long t1 = System.currentTimeMillis();
         System.out.println( "Done in "+(t1-t0)+" msec." );
 }

我的数据库包含 595 个同义词集,这意味着方法computeSimilarity将被调用 (595*594/2) 时间来计算两个单词之间的相似度,它花费的时间超过5000 ms!所以要完成我的任务,我至少需要一个星期!

我的问题是如何减少这段时间!

怎么提高成绩??

4

4 回答 4

0

我不认为语言是你的问题。

您可以通过并行性帮助自己。我认为这将是 map reduce 和 Hadoop 的一个很好的候选者。

于 2013-05-10T09:05:57.487 回答
0

在线程/分叉方面,Perl 与许多其他语言不同。

使 Perl 线程与其他线程不同的关键之一是默认情况下不共享数据。这使线程更容易和更安全地使用,您不必担心库或大多数代码的线程安全,只需担心线程位。然而,由于 Perl 必须将解释器的副本和所有加载的模块放入每个线程中,这可能会导致性能下降和内存消耗。

说到分叉,我只会谈论 Unix。Perl 使用线程在 Windows 上模拟 fork,它可以工作,但它可能很慢而且有问题。

分叉优势

  • 创建分叉非常快
  • 非常坚固

分叉的缺点

  • 进程之间的通信可能很慢而且很尴尬

线程优势

  • 线程协调和数据交换相当容易
  • 线程相当容易使用

线程缺点

  • 每个线程占用大量内存
  • 线程启动速度可能很慢
  • 线程可能有问题(perl 越新越好)
  • 数据库连接不跨线程共享

一般来说,要从 Perl 线程中获得良好的性能,最好启动一个线程池并重用它们。可以更轻松地创建、使用和丢弃分叉。

无论哪种情况,您都可能需要一些东西来管理您的员工池。对于分叉,您将要使用 Parallel::ForkManager 或 Child。Child 特别好,因为它内置了进程间通信。

对于线程,您将要使用threads::shared、Thread::Queue 并阅读perlthrtut。此外,线程数将取决于您的计算机拥有的内核数。如果您有四个内核,那么创建 3 个以上的线程并不是很有帮助(主程序为 3 + 1)。

不过,老实说,线程/分叉可能不是要走的路。事实上,在许多情况下,它们甚至会因为开销而减慢速度。如果你真的需要速度,最好的方法是通过分布式计算。我建议您研究某种分布式计算平台,以使您的运行时更好。如果您可以将 search/compareTo 空间的维度降低到小于 n^2,那么 map reduce 或 Hadoop 可能是一个不错的选择;否则,您只会有大量开销,并且无法使用 Hadoop 提供的真正可扩展性 (@Thomas Jungblut)。

于 2013-05-19T07:09:42.570 回答
0

你试过矩阵计算器吗?

于 2013-05-23T00:08:47.517 回答
0

我不知道是否有可能优化这个算法。

但绝对可以跑得更快。在我的机器上,这个操作花费的时间少了两倍,所以如果你有八个 i7 内核,你需要 15 个小时来处理所有事情(如果你并行处理循环)

您可以在 Amazon Web Services 获得虚拟机。因此,如果您拥有多台机器并在每台机器上对不同的数据块运行多线程处理 - 您将在几个小时内完成。

从技术上讲,可以为此使用 Hadoop,但如果您只需要运行一次 - 在我看来,使计算并行并在多台机器上启动会更简单。

于 2013-05-23T05:31:39.777 回答