Scikit-Learn/Pandas: 使用保存的模型基于用户输入进行预测

我正在使用Pandas构建一个机器学习模型,但在将我的模型应用于用户输入的测试数据时遇到了困难。我的数据基本上是一个包含两列的dataframe:文本和情感。我希望能够预测用户输入的情感。这是我所做的:

1. 训练/测试模型

# 读取数据集df = pd.read_csv('dataset/dataset.tsv', sep='\t')# 分割训练/测试集test_size = 0.1train_x, valid_x, train_y, valid_y = model_selection.train_test_split(df['text'], df['sentiment'], test_size=test_size)# 对目标变量进行标签编码(即负面 = 0,正面 = 1)encoder = preprocessing.LabelEncoder()train_y = encoder.fit_transform(train_y)valid_y = encoder.fit_transform(valid_y)# 创建一个计数向量化对象count_vect = CountVectorizer(analyzer='word', token_pattern=r'\w{1,}')count_vect.fit(df['text'])# 使用计数向量化对象转换训练和验证数据xtrain_count = count_vect.transform(train_x)xvalid_count = count_vect.transform(valid_x)# 训练模型的函数def train_model(classifier, feature_vector_train, label, feature_vector_valid, name):    # 在分类器上拟合训练数据集    classifier.fit(feature_vector_train, label)    # 将训练好的模型保存到“models”文件夹中    joblib.dump(classifier, 'models/' + name + '.pkl')     # 在验证数据集上预测标签    predictions = classifier.predict(feature_vector_valid)    return metrics.accuracy_score(predictions, valid_y)# 使用计数向量的朴素贝叶斯accuracy = train_model(naive_bayes.MultinomialNB(), xtrain_count, train_y, xvalid_count, 'NB-COUNT')print("NB, Count Vectors: ", accuracy)

一切运行正常,准确率约为80%

2. 在用户输入上测试模型

然后我再次读取保存的模型,获取用户输入并尝试进行预测(用户输入目前在input_text中是硬编码的):

clf = joblib.load('models/NB-COUNT.pkl')dataset_df = pd.read_csv('dataset/dataset.tsv', sep='\t')input_text = 'stackoverflow is the best'  # 我想预测情感的句子test_df = pd.Series(data=input_text)count_vect = CountVectorizer(analyzer='word', token_pattern=r'\w{1,}')count_vect.fit(dataset_df['text'])  # 再次拟合计数向量化器,以便我们可以从test_df中提取特征features = count_vect.transform(test_df)result = clf.predict(features)[0]print(result)

但我得到的错误是“维度不匹配”:

Traceback (most recent call last):File "C:\Users\vdvax\iCloudDrive\Freelance\09. Arabic Sentiment Analysis\test.py", line 20, in <module>result = clf.predict(features)[0]File "C:\Python36\lib\site-packages\sklearn\naive_bayes.py", line 66, in predictjll = self._joint_log_likelihood(X)File "C:\Python36\lib\site-packages\sklearn\naive_bayes.py", line 725, in _joint_log_likelihoodreturn (safe_sparse_dot(X, self.feature_log_prob_.T) +File "C:\Python36\lib\site-packages\sklearn\utils\extmath.py", line 135, in safe_sparse_dotret = a * bFile "C:\Python36\lib\site-packages\scipy\sparse\base.py", line 515, in __mul__raise ValueError('dimension mismatch')ValueError: dimension mismatch

回答:

您得到维度不匹配的错误是因为CountVectorizer转换的输出与拟合估算器中预期的形状在维度上不匹配。这是由于您在测试数据上拟合了一个单独的CountVectorizer造成的。

Scikit-learn提供了一个名为Pipeline的方便接口,它允许您将预处理器和估算器堆叠在一个单一的估算器类中。您应该在您的估算器之前将所有变换器放入Pipeline中,然后您的测试数据将由预拟合的变换器类进行转换。以下是您可以如何拟合一个管道版本的估算器:

from sklearn.pipeline import Pipeline# 接受一个元组列表,其中第一个参数是步骤名称,# 第二个参数是估算器本身。pipe = Pipeline([    ('cvec', CountVectorizer(analyzer='word', token_pattern=r'\w{1,}')),    ('clf', naive_bayes.MultinomialNB())])# 您可以像拟合任何其他估算器一样拟合管道,# 它将按顺序通过每个阶段pipe.fit(train_x, train_y)# 您可以通过将测试数据输入管道来产生预测pipe.predict(test_x)

请注意,这样做您不必创建多个阶段预处理的多个数据副本,因为一个阶段的输出会直接输入到下一个阶段。

现在,对于您的持久化问题。管道可以像其他模型一样被持久化:

joblib.dump(pipe, 'models/NB-COUNT.pkl')loaded_model = joblib.load('models/NB-COUNT.pkl')loaded_model.predict(test_df)

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注