You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Web端情感分析项目报错:输入特征数与MultinomialNB预期不符

解决MultinomialNB特征数不匹配问题

报错信息

ValueError: X has 5 features, but MultinomialNB is expecting 15940 features as input

问题场景

开发Web端讽刺检测项目时,加载训练好的MultinomialNB模型后,处理用户输入文本出现特征数不匹配,导致模型无法正常预测。

问题原因

训练模型时,CountVectorizer是基于训练数据集构建的词汇表(包含15940个特征)。但当前代码在预测阶段重新初始化了CountVectorizer,并调用fit_transform方法——该方法会基于用户输入的少量文本重新构建词汇表(仅生成5个特征),和模型训练时的词汇表完全不一致,因此出现特征数不匹配的报错。

解决步骤

  1. 保存训练阶段的CountVectorizer
    训练模型时,除了保存模型文件,还要将用于特征提取的CountVectorizer一并保存。训练代码示例:

    # 初始化训练用的CountVectorizer
    vt_train = CountVectorizer()
    # 用训练数据拟合并转换特征
    X_train = vt_train.fit_transform(train_texts)
    # 训练MultinomialNB模型
    model = MultinomialNB()
    model.fit(X_train, train_labels)
    # 保存模型和vectorizer到本地
    pkl.dump(model, open('newOwnModelNV.pkl', 'wb'))
    pkl.dump(vt_train, open('count_vectorizer.pkl', 'wb'))
    
  2. 在Flask项目中加载保存的CountVectorizer
    替换原代码中仅加载模型的部分,同时加载训练好的vectorizer:

    # 加载训练好的模型和CountVectorizer
    model = pkl.load(open(r'C:\Users\TEST\Desktop\SENTIMENT\code\main\newOwnModelNV.pkl', 'rb'))
    vt = pkl.load(open(r'C:\Users\TEST\Desktop\SENTIMENT\code\main\count_vectorizer.pkl', 'rb'))
    
  3. 修改预测阶段的特征转换逻辑
    预测时不能使用fit_transform(会重新构建词汇表),改用transform方法,基于已有词汇表转换用户输入:

    # 移除原代码中的vt = CountVectorizer()
    # 直接用加载好的vt转换预处理后的文本
    newData = vt.transform(data1).toarray()
    

修改后的完整代码

import pickle as pkl
import re
import nltk
import numpy as np

from sklearn.feature_extraction.text import CountVectorizer
from nltk.corpus import wordnet
from flask import Flask, request, render_template

# 加载训练好的模型和CountVectorizer
model = pkl.load(open(r'C:\Users\TEST\Desktop\SENTIMENT\code\main\newOwnModelNV.pkl', 'rb'))
vt = pkl.load(open(r'C:\Users\TEST\Desktop\SENTIMENT\code\main\count_vectorizer.pkl', 'rb'))

app = Flask(__name__)

@app.route('/')
def hello_world():
    return render_template("home.html")

@app.route('/predict',methods=['POST','GET'])
def predict():
    # 获取用户输入
    data = [str(x) for x in request.form.values()]
    
    # 文本预处理函数
    stopwords = nltk.corpus.stopwords.words('english')
    def parser(x):
        x = re.sub('[^a-z\s]', '', x.lower()) 
        x = [w for w in x.split() if w not in set(stopwords)]
        x = [w for w in x if wordnet.synsets(w)]
        return ' '.join(x)

    # 应用预处理
    data1 = [parser(x) for x in data]

    # 用训练好的vectorizer转换特征
    newData = vt.transform(data1).toarray()

    prediction = model.predict_proba(newData)
    output = '{0:.{1}f}'.format(prediction[0][1], 2)
    
    if float(output) > 0.8:
        return render_template('home.html', pred=f'High probability of sarcasm: {output}')
    else:
        return render_template('home.html', pred=f'Low probability of sarcasm: {output}')

if __name__ == '__main__':
    app.run(debug=True)

内容的提问来源于stack exchange,提问作者Mohd Nazzim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 09:25:44