逻辑回归:X每个样本有667个特征;期待 74869

Logistic regression: X has 667 features per sample; expecting 74869

我使用 imdb 电影评论数据集进行了逻辑回归来预测评论的情绪。

tfidf = TfidfVectorizer(strip_accents=None, lowercase=False, preprocessor=None, 

tokenizer=fill, use_idf=True, norm='l2', smooth_idf=True)
y = df.sentiment.values
X = tfidf.fit_transform(df.review)

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1, test_size=0.3, shuffle=False)
clf = LogisticRegressionCV(cv=5, scoring="accuracy", random_state=1, n_jobs=-1, verbose=3,max_iter=300).fit(X_train, y_train)

yhat = clf.predict(X_test)


print("accuracy:")
print(clf.score(X_test, y_test))

model_performance(X_train, y_train, X_test, y_test, clf)

在此之前应用了文本预处理。 模型性能只是一个创建混淆矩阵的函数。 这一切都非常准确。

我现在抓取新的 IMDB 评论:

#The movie "Joker" IMBD review page
url_link='https://www.imdb.com/title/tt7286456/reviews'
html=urlopen(url_link)

content_bs=BeautifulSoup(html)

JokerReviews = []
#All the reviews ends in a div class called text in html, can be found in the imdb source code
for b in content_bs.find_all('div',class_='text'):
  JokerReviews.append(b)

df = pd.DataFrame.from_records(JokerReviews)
df['sentiment'] = "0" 
jokerData=df[0]
jokerData = jokerData.apply(preprocessor)

问题:现在我想测试相同的逻辑回归来预测情绪:

tfidf2 = TfidfVectorizer(strip_accents=None, lowercase=False, preprocessor=None, tokenizer=fill, use_idf=True, norm='l2', smooth_idf=True)
y = df.sentiment.values
Xjoker = tfidf2.fit_transform(jokerData)

yhat = Clf.predict(Xjoker)

但是我得到了错误: ValueError:X 每个样本有 667 个特征;期待 74869

我不明白为什么它必须具有与 X_test

相同数量的功能

问题是您的模型是在识别出 74869 个唯一单词的预处理之后训练的,并且您用于推理的输入数据的预处理已经识别出 667 个单词,并且您应该将数据发送到具有相同特征的模型列数。除此之外,为推理识别的 667 个词中的一个词也可能不会被模型预期。

要为您的模型创建有效输入,您必须使用如下方法:

# check which columns are expected by the model, but not exist in the inference dataframe
not_existing_cols = [c for c in X.columns.tolist() if c not in Xjoker]
# add this columns to the data frame
Xjoker = Xjoker.reindex(Xjoker.columns.tolist() + not_existing_cols, axis=1)
# new columns dont have values, replace null by 0
Xjoker.fillna(0, inplace = True)
# use the original X structure as mask for the new inference dataframe
Xjoker = Xjoker[X.columns.tolist()]

完成这些步骤后,您可以调用 predict() 方法。

您需要在下面的代码中使用转换而不是 fit_transform

tfidf2 = TfidfVectorizer(strip_accents=None, lowercase=False, preprocessor=None, tokenizer=fill, use_idf=True, norm='l2', smooth_idf=True)
y = df.sentiment.values
Xjoker = tfidf2.fit_transform(jokerData)

yhat = Clf.predict(Xjoker)

如下所示:

tfidf2 = TfidfVectorizer(strip_accents=None, lowercase=False, preprocessor=None, tokenizer=fill, use_idf=True, norm='l2', smooth_idf=True)
y = df.sentiment.values
Xjoker = tfidf2.transform(jokerData)

yhat = Clf.predict(Xjoker)