【问题标题】:Logistic regression: X has 667 features per sample; expecting 74869逻辑回归:X 每个样本有 667 个特征;期待 74869
【发布时间】:2020-10-03 20:54:06
【问题描述】:

使用 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 相同数量的功能

【问题讨论】:

    标签: python nlp logistic-regression


    【解决方案1】:

    问题是您的模型是在识别出 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() 方法了。

    【讨论】:

    • 您好丹尼尔,谢谢您的回答。这样做和 df['sentiment'] = "0" 有什么不同?
    • 嗨 Ronnie,使用 df['sentiment'] = "0" 您正在 df 中创建一列并为所有行定义相同的值。您的代码的问题不在于这一点,而在于预处理步骤之后表示单词的列数。最终,您可以使用您的方法创建新列,但您必须对 74,202 个特征 (74,869 - 667) 重复此过程,这是不可行的。我建议的这种方式,您一次创建所有列。
    • 啊,我明白了。非常感谢!
    猜你喜欢
    • 2021-07-15
    • 1970-01-01
    • 2015-11-13
    • 1970-01-01
    • 2015-05-01
    • 2020-03-07
    • 2020-05-21
    • 2019-12-17
    • 2021-11-22
    相关资源
    最近更新 更多