Предварительная обработка CountVectorizer, связанная с регулярным выражением - PullRequest
1 голос
/ 24 февраля 2020

Я делаю обработку текста с использованием CountVectorizer / logisti c регрессия и сравниваю оценку f1 без предварительной обработки и предварительной обработки. Я хотел бы использовать регулярное выражение для предварительной обработки, поэтому я построил код, подобный приведенному ниже

def better_preprocessor(s):
    lower = s.lower()
    lower = re.sub(r'^\w{8,}$', lambda x:x[:7], lower)
    return lower

def a():
    cv = CountVectorizer()
    train = cv.fit_transform(train_data)
    features = cv.get_feature_names()
    cv_dev = CountVectorizer(vocabulary = features)
    dev = cv_dev.fit_transform(dev_data)
    print(features)

    lgr = LogisticRegression(C=0.5, solver="liblinear", multi_class="auto")
    lgr.fit(train, train_labels)
    lgr_pred = lgr.predict(dev)
    score = metrics.f1_score(dev_labels, lgr_pred, average="weighted")
    print('No preprocessing score:', score)

    cv_im = CountVectorizer(preprocessor=better_preprocessor)
    train_im = cv_im.fit_transform(train_data)
    features_im = cv_im.get_feature_names()
    cv_im_dev = CountVectorizer(preprocessor=better_preprocessor, vocabulary = features_im)
    dev_im = cv_im_dev.fit_transform(dev_data)

    lgr.fit(train_im, train_labels)
    lgr_pred_im = lgr.predict(dev_im)
    score_im = metrics.f1_score(dev_labels, lgr_pred_im, average="weighted")
    print('Preprocessing score', score_im)
    print(len(features)-len(features_im))
    print(features_im)

a()

Я попытался усечь длину слова больше или равно 8 до 7, но когда я проверял список словаря, используя get_feature_names, было без изменений. Я не знаю, где мне это исправить.

Ответы [ 2 ]

1 голос
/ 24 февраля 2020

Вам не нужно никаких регулярных выражений для этого. Используйте

def better_preprocessor(s):
    if len(s) >= 8:
        return s.lower()[:7]
    else:
        return s.lower()

Код re.sub(r'^\w{8,}$', lambda x:x[:7], lower) принимает строку lower и пытается найти соответствие ^\w{8,}$:

  • ^ - начало строки
  • \w{8,} - восемь или более символов слова
  • $ - конец строки.

Затем lambda x:x[:7] пытается найти совпадение (где x является сопоставить объект данных), и вы пытаетесь нарезать объект сопоставления данных. Возможно, вы намеревались использовать x.group()[:7], но это все еще излишнее.

Если вы планируете извлечь все слова из строки и урезать их, вам нужно указать, что слово для вас и использовать

def better_preprocessor(s):
    return re.sub(r'\b(\w{7})\w+', r'\1', s.lower())

См. Демонстрационный пример regex

  • \b - граница слова
  • (\w{7}) - группа 1 (обозначается \1 из шаблона замены): семь символов слова
  • \w+ - 1+ слова символа
0 голосов
/ 24 февраля 2020

Вот способ сделать это, используя параметр analyzer:

from sklearn.feature_extraction.text import CountVectorizer

def better_preprocessor(s):
    lower = s.lower().split()
    lower = [x[:7] for x in lower]
    for l in lower:
        yield l

lower = ["hello how are you doing today crocodilesaway","hello how are you"]

cv = CountVectorizer(analyzer=better_preprocessor, )
cv.fit_transform(lower)
cv.get_feature_names()

['are', 'crocodi', 'doing', 'hello', 'how', 'today', 'you']
...