Error en la secuencia de comandos de Python "Matriz 2D esperada, en su lugar obtuvo una matriz 1D"

81

Estoy siguiendo este tutorial para hacer esta predicción de ML:

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]))

Estoy usando Python 3.6 y aparece el error "Matriz 2D esperada, tengo una matriz 1D en su lugar:" Creo que el script es para versiones anteriores, pero no sé cómo convertirlo a la versión 3.6.

Ya prueba con:

X.reshape(1, -1)
JonTargaryen
fuente
3
¿Qué línea produce el error?
stackoverflowuser2010
10
X = X.reshape(1, -1). La remodelación no está en su lugar.
Mad Physicist
2
@ stackoverflowuser2010: supongo que la última línea clf.predict(<a-1d-thing>), ya Xque ya es bidimensional (a reshapepesar de que es inútil ).
Mark Dickinson
@MarkDickinson Sí, la última línea es.
JonTargaryen
2
@JonTargaryen la remodelación está en el lugar correcto, pero estás descartando el resultado. Asignar el resultado de nuevo a X.
Mad Physicist

Respuestas:

156

Se supone que debe proporcionar el predictmétodo con la misma matriz 2D, pero con un valor que desea procesar (o más). En resumen, puede simplemente reemplazar

[0.58,0.76]

Con

[[0.58,0.76]]

Y debería funcionar.

EDITAR: Esta respuesta se hizo popular, así que pensé en agregar un poco más de explicación sobre ML. La versión corta: solo podemos usar predicten datos que tengan la misma dimensionalidad que los datos de entrenamiento ( X).

En el ejemplo en cuestión, le damos a la computadora un montón de filas X(con 2 valores cada una) y le mostramos las respuestas correctas en y. Cuando queremos predictusar nuevos valores, nuestro programa espera lo mismo: un montón de filas. Incluso si queremos hacerlo en una sola fila (con dos valores), esa fila tiene que ser parte de otra matriz.

Ofer Sadan
fuente
31
pero ¿por qué funciona eso? No entiendo cuál es el problema.
Charlie Parker
2
¿Cómo se logra esto para marcos de datos más grandes? (dinámicamente)
Sip
3
¿Por qué tiene que ser una matriz 2D? ¿Cuál es el razonamiento detrás de esto?
problemofficer
18

El problema se produce cuando ejecuta la predicción en la matriz [0.58,0.76]. Solucione el problema modificándolo antes de llamar 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
stackoverflowuser2010
fuente
7

Utilizo el siguiente enfoque.

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

reg.predict([[2136]])
Vikas Rathour
fuente
5

Enfrenté el mismo problema, excepto que el tipo de datos de la instancia que quería predecir era un panda.Seriesobjeto.

Bueno, solo necesitaba predecir una instancia de entrada. Lo tomé de una porción de mis datos.

df = pd.DataFrame(list(BiogasPlant.objects.all()))
test = df.iloc[-1:]       # sliced it here

En este caso, deberá convertirlo en una matriz 1-D y luego reshape.

 test2d = test.values.reshape(1,-1)

De los documentos , valuesconvertirá Series en una matriz numpy.

devsaw
fuente
2

Me enfrenté al mismo problema. Solo tiene que convertirlo en una matriz y, además, debe poner corchetes dobles para convertirlo en un solo elemento de la matriz 2D, ya que el primer corchete inicializa la matriz y el segundo lo convierte en un elemento de esa matriz.

Así que simplemente reemplace la última declaración por:

print(clf.predict(np.array[[0.58,0.76]]))
Satyam Mittal
fuente
1

Estaba enfrentando el mismo problema antes, pero de alguna manera encontré la solución, puede intentarlo reg.predict([[3300]]).

La API solía permitir el valor escalar, pero ahora debe proporcionar una matriz 2D.

FASIH AHMED
fuente
1

Simplemente inserte el argumento entre un corchete doble:

regressor.predict ([[valores]])

eso funcionó para mi

Camunatas
fuente
0

Con una característica, mi lista de marcos de datos se convierte en una serie. Tuve que convertirlo de nuevo a una lista de Dataframe y funcionó.

if type(X) is Series:
    X = X.to_frame()
Rey Arturo
fuente
-1

La matriz X e Y de Variable Independiente y Variable Dependiente respectivamente a DataFrame de int64 Type para que se convierta de una matriz 1D a una matriz 2D. Es decir, X = pd.DataFrame (X) e Y = pd.dataFrame (Y) donde pd es de la clase pandas en python. y, por lo tanto, el escalado de funciones no conduce a ningún error.

Chahat Agarwal
fuente