2011-09-29 18 views
16

मैं एनएलटीके का उपयोग कॉर्पस में एन-ग्राम खोजने के लिए कर रहा हूं लेकिन कुछ मामलों में इसमें काफी समय लग रहा है। मैंने देखा है कि एन-ग्राम की गणना अन्य पैकेजों में एक असामान्य विशेषता नहीं है (जाहिर है हेस्टैक के लिए इसके लिए कुछ कार्यक्षमता है)। क्या इसका मतलब है कि अगर मैं एनएलटीके छोड़ देता हूं तो मेरे कॉर्पस में एन-ग्राम ढूंढने का एक संभावित तेज़ तरीका है? यदि हां, तो चीजों को गति देने के लिए मैं क्या उपयोग कर सकता हूं?फास्ट एन-ग्राम गणना

+0

रुचि रखने वालों के लिए अधिक पढ़ना: http://packages.python.org/Whoosh/ngram s.html – Trindaz

+0

संबंधित प्रश्न: http://stackoverflow.com/questions/21883108/fast-optimize-n-gram-implementations-in-python – dmcc

उत्तर

21

चूंकि आपने यह इंगित नहीं किया कि आप शब्द या चरित्र-स्तर एन-ग्राम चाहते हैं, तो मैं सामान्यता के नुकसान के बिना पूर्व को मानने वाला हूं।

मैं यह भी मानता हूं कि आप तारों द्वारा प्रतिनिधित्व टोकन की एक सूची से शुरू करते हैं। आप आसानी से क्या कर सकते हैं एन-ग्राम निष्कर्षण स्वयं लिखना है।

def ngrams(tokens, MIN_N, MAX_N): 
    n_tokens = len(tokens) 
    for i in xrange(n_tokens): 
     for j in xrange(i+MIN_N, min(n_tokens, i+MAX_N)+1): 
      yield tokens[i:j] 

तो फिर तुम प्रत्येक एन-ग्राम पर ले (एक dict में जोड़ने, एक डेटाबेस में संग्रहीत, जो कुछ भी) जनरेटर भूमि के ऊपर से छुटकारा पाने के लिए चाहते हैं वास्तविक कार्रवाई के साथ yield बदलें।

अंत में, यदि यह वास्तव में पर्याप्त तेज़ नहीं है, तो उपरोक्त को Cython में परिवर्तित करें और इसे संकलित करें। का उपयोग कर उदाहरण defaultdictyield के बजाय एक:

def find_ngrams(input_list, n): 
    return zip(*[input_list[i:] for i in range(n)]) 
+2

साइथन के नए संस्करण स्टेटमेंट के लिए पायथन को पहचानते हैं और यदि संभव हो तो उन्हें गति देते हैं। इसके अलावा आपके भीतर आंतरिक पुनरावृत्ति में एक विधि लुकअप है। लूप के बाहर 'tokenjoiner = "" .join' को परिभाषित करना और आंतरिक "" को बदलना चाहिए। जॉइन को चीजों को गति देना चाहिए। – rocksportrocker

+0

@rocksportrocker: अच्छी जगह, आपके सुझाव जोड़ा। –

+0

और आप "count.get (....) + = 1" के साथ आंतरिक रेखा को फिर से लिख सकते हैं विधि विधि से बचने के लिए एक और var परिचय। – rocksportrocker

7

आप zip और सूचक (*) ऑपरेटर here का उपयोग कर एक pythonic, सुरुचिपूर्ण और तेजी से ngram पीढ़ी समारोह मिल सकती है ग्राम आप निम्नलिखित फ़ंक्शन का उपयोग कर सकते हैं

def ngrams(text, n): 
    n-=1 
    return [text[i-n:i+1] for i,char in enumerate(text)][n:] 
0

चरित्र स्तरीय n- के लिए:

def ngrams(tokens, int MIN_N, int MAX_N): 
    cdef Py_ssize_t i, j, n_tokens 

    count = defaultdict(int) 

    join_spaces = " ".join 

    n_tokens = len(tokens) 
    for i in xrange(n_tokens): 
     for j in xrange(i+MIN_N, min(n_tokens, i+MAX_N)+1): 
      count[join_spaces(tokens[i:j])] += 1 

    return count 
संबंधित मुद्दे