Оптимизация алгоритма разделения с выводом биграмм в Python

У меня проблема с этой функцией разделения. Функция в основном берет строку, например word = 'optimization', определяет ее точки разделения относительно сгенерированного случайного числа и превращает это разбиение в биграммы. Маркер '0' означает конец слова. Рассмотрите слово ниже; левая сторона является входом, и функция должна давать один из всех возможных выходов с одинаковой вероятностью для любого вывода одного и того же слова:

'optimization' = [['op', 'ti'], ['ti', 'mizati'], ['mizati', 'on'], ['on', '0']

Проблема: когда я профилировал все свои функции, эта функция разделения потребляла наибольшее время выполнения (обрабатывала 100 000 слов), но я застрял на ее оптимизации. Мне нужна помощь на данный момент. Также могут быть лучшие способы, но я ограничен своей собственной точкой зрения.

from numpy import mod
import nltk   

def random_Bigramsplitter(word):
    spw = []
    length = len(word)
    rand = random_int(word)  # produce random number in respect to len(word)

    if rand == length:  # probability of not dividing
        return [tuple([word, '0'])]
    else:
        div = mod(rand, (length + 1))  # defining division points by mod operation
        bound = length-div
        spw.append(div)
        while div != 0:
            rand = random_int(word)
            div = mod(rand, (bound + 1))
            bound = bound-div
            spw.append(div)
        result = spw

    b = 0
    points = []
    for x in range(len(result) - 1):  # calculating splitting points in respect to array structure
        b += result[x]
        points.append(b)

    xy = 0
    t = []
    for i in points:
        t.append(word[xy:i])
        xy = i

    if word[xy: len(word)] != '':
        t.append(word[xy: len(word)])

    t.extend('0')
    c = [b for b in nltk.bigrams(t)]

    return c

person serkan maestro    schedule 02.10.2015    source источник
comment
Для меня не очень понятно, работает ли создатель биграмм NLTK достаточно быстро для ваших нужд. Может быть, лучше написать собственный разделитель биграмм.   -  person colidyre    schedule 02.10.2015
comment
@LetzerWille: я предполагаю такую ​​функцию: from random import choice; def random_int(word): return choice(range(len(word))) + 1   -  person colidyre    schedule 02.10.2015


Ответы (1)


Вы можете заменить

c = [b for b in nltk.bigrams(t)]

с участием

def get_ngram(word, n):
    return zip(*[word[i:] for i in xrange(n)])

c = [b for b in get_ngram(t, 2)]

это вроде быстрее. Я не утверждаю, что это самое быстрое решение.

Есть больше ответов для оптимизации скорости вашей биграммы. Кажется, это хорошая отправная точка: Быстрый расчет n-грамм, мой фрагмент кода взят из : http://locallyoptimal.com/blog/2013/01/20/elegant-n-gram-generation-in-python/

person colidyre    schedule 02.10.2015
comment
@Serkan Kumyol - есть ли какие-то успехи в этом? Строка c=[b for b in nltk.bigrams(t)] была убийцей времени, как уже показал LetzerWille. - person colidyre; 04.10.2015
comment
Я переписываю весь код, возможно, лучше разделить строку в соответствии с соответствием ascıı. Я также попробовал профилировщик строк, и мой random_int определенно должен измениться, и, возможно, я смогу избавиться от него, потому что это самое дорогостоящее выражение, как я только что узнал. - person serkan maestro; 05.10.2015
comment
@Serkan Kumyol - Тогда, пожалуйста, либо отредактируйте свой вопрос в соответствии с вашим новым кодом, либо проголосуйте за полезные ответы, либо даже отметьте их как решение, которое сработало для вас, чтобы указать, что вы добились хотя бы прогресса. Если вы отредактируете свой вопрос, я бы рекомендовал также предоставить код для random_int(). - person colidyre; 05.10.2015