【问题标题】:Linear regression load model doesn't predict as expected线性回归负载模型未按预期进行预测
【发布时间】:2019-08-08 01:45:52
【问题描述】:

我已经使用 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)

【问题讨论】:

  • 这可能更多地属于数据科学堆栈交换
  • 您对平均响应的预测可能意味着两件事:(1)您的模型没有足够的数据可供学习; (2)你的模型太死板(高度偏颇)。对于第一种情况,您需要更多数据。其次,您可以尝试更灵活的模型,例如随机森林,而不是 linreg。
  • @Sergey Bushmanov 数据是 750000 条评论(来自每颗星的 150000 条评论),所以我认为有足够的数据。问题是,当我预测测试数据时,我实际上打印了实际评级和预测评级,它们不在平均响应附近。如果发生这种情况(我的模型太死板),那么我最后的预测将是 2.5 左右。但他们不是。唯一的问题(我认为)是我加载模型或重塑。我如何确定我的模型是否如您所说的那样过于僵化?
  • 我不太明白你的意思。首先你说:“无论输入什么,它总是预测 2.1-3.0 左右。”然后你继续:“当我预测测试数据时,我实际上打印了实际评级和预测评级,它们不在平均响应附近”。这两者相互矛盾,不是吗?如果您想要一些与平均值不同的东西,请查看从您的测试中产生不同结果的原因并提供给您的预测算法。至于检查您的模型是否过于偏颇,只需尝试 RF,看看您是否获得更明智(“准确”?)的结果。
  • “无论输入什么”是指加载模型时。 “当我预测测试数据时”是指在训练模型并预测测试数据之后。对不起:D

标签: python machine-learning scikit-learn linear-regression doc2vec


【解决方案1】:

您的示例代码显示了joblib.dumpjoblib.load 的导入——尽管在此摘录中两者都没有使用。而且,文件的后缀暗示该模型最初可能是用joblib.dump() 保存的,而不是香草泡菜。

但是,此代码显示文件仅通过普通 pickle.load() 加载——这可能是错误的根源。

The joblib.load() docs 建议它的load() 可以做一些事情,比如从它自己的dump() 创建的多个单独文件中加载numpy 数组。 (奇怪的是,dump() 文档对此不太清楚,但据说dump() 的返回值可能是文件名的列表。)

您可以检查文件的保存位置以查找似乎相关的额外文件,并尝试使用joblib.load() 而不是plain-pickle,以查看它是否加载了您的@987654332 的功能更强大/更完整的版本@对象。

【讨论】:

    【解决方案2】:

    更新:我忽略了.split() 987654321 .cleanText(),所以这不是真正的问题。但是保持答案参考和因为真实问题是在CMETS中发现的。)

    非常常见,用户从Doc2Vec 987654324 infer_vector()时获得神秘疲软的结果。 Doc2Vec infer_vector()要求单词列表 not em>一个字符串。

    如果提供字符串,则该函数将将其视为一个字符列表 - 每个Python的字符串的建模作为字符列表,以及字符和一个字符串的键入Conflation。大多数这些一个字符的词语可能是模型不知道的,以及可能是 - 'i''a'等 - 不是很有意义。所以推断的Doc-载体将弱且毫无意义。 (而且,它并不令人惊讶的这样一个向量,馈送到你的线性回归,始终给出了中间预测值。)

    如果将文本闯入预期的单词列表,结果应提高结果。

    但更一般地,提供给infer_vector()的单词应该是预处理的,令牌化完全然而培训文件是。

    (适当的理智测试是否正确地进行推理是推断为您的一些培训文件的向量,然后询问最接近这些重新推断向量的Doc标签的Doc2Vec Model。一般来说,相同的文档的培训时间标签/ ID应该是顶部结果,或者至少一个页面中的至少一个。如果不是,则数据,模型参数或推断中可能存在其他问题。)

    【讨论】:

    • 本文以与我的培训数据相同的方法预处理。至于Infum_vector,我知道它需要一个单词列表,这就是我在预处理后在该句子结束时拆分它的原因。请下次仔细阅读代码。这里的问题是我加载模型或载体的重写。 span>
    • 抱歉,我没有注意到。这是一个非常常见的错误,您的培训代码未显示,您的split()在我的代码的显示中修剪了滚动区域。祝你好运弄清楚! span>
    • 它可能不是您的加载或重塑 - 但您的Doc2Vec或回归培训中的东西。您可能希望将该代码添加到问题中。 span>
    • hmm,实际上是您使用的方式@ 987654333,但文件的文件扩展名为.joblib是一点点腥。如果joblib.dump()用于保存,则应使用joblib.load()加载(并务必将任何其他文件与主文件一起转储一起)。 span>
    • thaaaaaaaank你!它只是使用Save / Load Joblib库工作!但我希望你用Joblib和泡菜在这里放在这里的另一个答案,所以我可以把它标记为一个合适的答案....谢谢我的理智:P SPAN>
    猜你喜欢
    • 2017-11-30
    • 2017-03-06
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2016-05-15
    • 2014-05-01
    • 1970-01-01
    • 2015-06-19
    相关资源
    最近更新 更多