Технически это не ответ, но его нельзя записать в комментариях, так что вот оно.Здесь есть несколько проблем:
LogisticRegression
класс (и большинство других моделей scikit-learn) работают с двумерными данными (n_samples, n_features)
.
Это означает, что ему нужен набор 1-мерных массивов (по одному для каждой строки (выборки), в котором элементы массива содержат значения признаков).
В ваших данных одно слово будет массивом 1-го числа, что означает, что одно предложение (образец) будет массивом 2-го числа.Это означает, что полные данные (коллекция предложений здесь) будут представлять собой набор двумерных массивов.Даже в этом, поскольку каждое предложение может иметь различное количество слов, оно не может быть объединено в один трехмерный массив.
Во-вторых, W2VTransformer
в gensim выглядит как класс, совместимый с scikit-learn, но это не так.Он пытается следовать «соглашениям scikit-learn API» для определения методов fit()
, fit_transform()
и transform()
.Они не совместимы с scikit-learn Pipeline
.
Вы можете видеть, что требования к входным параметрам fit()
и fit_transform()
различны.
fit()
:
X (итерируемый из итераций str) - входной корпус.
X может быть просто списком списков токенов, но для более крупных корпусов рассмотрим итерацию, которая направляет предложения непосредственно с диска / сети.См. BrownCorpus, Text8Corpus или LineSentence в модуле word2vec для таких примеров.
fit_transform()
:
X (numpy массив формы [n_samples, n_features]) - обучающий набор.
Если вы хотите использовать scikit-learn, товам нужно будет иметь 2-ую форму.Вам нужно будет «как-то объединить» слова-векторы для одного предложения, чтобы сформировать 1-й массив для этого предложения.Это означает, что вам нужно сформировать своего рода вектор предложений, выполнив:
- сумма отдельных слов
- среднее значение отдельных слов
- взвешенное усреднение отдельныхслова, основанные на частоте, tf-idf и т. д.
- с использованием других методов, таких как sent2vec, параграф2vec, doc2vec и т. д.
Примечание : - Я заметил, что вы делали это на основе D2VTransformer
.Это должен быть правильный подход, если вы хотите использовать sklearn.
Проблема в этом вопросе заключалась в следующей строке (поскольку этот вопрос теперь удален):
X_train = vectorizer.fit_transform(X_train)
Здесь вы перезаписываетеваш исходный X_train
(список слов) с уже рассчитанными векторами слов и, следовательно, с этой ошибкой.
Или же вы можете использовать другие инструменты / библиотеки (керас, тензор потока), которые позволяют последовательно вводить переменный размер.Например, LSTM могут быть сконфигурированы здесь, чтобы принимать переменные входные данные и маркер окончания, чтобы отметить конец предложения (образец).
Обновление :
ВПриведенное выше решение позволяет заменить строки:
model = D2VTransformer(dm=1, size=50, min_count=2, iter=10, seed=0)
model.fit(X_train)
clf = LogisticRegression(penalty='l2', C=0.1, random_state=0)
clf.fit(model.transform(X_train), y_train)
pipeline = Pipeline([
('vec', model),
('clf', clf)
])
y_pred = pipeline.predict(X_train)
на
pipeline = Pipeline([
('vec', model),
('clf', clf)
])
pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_train)
Нет необходимости подбирать и преобразовывать отдельно, поскольку pipeline.fit()
автоматически сделает это.