Правильный способ использования фраз и preprocess_string gensim - PullRequest
0 голосов
/ 24 апреля 2018

Как правильно использовать фразы gensim и preprocess_string вместе? Я делаю так, но это немного надумано.

from gensim.models.phrases import Phrases
from gensim.parsing.preprocessing import preprocess_string
from gensim.parsing.preprocessing import strip_tags
from gensim.parsing.preprocessing import strip_short
from gensim.parsing.preprocessing import strip_multiple_whitespaces
from gensim.parsing.preprocessing import stem_text
from gensim.parsing.preprocessing import remove_stopwords
from gensim.parsing.preprocessing import strip_numeric
import re
from gensim import utils

# removed "_" from regular expression
punctuation = r"""!"#$%&'()*+,-./:;<=>?@[\]^`{|}~"""

RE_PUNCT = re.compile(r'([%s])+' % re.escape(punctuation), re.UNICODE)


def strip_punctuation(s):
    """Replace punctuation characters with spaces in `s` using :const:`~gensim.parsing.preprocessing.RE_PUNCT`.

    Parameters
    ----------
    s : str

    Returns
    -------
    str
        Unicode string without punctuation characters.

    Examples
    --------
    >>> from gensim.parsing.preprocessing import strip_punctuation
    >>> strip_punctuation("A semicolon is a stronger break than a comma, but not as much as a full stop!")
    u'A semicolon is a stronger break than a comma  but not as much as a full stop '

    """
    s = utils.to_unicode(s)
    return RE_PUNCT.sub(" ", s)



my_filter = [
    lambda x: x.lower(), strip_tags, strip_punctuation,
    strip_multiple_whitespaces, strip_numeric,
    remove_stopwords, strip_short, stem_text
]


documents = ["the mayor of new york was there", "machine learning can be useful sometimes","new york mayor was present"]

sentence_stream = [doc.split(" ") for doc in documents]
bigram = Phrases(sentence_stream, min_count=1, threshold=2)
sent = [u'the', u'mayor', u'of', u'new', u'york', u'was', u'there']
test  = " ".join(bigram[sent])


print(preprocess_string(test))
print(preprocess_string(test, filters=my_filter))

Результат:

['mayor', 'new', 'york']
['mayor', 'new_york'] #correct

часть кода была взята из: Как извлечь фразы из корпуса, используя gensim

1 Ответ

0 голосов
/ 17 декабря 2018

Я бы рекомендовал использовать gensim.utils.tokenize() вместо gensim.parsing.preprocessing.preprocess_string() для вашего примера.

Во многих случаях tokenize() делает очень хорошую работу, поскольку он будет возвращать только последовательности буквенных символов (без цифр). Это экономит вам дополнительные этапы очистки для пунктуации и т. Д.

Однако tokenize() не включает в себя удаление стоп-слов, коротких токенов и стволов. В любом случае это должно быть сокращено, если вы имеете дело с другими языками, кроме английского.

Вот код для ваших (уже чистых) примеров документов, который дает вам нужные биграммы.

documents = ["the mayor of new york was there",
             "machine learning can be useful sometimes",
             "new york mayor was present"]

import gensim, pprint

# tokenize documents with gensim's tokenize() function
tokens = [list(gensim.utils.tokenize(doc, lower=True)) for doc in documents]

# build bigram model
bigram_mdl = gensim.models.phrases.Phrases(tokens, min_count=1, threshold=2)

# do more pre-processing on tokens (remove stopwords, stemming etc.)
# NOTE: this can be done better
from gensim.parsing.preprocessing import preprocess_string, remove_stopwords, stem_text
CUSTOM_FILTERS = [remove_stopwords, stem_text]
tokens = [preprocess_string(" ".join(doc), CUSTOM_FILTERS) for doc in tokens]

# apply bigram model on tokens
bigrams = bigram_mdl[tokens]

pprint.pprint(list(bigrams))

Выход:

[['mayor', 'new_york'],
 ['machin', 'learn', 'us'],
 ['new_york', 'mayor', 'present']]
...