2016-07-27 1 views
1

J'ai environ 3000 objets où chaque objet est associé à un nombre. Je veux diviser ces objets au hasard dans la formation et les tests de données avec une formation de 70% et 30% de test. Mais, je veux les diviser en fonction du nombre associé à chaque objet, mais pas en fonction du nombre d'objets.Séparation aléatoire des données d'entraînement et de test

Un exemple, en supposant que mon ensemble de données contient 5 objets.

Obj 1 => 200 
Obj 2 => 30 
Obj 3 => 40 
Obj 4 => 20 
Obj 5 => 110 

Si je les partagerai avec près de 70% rapport -30%, mon ensemble de formation devrait être

Obj 2 => 30 
Obj 3 => 40 
Obj 4 => 20 
Obj 5 => 110 

et mes tests ensemble serait

Obj 1 => 200

Si je Je les diviserai à nouveau, je devrais avoir un autre jeu d'entraînement et d'essai qui se rapproche du ratio de 70-30. Je comprends que la division ci-dessus ne me donne pas la séparation pure 70-30 mais tant que ça se rapproche, c'est acceptable.

Existe-t-il des méthodes/packages prédéfinis pour cela en Python?

+0

Copie possible de [Numpy: comment diviser/partitionner un ensemble de données (tableau) en ensembles de données d'apprentissage et de test pour, par exemple, validation croisée?] (Http://stackoverflow.com/questions/3674409/numpy-how-to -split-partition-a-dataset-array-into-training-and-datasets) – Zafi

+0

Juste pour le compte rendu, c'est probablement une très mauvaise idée. En règle générale, vous souhaitez conserver le même niveau d'entraînement afin de ne pas entraîner vos données de test. –

Répondre

2

En supposant que je comprends bien votre question, ma suggestion serait ceci:

from random import shuffle 
sum = sum([obj.count for obj in obj_list]) #Get the total "count" of all the objects, O(n) 
shuffle(obj_list) 
running_sum = 0 
i = 0 
while running_sum < sum * .3 
    running_sum += obj_list[i].count 
    i += 1 
training_data = obj_list[i:] 
testing_data = obj_list[:i] 

Cette opération entière est O (n), vous n'allez obtenir une meilleure complexité de temps que cela. Il y a certainement des façons de condenser la boucle et n'importe quoi en un seul doublage, mais je ne connais pas de builtins qui accomplissent ce que vous demandez avec une seule fonction, surtout pas quand vous lui demandez d'être "aléatoire" dans le sens que vous voulez un ensemble de formation/test différent chaque fois que vous le divisez (si je comprends bien la question)

+0

Merci pour votre réponse. Vous avez bien compris mon problème. L'approche est plutôt optimisée. Je suis d'accord sur le fait que pour obtenir la somme, je devrai la boucler à travers tous les objets une fois. Ainsi, l'O (n). Cependant, la ligne 'if running_sum> sum * .7' rendra l'ensemble d'entraînement toujours supérieur à 70%, ai-je raison de faire cette affirmation. – Veenit

+0

Plus par un seul article, vous avez raison. Je suppose que j'ai supposé que sur un ensemble de 3000 articles un seul article ne ferait pas une grande différence.Si c'est un problème, alors je voudrais ajouter la ligne i - = randint (0,1) de sorte qu'il soit aléatoirement soit légèrement inférieur à 0,7 ou légèrement supérieur – James

+1

J'ai également modifié pour faire arrêter la boucle après. 3, sachant que vous avez seulement besoin de trouver le premier .3 à savoir .7, donc aller à .3 est plus rapide - cela va gagner du temps, je ne sais pas pourquoi je n'ai pas pensé à l'origine – James

0

Je ne sais pas s'il existe une fonction spécifique en Python, mais en supposant qu'il n'y en ait pas, voici une approche.

objets Lecture aléatoire:

from random import shuffle 
values = shuffle[200, 40, 30, 110, 20] 

pourcentage Calculer des valeurs du dictionnaire:

prob = [float(i)/sum(values) for i in values] 

Appliquer une boucle:

sum=0 
for i in range(len(result)): 
    if sum>0.7: 
     index=i-1 
     break 
    sum=sum+result[i] 

Maintenant, les objets avant index sont des objets la formation et après sont tester des objets.