Как правильно сочетать числовые функции с текстом (сумкой слов) в scikit-learn?
Я пишу классификатор для веб-страниц, поэтому у меня есть смесь числовых функций, и я также хочу классифицировать текст. Я использую подход "мешок слов" для преобразования текста в (большой) числовой вектор. Код заканчивается так:
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
import numpy as np
numerical_features = [
[1, 0],
[1, 1],
[0, 0],
[0, 1]
]
corpus = [
'This is the first document.',
'This is the second second document.',
'And the third one',
'Is this the first document?',
]
bag_of_words_vectorizer = CountVectorizer(min_df=1)
X = bag_of_words_vectorizer.fit_transform(corpus)
words_counts = X.toarray()
tfidf_transformer = TfidfTransformer()
tfidf = tfidf_transformer.fit_transform(words_counts)
bag_of_words_vectorizer.get_feature_names()
combinedFeatures = np.hstack([numerical_features, tfidf.toarray()])
Это работает, но я беспокоюсь о точности. Обратите внимание, что есть 4 объекта и только две числовые функции. Даже самый простой текст приводит к вектору с девятью элементами (потому что в корпусе девять разных слов). Очевидно, что в реальном тексте будут сотни или тысячи отдельных слов, поэтому конечный вектор признаков будет < 10 числовых, но> 1000 слов.
Из-за этого, разве классификатор (SVM) не будет сильно взвешивать слова по числовым признакам в 100-1 раза? Если так, как я могу дать компенсацию, чтобы убедиться, что пакет слов одинаково взвешен по отношению к числовым признакам?
1 ответ
Я думаю, что ваше беспокойство полностью обосновано в отношении значительно более высокого измерения, созданного из разреженных текстовых токенов наивным способом (как мульти-горячие векторы). По крайней мере, вы можете решить это двумя способами, описанными ниже. Оба они будут создавать вектор низкой размерности (например, 100-размерный) из текста. Измерение не будет увеличиваться, когда ваш словарный запас увеличивается.
- с функцией хеширования. Это относится к вашей модели "мешок слов".
- со встраиванием слов ( пример использования, который работает с scikit-learn) или более продвинутыми кодировщиками текста, такими как универсальный кодировщик предложений или любой вариант современного кодировщика BERT.
Вы можете взвесить счет с помощью Tf – idf:
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
np.set_printoptions(linewidth=200)
corpus = [
'This is the first document.',
'This is the second second document.',
'And the third one',
'Is this the first document?',
]
vectorizer = CountVectorizer(min_df=1)
X = vectorizer.fit_transform(corpus)
words = vectorizer.get_feature_names()
print(words)
words_counts = X.toarray()
print(words_counts)
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(words_counts)
print(tfidf.toarray())
Выход такой:
# words
[u'and', u'document', u'first', u'is', u'one', u'second', u'the', u'third', u'this']
# words_counts
[[0 1 1 1 0 0 1 0 1]
[0 1 0 1 0 2 1 0 1]
[1 0 0 0 1 0 1 1 0]
[0 1 1 1 0 0 1 0 1]]
# tfidf transformation
[[ 0. 0.43877674 0.54197657 0.43877674 0. 0. 0.35872874 0. 0.43877674]
[ 0. 0.27230147 0. 0.27230147 0. 0.85322574 0.22262429 0. 0.27230147]
[ 0.55280532 0. 0. 0. 0.55280532 0. 0.28847675 0.55280532 0. ]
[ 0. 0.43877674 0.54197657 0.43877674 0. 0. 0.35872874 0. 0.43877674]]
С этим представлением вы сможете объединить дополнительные двоичные функции для обучения SVC.