我已经训练了一个线性回归模型,sklearn,获得5星评级,这已经足够了。我使用Doc2vec来创建我的向量,并保存了该模型。然后我将线性回归模型保存到另一个文件。我要做的是加载Doc2vec模型和线性回归模型,并尝试预测另一个评论。
这个预测有一些非常奇怪的东西:无论输入是什么,它总是预测在2.1-3.0左右。
事实是,我有一个建议,它预测平均值为5(2.5 +/-),但事实并非如此。我在训练模型时打印了预测值和测试数据的实际值,它们的范围通常为1-5。所以我的想法是,代码的加载部分有问题。这是我的加载代码:
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
from bs4 import BeautifulSoup
from joblib import dump, load
import pickle
import re
model = Doc2Vec.load('../vectors/750000/doc2vec_model')
def cleanText(text):
text = BeautifulSoup(text, "lxml").text
text = re.sub(r'\|\|\|', r' ', text)
text = re.sub(r'http\S+', r'<URL>', text)
text = re.sub(r'[^\w\s]','',text)
text = text.lower()
text = text.replace('x', '')
return text
review = cleanText("Horrible movie! I don't recommend it to anyone!").split()
vector = model.infer_vector(review)
pkl_filename = "../vectors/750000/linear_regression_model.joblib"
with open(pkl_filename, 'rb') as file:
linreg = pickle.load(file)
review_vector = vector.reshape(1,-1)
predict_star = linreg.predict(review_vector)
print(predict_star)
您的示例代码显示joblib.dump
和joblib.load
的导入 - 即使在此摘录中均未使用。并且,您的文件的后缀暗示该模型最初可能与joblib.dump()
保存,而不是香草泡菜。
但是,此代码显示文件仅通过普通的pickle.load()
加载 - 这可能是错误的来源。
The joblib.load()
docs建议它的load()
可以做一些事情,比如从自己的dump()
创建的多个独立文件中加载numpy数组。 (奇怪的是,dump()
文档在这方面不太清楚,但据说dump()
有一个返回值,可能是一个文件名列表。)
您可以检查文件的保存位置以查找看似相关的额外文件,并尝试使用joblib.load()
而不是plain-pickle,以查看是否加载了linreg
对象的更多功能/更完整版本。
(更新:我忽略了在.split()
之后在问题代码中完成的.cleanText()
标记化,所以这不是真正的问题。但是要保持答案以供参考,因为真正的问题是在评论中发现的。)
很常见的是,当Doc2Vec
为infer_vector()
提供一个简单的字符串时,用户会得到神秘的弱结果。 Doc2Vec
infer_vector()
需要一个单词列表,而不是字符串。
如果提供一个字符串,该函数将把它看作一个单字符的单词 - 根据Python的字符串建模作为字符列表,以及字符和单字符串的类型混合。大多数这些单字符的单词可能都不为模型所知,那些可能是 - 'i'
,'a'
等 - 并不是很有意义。因此推断的doc-vector将是弱的和无意义的。 (而且,这样的矢量,用于线性回归,并不总是给出一个中等预测值。)
如果您将文本分成预期的单词列表,您的结果应该会有所改善。
但更一般地说,提供给infer_vector()
的词语应该经过预处理并准确地标记,但是培训文件是。
(对你是否正确进行推理的公平的健全性测试是推断你的一些训练文件的向量,然后向Doc2Vec
模型询问最接近这些重新推断的向量的文档标签。一般来说,同一文件的培训 - 时间标记/ ID应该是最重要的结果,或者至少是前几个中的一个。如果不是,则数据,模型参数或推断中可能存在其他问题。)