2012-06-28 10 views
5

Quizás estoy haciendo algo mal mientras z-normalizing mi matriz. ¿Puede alguien mirar esto y sugerir lo que está pasando?Los valores de salida difieren entre R y Python?

En R:

> data <- c(2.02, 2.33, 2.99, 6.85, 9.20, 8.80, 7.50, 6.00, 5.85, 3.85, 4.85, 3.85, 2.22, 1.45, 1.34) 
> data.mean <- mean(data) 
> data.sd <- sqrt(var(data)) 
> data.norm <- (data - data.mean)/data.sd 
> print(data.norm) 
[1] -0.9796808 -0.8622706 -0.6123005 0.8496459 1.7396910 1.5881940 1.0958286 0.5277147 0.4709033 -0.2865819 
[11] 0.0921607 -0.2865819 -0.9039323 -1.1955641 -1.2372258 

En Python usando numpy:

>>> import string 
>>> import numpy as np 
>>> from scipy.stats import norm 
>>> data = np.array([np.array([2.02, 2.33, 2.99, 6.85, 9.20, 8.80, 7.50, 6.00, 5.85, 3.85, 4.85, 3.85, 2.22, 1.45, 1.34])]) 
>>> data -= np.split(np.mean(data, axis=1), data.shape[0]) 
>>> data *= np.split(1.0/data.std(axis=1), data.shape[0]) 
>>> print data 

[[-1.01406602 -0.89253491 -0.63379126 0.87946705 1.80075126 1.64393692 
    1.13429034 0.54623659 0.48743122 -0.29664045 0.09539539 -0.29664045 
    -0.93565885 -1.23752644 -1.28065039]] 

Estoy usando numpy incorrectamente?

+0

¿Por qué está configurando 'data' como un np.array dentro de otro np.array? –

+0

@HughBothwell: Oh ... no me di cuenta. Esto se simplificó a partir de un fragmento de código más grande donde los datos eran una matriz de matrices. – Legend

+1

Solo para el registro, en R se puede normalizar usando 'data.norm <- scale (data, center = TRUE, scale = TRUE)' – Marius

Respuesta

9

Creo que su resultado de NumPy es correcto. Haría la normalización de una manera más simple, sin embargo:

>>> data = np.array([2.02, 2.33, 2.99, 6.85, 9.20, 8.80, 7.50, 6.00, 5.85, 3.85, 4.85, 3.85, 2.22, 1.45, 1.34]) 
>>> data -= data.mean() 
>>> data /= data.std() 
>>> data 
array([-1.01406602, -0.89253491, -0.63379126, 0.87946705, 1.80075126, 
     1.64393692, 1.13429034, 0.54623659, 0.48743122, -0.29664045, 
     0.09539539, -0.29664045, -0.93565885, -1.23752644, -1.28065039]) 

La diferencia entre los dos resultados radica en la normalización: con r como resultado R:

>>> r/data 
array([ 0.96609173, 0.96609173, 0.96609173, 0.96609179, 0.96609179, 0.96609181, 0.9660918 , 0.96609181, 
     0.96609179, 0.96609179,  0.9660918 , 0.96609179, 0.96609175, 0.96609176, 0.96609177]) 

Por lo tanto, los dos resultados son en su mayoría simplemente proporcional el uno al otro. Por lo tanto, es posible que desee comparar las desviaciones estándar obtenidas con R y con Python.

PS: Ahora que lo pienso de ella, puede ser que la variación en NumPy y en I no se define de la misma manera: para N elementos, algunas herramientas se normalizan con N-1 en lugar de N, al calcular la varianza Es posible que desee comprobar esto.

PPS: Esta es la razón de la discrepancia: la diferencia en los factores proviene de dos convenios de normalización diferentes: el factor observado es simplemente sqrt (14/15) = 0,9660917 ... (porque los datos tiene 15 elementos) Por lo tanto, para obtener en R el mismo resultado que en Python, debe dividir el resultado R por este factor.

+0

+1 Gracias por confirmar. ¿Es este enfoque extensible para el caso cuando los datos tienen múltiples matrices dentro (como en mi pregunta, pero múltiples elementos de la matriz)? Además, ¿alguna idea de por qué el resultado de 'R' es diferente? – Legend

+1

@Legend Puedo confirmar que R usa n-1 como denominador, y estaba pensando que esa podría ser la diferencia. Como hombre de estadísticas, en realidad estoy un poco sorprendido de que Numpy use n por defecto, pero estoy seguro de que alguien está diciendo todo lo contrario sobre R en este momento. – joran

+0

@Legend: El parámetro 'axis = 1' que usaste en la respuesta es el camino a seguir, si tienes matrices dentro de matrices. – EOL

14

La razón por la que obtiene diferentes resultados tiene que ver con cómo se calcula la desviación estándar/varianza. R calcula utilizando el denominador N-1, mientras que numpy calcula usando el denominador N. Puede obtener un resultado numpy igual al resultado R usando data.std(ddof=1), que le dice a numpy que use N-1 como denominador al calcular la varianza.

+1

+1 para 'ddof = 1', que es más simple que poner el factor de corrección a mano. – EOL

+0

+1 ¡Gracias por el enfoque! – Legend

Cuestiones relacionadas