【问题标题】:Can't do linear regression in scikit-Learn due to "reshaping" issue由于“重塑”问题,无法在 scikit-Learn 中进行线性回归
【发布时间】:2018-05-25 11:55:02
【问题描述】:

我有一个包含两列的简单 CSV:

  1. ErrorWeek(一年中的周数)
  2. ErrorCount(给定一周内的错误数)

我将 CSV 数据读入 pandas 数据框,如下所示:

df = pd.read_csv("Errors.csv", sep=",")

df.head() 显示:

   ErrorWeek  ErrorCount
0          1          80
1          2         118
2          3         249
3          4         397
4          5         159

到目前为止一切顺利。

然后,我创建一个测试/训练拆分,如下所示:

X_train, X_test, y_train, y_test = train_test_split(
    df['ErrorWeek'], df['ErrorCount'], random_state=0)

目前没有错误。

但是,我随后创建了一个线性回归对象并尝试拟合数据。

# Create linear regression object
regr = linear_model.LinearRegression()

# Train the model using the training sets
regr.fit(X_train, y_train)

这里我确实收到错误:“使用 array.reshape(-1, 1) 重塑您的数据”

--

查看 X_Test 和 y_Test 的形状,我得到了看起来像两个一维“数组”的东西:

X_train shape: (36,)
y_train shape: (36,)

--

我花了很多时间试图弄清楚这一点,但我是 Pandas、Python 和 scikit-learn 的新手。

我正在读取二维数据,但 Pandas 不这么看。

具体来说,我需要做什么?

谢谢,

【问题讨论】:

    标签: pandas scikit-learn


    【解决方案1】:

    X_train.reshape(-1,1) 无法使用,因为它是一个系列,您需要使用 X_train = X_train.values.reshape(-1,1)

    【讨论】:

      【解决方案2】:

      显然 sklearn 希望 x 成为 pandas.core.frame.DataFrame,因为它无法区分具有 n 个样本的单个特征或具有一个样本的 n 个特征。 相反,y 可以是一列,即 pandas.core.series.Series。 因此,在您的示例中,您应该将 x 转换为 pandas.core.frame.DataFrame。

      正如@MaxU 已经指出的那样:

      x=df[['ErrorWeek']]   # double brakets
      y=df['ErrorCount']    # single brakets
      X_train, X_test, y_train, y_test = train_test_split(x, y, random_state=0)
      

      【讨论】:

        【解决方案3】:

        在做:

        X_train, X_test, y_train, y_test = train_test_split(
                 df['ErrorWeek'], df['ErrorCount'], random_state=0)
        

        将生成一维的所有输出数组,因为您正在为 X 和 y 选择单列值。

        现在,当您传递 [n,] 的一维数组时,Scikit-learn 无法确定您传递的是多列的一行数据,还是单列的多个数据样本。即 sklearn 可能无法仅根据 X 数据推断其 n_samples=n 和 n_features=1 还是其他方式(n_samples=1 和 n_features=n)。

        因此它要求您将提供的一维数据重新整形为形状为 [n_samples, n_features] 的二维数据

        现在有多种方法可以做到这一点。

        • 你可以按照 scikit-learn 所说的去做:

          X_train = X_train.reshape(-1,1) X_test = X_test.reshape(-1,1)

        reshape第二位的1表示只有一列,-1表示自动检测这一列的行数。

        • 按照@MaxU 和@Wen 在其他答案中的建议进行操作

        【讨论】:

        • 谢谢。这个 DID 工作的变体! :) 我基本上为所有 X_train、y_train、y_test 做了 X_train = np.array(X_train).reshape(-1,1)。感谢您的回答。
        • @Morkus 你不需要重塑y_trainy_test。它们应该只是一维数组。
        • 如果我注释掉这两行,我得到:“ValueError: Expected 2D array, got 1D array instead:” 不知道为什么,但错误发生在 predict 方法调用上。谢谢。
        • @Morkus y_trainy_test 不会发送到 predict() 方法。请更新方法中的代码和错误。 X_trainX_test 需要重塑,但 y_trainy_test 不需要重塑
        【解决方案4】:

        试试这个:

        X_train, X_test, y_train, y_test = train_test_split(
            df[['ErrorWeek']], df['ErrorCount'], random_state=0)
        

        PS 注意额外的方括号:df[['ErrorWeek']]

        【讨论】:

        • 感谢您的回复。我对双方括号及其含义有点困惑,但这也不起作用。
        【解决方案5】:

        更改您的 fit 部分

        regr.fit(X_train[:,None], y_train)
        

        【讨论】:

        • 谢谢,但这不起作用。当你有类似 [:, None] 的东西时,冒号是什么意思?
        • @Morkus 它只是将数组转换为 ndarray
        猜你喜欢
        • 2018-07-31
        • 2015-12-15
        • 2016-05-10
        • 2017-12-31
        • 2016-05-16
        • 2019-05-14
        • 2017-12-25
        • 2017-03-26
        • 2016-08-27
        相关资源
        最近更新 更多