Python脚本错误:“Expected 2D array, got 1D array instead:”?

117

我正在遵循这个教程来进行机器学习预测:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import style

style.use("ggplot")
from sklearn import svm

x = [1, 5, 1.5, 8, 1, 9]
y = [2, 8, 1.8, 8, 0.6, 11]

plt.scatter(x,y)
plt.show()

X = np.array([[1,2],
             [5,8],
             [1.5,1.8],
             [8,8],
             [1,0.6],
             [9,11]])

y = [0,1,0,1,0,1]
X.reshape(1, -1)

clf = svm.SVC(kernel='linear', C = 1.0)
clf.fit(X,y)

print(clf.predict([0.58,0.76]))

我正在使用Python 3.6,但却遇到了“预期是二维数组,而实际传入的是一维数组”错误。我认为这个脚本是为旧版本编写的,但我不知道该如何将其转换为3.6版本。

已经尝试了:

X.reshape(1, -1)

3
哪一行代码出现了错误? - stackoverflowuser2010
13
X = X.reshape(1, -1) 的翻译: X = X.reshape(1, -1)reshape 操作不是原地修改。 - Mad Physicist
2
@stackoverflowuser2010:我猜测最后一行是 clf.predict(<a-1d-thing>),因为 X 已经是二维的了(虽然 reshape 是无用的)。 - Mark Dickinson
@JonTargaryen:您使用的是scikit-learn的哪个版本?这应该不会变成一个错误,直到0.19版本,而这个版本还没有发布。 - Mark Dickinson
2
@JonTargaryen 重塑(reshape)的位置对了,但你丢弃了结果。请把结果赋回给 X - Mad Physicist
显示剩余4条评论
11个回答

214

你只需要使用相同的2D数组,但提供一个(或多个)想要处理的值来调用predict方法。简而言之,您只需替换即可。

[0.58,0.76]

使用

[[0.58,0.76]]

并且它应该能够工作。

编辑:这个答案变得很受欢迎,所以我想多加一点关于ML的解释。简而言之:我们只能在与训练数据(X)具有相同维度的数据上使用predict

在所讨论的示例中,我们向计算机提供了X中的一堆行(每行有2个值),并向其展示了y中的正确响应。当我们想要使用新值进行predict时,我们的程序期望相同 - 一堆行。即使我们只想对一行进行操作(有两个值),那么该行也必须是另一个数组的一部分。


36
但是为什么会有效呢?我不明白问题出在哪里。 - Charlie Parker
2
你如何在更大的数据框上(动态地)实现这个? - Sip
6
为什么必须使用2D数组?背后的原因是什么? - problemofficer - n.f. Monica

23
问题出现在你对数组[0.58, 0.76]进行预测时。在调用predict()之前,请通过重新整形来修复它:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import style

style.use("ggplot")
from sklearn import svm

x = [1, 5, 1.5, 8, 1, 9]
y = [2, 8, 1.8, 8, 0.6, 11]

plt.scatter(x,y)
plt.show()

X = np.array([[1,2],
             [5,8],
             [1.5,1.8],
             [8,8],
             [1,0.6],
             [9,11]])

y = [0,1,0,1,0,1]

clf = svm.SVC(kernel='linear', C = 1.0)
clf.fit(X,y)

test = np.array([0.58, 0.76])
print test       # Produces: [ 0.58  0.76]
print test.shape # Produces: (2,) meaning 2 rows, 1 col

test = test.reshape(1, -1)
print test       # Produces: [[ 0.58  0.76]]
print test.shape # Produces (1, 2) meaning 1 row, 2 cols

print(clf.predict(test)) # Produces [0], as expected

从pandas 0.19.0版本开始,你需要在.reshape(1, -1)之前添加.values ,如下所示:test = test.values.reshape(1, -1) - yeliabsalohcin
我的预测误差出现在LightGDM模型中,我知道如何进行重塑,但是LightGBM创建了自己的lbg.Dataset,不确定如何设置重塑或使LightGDM的预测工作,我的问题已发布在:https://dev59.com/m1_6s4gBPY-HTNNj4PmX - manager_matt

12

我使用以下方法。

reg = linear_model.LinearRegression()
reg.fit(df[['year']],df.income)

reg.predict([[2136]])

7
我遇到了同样的问题,除了我想预测的实例的数据类型是一个panda.Series对象。
好的,我只需要预测一个输入实例。我从我的数据切片中选了它。
df = pd.DataFrame(list(BiogasPlant.objects.all()))
test = df.iloc[-1:]       # sliced it here

在这种情况下,您需要将其转换为一维数组,然后使用reshape函数进行重塑。
 test2d = test.values.reshape(1,-1)

文档中可以看出,values可以将Series转换为numpy数组。

3
我遇到了同样的问题。你只需要将它变成一个数组,而且你还需要加上双方括号,使其成为二维数组的单个元素,因为第一个方括号初始化了数组,第二个方括号使其成为该数组的元素。
所以,简单地用以下语句替换最后一个语句即可:
print(clf.predict(np.array[[0.58,0.76]]))

你正在创建一个数组,所以你想要np.array[[0.58,0.76]),而不是方括号。 - jonincanada

3

只需在两个方括号之间插入参数:

regressor.predict([[values]])

那对我有效


1
我之前也遇到过同样的问题,但是我已经找到了解决方法, 你可以尝试使用reg.predict([[3300]])。 这个API以前可以接受标量值,但现在需要提供一个二维数组。

0

有一个功能会将我的数据框列表转换为系列。我不得不将其转换回数据框列表,然后它就可以工作了。

if type(X) is Series:
    X = X.to_frame()

0
你可以这样做:
np.array(x)[:, None]

0

只需用两个方括号将您的numpy对象括起来,或者反之亦然。

例如:

如果最初您的x = [8,9,12,7,5]

将其更改为x = [[8,9,12,7,5]]

这应该可以解决维度问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接