回归模型 Pandas
Posted
技术标签:
【中文标题】回归模型 Pandas【英文标题】:Regression model Pandas 【发布时间】:2018-12-18 15:53:05 【问题描述】:我目前正在大学完成我的数据分析课程的作业。我设法完成了前两个部分,没有很多问题(EDA 和文本处理)。我现在需要这样做:
建立一个回归模型,该模型将根据以下因素预测每个产品的评分 与评论中使用的一些非常常见的词相对应的属性 (选择多少字留给您作为决定)。所以,对于你的每一个产品 根据每个单词出现的次数,将有一个长的(ish)属性向量 在对该产品的评论中。您的目标变量是评级。
我发现自己对如何解决这个问题有点迷茫。 Here 是我正在使用的数据集的链接。 Review2
是 Review
的词形化版本。
任何有关如何解决此问题的见解将不胜感激!
P.S:我在这里发帖不是为了获得完整的解决方案……只是朝着正确的方向前进
编辑:
这是我为我的Ordinal回归写的代码(能不能有一些反馈):
# Create word matrix
bow = df.Review2.str.split().apply(pd.Series.value_counts)
rating = df['Rating']
df_rating = pd.DataFrame([rating])
df_rating = df_rating.transpose()
bow = bow.join(df_rating)
# Remove some columns and rows
bow = bow.loc[(bow['Rating'].notna()), ~(bow.sum(0) < 80)]
# Divide into train - validation - test
bow.fillna(0, inplace=True)
rating = bow['Rating']
bow = bow.drop('Rating', 1)
x_train, x_test, y_train, y_test = train_test_split(bow, rating, test_size=0.4, random_state=0)
# Run regression
regr = m.OrdinalRidge()
regr.fit(x_train, y_train)
y_pred = regr.predict(x_test)
scores = cross_val_score(regr, bow, rating, cv=5, scoring='accuracy'))
# Plot
pca = PCA(n_components = 1)
pca.fit(x_validate)
x_validate = pca.transform(x_validate)
plt.scatter(x_validate, y_validate, color='black')
plt.plot(x_validate, y_pred, color='blue', linewidth=1)
plt.show()
这就是剧情的样子(取自here):
是否有可能对代码有一些反馈,并可能以更好、更丰富的方式来绘制结果(我不太了解回归是否表现良好)
【问题讨论】:
嗨,您要求 SO 为您编写代码。虽然许多用户很乐意提供帮助,但您应该展示您为解决问题所做的工作 - 即向我们展示您认为可以如何完成的一些代码并制作minimal, complete and verifiable example (MCVE)。您已标记此帖子熊猫,所以这是我最喜欢的答案,解释如何制作MCVE in pandas。 @tobsecret 如果有的话,我会提供一些代码。我的问题实际上是关于如何开始解决这个问题,我真的不知道如何在words
和ratings
之间建立关系。我是否应该使用评论中出现的前 50 个单词并与它们各自的平均评分相关联?我只是不知道如何开始;因此我无法提供任何代码。我只是在寻找“逻辑帮助”,而不是太多“实际帮助”
@tobsecret,因为 OP 要求“只是朝着正确的方向推动”与“您要求 SO 为您编写代码”非常不同,我不明白您的评论。你能澄清一下你评论的那部分吗?
在我评论后编辑了正确方向的推动,感谢您的澄清。
words
和 ratings
之间的关系正是您的模型所涵盖的内容。由于您正在处理一个序数变量(这意味着 5 的评级与 4 的评级比它与 3 的评级更相似),建模问题是序数回归的问题。您已使用 scikit-learn
标签标记了该问题,但您的问题尚不清楚您是否必须以某种方式使用该框架。无论如何,看起来pythonhosted.org/mord 有一个受 scikit-learn 启发的 API 设计,因此可能很有用。否则手动实现它是一个很好的练习。
【参考方案1】:
建立一个回归模型来预测每个人的评分 基于与一些非常常见的词相对应的属性的产品 在评论中使用(选择留给您的字数作为 决定)。因此,对于每个产品,您将有一个长的(ish)向量 属性基于每个单词在评论中出现的次数 这个产品。您的目标变量是评分。
让我们把它拆成几块!
因此,对于每个产品,您将有一个长的(ish)向量 属性基于每个单词在评论中出现的次数 这个产品。
这是一个词袋模型,这意味着您必须为您的 words 列或 review 2 列创建一个矩阵表示(仍然保存在 pd.DataFrame 中),并且有一个问题询问如何做到这一点这里:
How to create a bag of words from a pandas dataframe
以下是如何使用 Review2 列创建该矩阵的最小示例:
In [12]: import pandas as pd
In [13]: df = pd.DataFrame("Review2":['banana apple mango', 'apple apple strawberry'])
In [14]: df
Out[14]:
Review2
0 banana apple mango
1 apple apple strawberry
In [15]: df.Review2.str.split()
Out[15]:
0 [banana, apple, mango]
1 [apple, apple, strawberry]
Name: Review2, dtype: object
In [16]: df = df.Review2.str.split().apply(pd.Series.value_counts) # this will produce the word count matrix
In [17]: df
Out[17]:
apple banana mango strawberry
0 1.0 1.0 1.0 NaN
1 2.0 NaN NaN 1.0
词袋模型只计算一个词在感兴趣的文本中出现的频率,不考虑位置,并以这种方式将一组文本表示为一个矩阵,其中每个文本由一行表示,而列显示所有单词的计数。
[...] 基于与一些非常常见的单词相对应的属性 在评论中使用(选择留给您的字数作为 决定)。
现在您已经有了矩阵表示(行是产品,列是每个唯一单词的计数),您可以将矩阵过滤到最常见的单词。我鼓励你看看字数分布的样子。我们将为此使用seaborn 并像这样导入它:
import seaborn as sns
鉴于保存字数矩阵的 pd.DataFrame 称为 df,sns.distplot(df.sum())
应该可以解决问题。选择一些似乎保留了大量计数但不包括许多低计数单词的截止值。它可以是任意的,现在并不重要。
您的字数矩阵是您的输入数据,或者也称为预测变量。在机器学习中,这通常称为输入矩阵或向量X
。
您的目标变量是评分。
输出变量或目标变量是评分列。在机器学习中,这通常称为输出向量y
(请注意,有时这也可以是输出矩阵,但最常见的是输出向量)。
这意味着我们的模型尝试调整其参数以将每行的字数数据映射到相应的评分值。
Scikit-learn 提供了很多机器学习模型,例如 logistic regression,它们采用 X 和 y 进行训练,并且具有非常统一的界面。 Jake Vanderplas's Python Data Science Handbook 很好地解释了 Scikit-learn 界面,并向您展示了如何使用它来解决回归问题。
编辑:我们在这里使用逻辑回归,但正如 fuglede 正确指出的那样,逻辑回归忽略了评级是在设定的范围内。为此,您可以使用 mord.OrdinalRidge,其 API 的工作方式与 scikit-learn 非常相似。
在训练模型之前,您应该将数据集拆分为训练集、测试集和验证集 - 一个好的比例可能是 60:20:20。 通过这种方式,您将能够在您的训练集上训练您的模型并评估它对您的测试数据集的预测效果,以帮助您调整模型参数。通过这种方式,您将知道您的模型何时过度拟合您的训练数据,以及何时真正为该任务生成了一个良好的通用模型。这种方法的问题在于,如果您经常调整模型参数,您仍然可以过度拟合您的训练数据。
这就是我们有一个验证集的原因 - 这是为了确保我们不会在不知情的情况下意外地将模型的参数过度拟合到我们的训练和测试集。我们通常只对验证集进行一次测试,以避免对其过度拟合,而且它仅用于最终的模型评估步骤。
Scikit-learn 也有一个功能:train_test_split
train_test_split 但是只进行一次拆分,因此您首先将数据集拆分为 60:40,然后将 40 拆分为 50:50 为测试和验证集。
您现在可以在训练数据上训练不同的模型,并在测试集上使用模型的预测函数对其进行测试。一旦你认为你做得很好并且你的模型足够好,你现在可以在你的验证集上测试它。
【讨论】:
普通逻辑回归 (a lasklearn.linear_model.LogisticRegression
) 将完全忽略评级的序数性质。这可以通过比例优势模型(也称为有序逻辑回归)来捕捉——参见en.wikipedia.org/wiki/Ordinal_regression;我不相信 scikit-learn 提供了开箱即用的功能,但很容易找到 Python 实现,参见。例如***.com/questions/28035216/ordered-logit-in-python
非常感谢您对问题的见解。明天早上就开始做!再次感谢!
@tobsecret 嗨,当我尝试做 sns.distplot(df['BOW'].sum())
时,BOW
是我的专栏,里面有一堆字我收到这个错误:unsupported operand type(s) for /: 'Counter' and 'int'
你有什么见解吗?
正如我在回答中所写的,在 df 中,列是单词,行是单独的评论,每个单元格都包含该评论中该单词的计数。当您致电df.sum()
时,它会给您一个pd.Series
,其中包含每个单词的总计数。我链接到的关于如何创建词袋模型的答案就是问题所在 - 您可能使用了该答案中的选项 1:他们使用 Counter。该答案只是为了让您大致了解如何将一堆单词转换为字数。让我在我的答案中添加一个最小的例子,让我的意思更清楚。
添加了修改,请看一下 - 希望现在更清楚了。以上是关于回归模型 Pandas的主要内容,如果未能解决你的问题,请参考以下文章
如何使用for循环或条件在pandas数据框的子集中创建多个回归模型(statsmodel)?
构建多回归模型会引发错误:`Pandas 数据转换为对象的 numpy dtype。使用 np.asarray(data) 检查输入数据。`
在 pandas 数据框中使用最大似然估计器的自动回归 (AR) 模型:correlate() 得到了一个意外的关键字参数“旧行为”