コーパス内のn-gramを検索するためにNLTKを使用していますが、場合によっては非常に長い時間がかかります。n-gramの計算は、他のパッケージでは珍しい機能ではないことに気づきました(Haystackにはいくつかの機能があるようです)。これは、NLTKを放棄した場合に、コーパスでn-gramを見つけるための潜在的に高速な方法があることを意味しますか?もしそうなら、私は物事をスピードアップするために何を使うことができますか?
14365 次
4 に答える
26
単語レベルまたは文字レベルの n グラムが必要かどうかを示していないので、一般性を失うことなく前者を想定します。
また、文字列で表されるトークンのリストから始めることも想定しています。簡単にできることは、n-gram 抽出を自分で作成することです。
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]
次に、yield
各 n-gram で実行する実際のアクション ( に追加するdict
、データベースに保存するなど) に置き換えて、ジェネレーターのオーバーヘッドを取り除きます。
最後に、本当に高速でない場合は、上記をCythonに変換してコンパイルします。defaultdict
の代わりにa を使用した例yield
:
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
于 2011-09-29T10:23:06.253 に答える
9
ここzip
で、splat (*) 演算子を使用して、pythonic でエレガントかつ高速な ngram 生成関数を見つけることができます 。
def find_ngrams(input_list, n):
return zip(*[input_list[i:] for i in range(n)])
于 2015-05-06T18:55:34.147 に答える
0
def generate_ngrams(words, ngram=2):
return [words[i:i+ngram] for i in range(len(words)-ngram+1)]
sentence = "I really like python, it's pretty awesome."
words = sentence.split()
words
['I', 'really', 'like', 'python,', "it's", 'pretty', 'awesome.']
res = generate_ngrams(words, ngram=2)
res
[['I', 'really'],
['really', 'like'],
['like', 'python,'],
['python,', "it's"],
["it's", 'pretty'],
['pretty', 'awesome.']]
res = generate_ngrams(words, ngram=3)
res
[['I', 'really', 'like'],
['really', 'like', 'python,'],
['like', 'python,', "it's"],
['python,', "it's", 'pretty'],
["it's", 'pretty', 'awesome.']]
res = generate_ngrams(words, ngram=4)
res
[['I', 'really', 'like', 'python,'],
['really', 'like', 'python,', "it's"],
['like', 'python,', "it's", 'pretty'],
['python,', "it's", 'pretty', 'awesome.']]
于 2021-07-07T15:29:48.653 に答える