2014-12-04 14 views
5

Attualmente sto spostando l'analisi dei miei dati da R a Python. Quando ridimensiono un set di dati in R vorrei usare R.scale(), che nella mia comprensione farebbe quanto segue: (x-mean (x))/sd (x)Differenza tra R.scale() e sklearn.preprocessing.scale()

Per sostituire quella funzione ho provato a usare sklearn .preprocessing.scale(). Dalla mia comprensione della descrizione fa la stessa cosa. Ciononostante ho eseguito un piccolo file di test e ho scoperto che entrambi questi metodi hanno valori di ritorno diversi. Ovviamente le deviazioni standard non sono le stesse ... Qualcuno è in grado di spiegare perché le deviazioni standard "deviano" l'una dall'altra?

MWE:

# import packages 
from sklearn import preprocessing 
import numpy 
import rpy2.robjects.numpy2ri 
from rpy2.robjects.packages import importr 
rpy2.robjects.numpy2ri.activate() 
# Set up R namespaces 
R = rpy2.robjects.r 


np1 = numpy.array([[1.0,2.0],[3.0,1.0]]) 
print "Numpy-array:" 
print np1 

print "Scaled numpy array through R.scale()" 
print R.scale(np1) 
print "-------" 
print "Scaled numpy array through preprocessing.scale()" 
print preprocessing.scale(np1, axis = 0, with_mean = True, with_std = True) 
scaler = preprocessing.StandardScaler() 
scaler.fit(np1) 
print "Mean of preprocessing.scale():" 
print scaler.mean_ 
print "Std of preprocessing.scale():" 
print scaler.std_ 

uscita: Output generated by the MWE

risposta

3

Sembra avere a che fare con il modo in deviazione standard viene calcolato.

>>> import numpy as np 
>>> a = np.array([[1, 2],[3, 1]]) 
>>> np.std(a, axis=0) 
array([ 1. , 0.5]) 
>>> np.std(a, axis=0, ddof=1) 
array([ 1.41421356, 0.70710678]) 

Da numpy.stddocumentation,

ddof: int, opzionali gradi

Mezzi Delta della Libertà. Il divisore utilizzato nei calcoli è Nddof, dove N rappresenta il numero di elementi. Di default ddof è zero.

A quanto pare, R.scale() usa ddof=1, ma sklearn.preprocessing.StandardScaler() usa ddof=0.

EDIT: (Per spiegare come utilizzare ddof alternativo)

Non sembra essere un modo semplice per calcolare std con ddof alternativo, senza accedere alle variabili dell'oggetto stesso StandardScaler().

sc = StandardScaler() 
sc.fit(data) 
# Now, sc.mean_ and sc.std_ are the mean and standard deviation of the data 
# Replace the sc.std_ value using std calculated using numpy 
sc.std_ = numpy.std(data, axis=0, ddof=1) 
+0

Ehi, grazie per il tuo aiuto! C'è un modo semplice per passare ddof = 1 a sklearn.preprocessing.StandardScaler() o devo scrivere la mia funzione di scala? In realtà non voglio abusare dell'ambiente R, dato che sembra essere più lento della versione sklearn ... Quindi una soluzione in python sarebbe il mio obiettivo. – BenR

+0

Non possibile in 'StandardScaler' così com'è. Il fatto che tu stia utilizzando sklearn mi indica che sei più esperto nell'apprendimento automatico rispetto alle statistiche classiche? Se questo è il caso, sarei curioso di sapere su un caso in cui questa differenza nei gradi di libertà fa davvero la differenza. – eickenberg

+0

Non sembra essere un modo semplice per farlo, senza accedere alle variabili della classe 'StandardScaler()'. Se 'sc = StandardScaler()', quindi 'sc.mean_' e' sc.std_' sono la media e la deviazione standard, i cui valori sono ottenuti da 'sc.fit (data)'. Invece di eseguire 'sc.fit (data)' o dopo aver eseguito lo stesso, potresti usare numpy per calcolare la media e/o std, che ti permetterebbe di calcolare std con ddof = 1. 'sc.std_ = np.std (dati, asse = 0, ddof = 1)'. – Sid