2016-04-19 17 views
5

Ho un set di dati e voglio applicare gli allarmi naive su quello. Sarò convalidare usando la tecnica K-fold. I miei dati hanno due classi e hanno ordinato che, se il mio set di dati ha 100 righe, i primi 50 sono di una classe e i successivi 50 sono di seconda classe. Quindi, prima voglio mischiare i dati e poi formare casualmente le pieghe K. Il problema è che quando sto provando a randomSplit su RDD, sta creando RDD di diverse dimensioni. Mio codice e un esempio di set di dati è il seguente:Split RDD per convalida K-fold: pyspark

documentDF = sqlContext.createDataFrame([ 
    (0,"This is a cat".lower().split(" "),), 
    (0,"This is a dog".lower().split(" "),), 
    (0,"This is a pig".lower().split(" "),), 
    (0,"This is a mouse".lower().split(" "),), 
    (0,"This is a donkey".lower().split(" "),), 
    (0,"This is a monkey".lower().split(" "),), 
    (0,"This is a horse".lower().split(" "),), 
    (0,"This is a goat".lower().split(" "),), 
    (0,"This is a tiger".lower().split(" "),), 
    (0,"This is a lion".lower().split(" "),), 
    (1,"A mouse and a pig are friends".lower().split(" "),), 
    (1,"A pig and a dog are friends".lower().split(" "),), 
    (1,"A mouse and a cat are friends".lower().split(" "),), 
    (1,"A lion and a tiger are friends".lower().split(" "),), 
    (1,"A lion and a goat are friends".lower().split(" "),), 
    (1,"A monkey and a goat are friends".lower().split(" "),), 
    (1,"A monkey and a donkey are friends".lower().split(" "),), 
    (1,"A horse and a donkey are friends".lower().split(" "),), 
    (1,"A horse and a tiger are friends".lower().split(" "),), 
    (1,"A cat and a dog are friends".lower().split(" "),) 
], ["label","text"]) 

from pyspark.mllib.classification import NaiveBayes, NaiveBayesModel 
from pyspark.mllib.linalg import Vectors 
from pyspark.ml.feature import CountVectorizer 
from pyspark.mllib.regression import LabeledPoint 

def mapper_vector(x): 
    row = x.text 
    return LabeledPoint(x.label,row) 

splitSize = [0.2]*5 
print("splitSize"+str(splitSize)) 
print(sum(splitSize)) 
vect = documentDF.map(lambda x: mapper_vector(x)) 
splits = vect.randomSplit(splitSize, seed=0) 

print("***********SPLITS**************") 
for i in range(len(splits)): 
    print("split"+str(i)+":"+str(len(splits[i].collect()))) 

This uscite di codice:

splitSize[0.2, 0.2, 0.2, 0.2, 0.2] 
1.0 
***********SPLITS************** 
split0:1 
split1:5 
split2:3 
split3:5 
split4:6 

Il documentDF avuto 20 righe, ho voluto 5 campioni esclusivi distinti da questo insieme di dati che hanno la stessa dimensione. Tuttavia, si può vedere che tutte le divisioni hanno dimensioni diverse. Che cosa sto facendo di sbagliato?

Modifica: Secondo zero323 non sto facendo niente di sbagliato. Quindi, se voglio ottenere i risultati finali (come descritto) senza utilizzare ML CrossValidator, cosa devo cambiare? Inoltre, perché i numeri sono diversi? Se ogni divisione ha una ponderazione uguale, non dovrebbero avere un numero uguale di file? Inoltre, c'è un altro modo per randomizzare i dati?

risposta

3

Non stai facendo nulla di sbagliato. randomSplit semplicemente non fornisce garanzie rigide sulla distribuzione dei dati. Sta usando BernoulliCellSampler (vedi How does Sparks RDD.randomSplit actually split the RDD) e le frazioni esatte possono differire da correre a correre. Questo è un comportamento normale e dovrebbe essere perfettamente accettabile su qualsiasi insieme di dati reali in cui le differenze dovrebbero essere statisticamente insignificanti.

Su un lato non Spark ML fornisce già un CrossValidator che può essere utilizzato con ML Pipelines (vedere How to cross validate RandomForest model? per l'utilizzo di esempio).

+0

Quindi, se voglio ottenere i risultati finali senza utilizzare ML CrossValidator, cosa devo cambiare? Inoltre, perché i numeri sono diversi? Se ogni divisione ha una ponderazione uguale, non dovrebbero avere un numero uguale di file? Hai detto che le frazioni esatte possono differire da correre a correre, ma ottengo le stesse frazioni ogni volta che eseguo il codice. C'è un altro modo per randomizzare i dati? – harshit

+0

Ottieni esattamente le stesse frazioni perché usi seme RNG fisso. Le frazioni ottenute potrebbero non essere precise perché si tratta di campioni casuali ed è piuttosto difficile ottenere valori esatti in parallelo senza compromettere le proprietà statistiche. – zero323

+0

Tuttavia, Spark's CrossValidator non è stratificato. –