es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Recuperar conjunto de datos de un diccionario

Tengo una función que divide un conjunto de datos en un entorno no iid. Esta función devuelve un diccionario de las etiquetas:
“`
def noniid(dataset, clients, min, max, equal_amount=False):
len_dataset = len(dataset)
samples_per_client = int(len_dataset/clients)
idx = np.arange(len_dataset) #idx([0, 1, 2, …, 59999])
dict_users = {i: list() for i in range(clients)}

if equal_amount==False: #diferentes clientes pueden tener cantidades de datos muy diferentes
random_num_size = np.random.randint(min, max+1, size=clients)
print(f"Número total de muestras propiedad de los clientes: {sum(random_num_size)}")

<pre><code># el conjunto de datos total debe ser mayor o igual a la suma del conjunto de datos dividido.
assert len_dataset >= sum(random_num_size)

if (len_dataset == sum(random_num_size)): #cada muestra será utilizada
# dividir y asignar
for i, rand_num in enumerate(random_num_size):

rand_set = set(np.random.choice(idx, rand_num, replace=False))
idx = list(set(idx) – rand_set)
dict_users[i] = rand_set

else: #si no se usan todas las muestras, se asignan todas las muestras sin usar restantes al último cliente
for i, rand_num in enumerate(random_num_size):
if(i==clients-1):
dict_users[i] = idx #asignar todas las muestras restantes al último cliente
else:
rand_set = set(np.random.choice(idx, rand_num, replace=False))
idx = list(set(idx) – rand_set)
dict_users[i] = rand_set

return dict_users
</code></pre>

else: #cada cliente tiene el mismo número de muestras<br>
for i in range(clients):
dict_users[i] = set(np.random.choice(idx, samples_per_client, replace=False))
idx = list(set(idx) – dict_users[i])

<pre><code>return dict_users
</code></pre>

<code>
Por ejemplo, si aplico esta función a un conjunto de datos, obtengo esto:
</code>
{0: {65536,
65540,
5,
65544,
13,
15,
65552,
32785,
65553,
18,

{1: {8,
150,

“`

Ahora, a partir de este diccionario, quiero obtener el conjunto de datos original dividido tal como se establece en el diccionario. Por ejemplo, el dataset0 tendrá las muestras 65536, 65540, y así sucesivamente, el dataset1 tendrá 8, 150 y así sucesivamente.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para obtener el conjunto de datos original dividido según lo especificado por el diccionario, podemos utilizar el diccionario devuelto por la función para crear una lista de conjuntos de datos donde cada conjunto de datos corresponde a un cliente. Podemos hacer un bucle a través del diccionario y para cada cliente, podemos crear un nuevo conjunto de datos extrayendo las muestras que están presentes en el conjunto asociado con ese cliente en el diccionario.

    Aquí hay un fragmento de código de ejemplo:

    def split_dataset_by_clients(dataset, dict_users):
        """
        Función que divide un conjunto de datos en base a un diccionario de usuarios
    
        Args:
        - dataset (torch.utils.data.Dataset): el conjunto de datos original
        - dict_users (dict): un diccionario de usuarios donde cada clave es un ID de cliente y el valor correspondiente es un conjunto 
        de índices que indican las muestras asignadas a ese cliente
    
        Returns:
        - lista de conjuntos de datos: una lista de conjuntos de datos donde cada conjunto de datos corresponde a un cliente
        """
    
        # Crear una lista vacía para almacenar los conjuntos de datos
        datasets = []
    
        # Recorrer el diccionario de usuarios
        for user in dict_users:
    
            # Extraer el conjunto de índices para el usuario actual
            user_idx = list(dict_users[user])
    
            # Crear un Subset del conjunto de datos original con los índices extraídos
            user_dataset = torch.utils.data.Subset(dataset, user_idx)
    
            # Agregar el nuevo conjunto de datos a la lista de conjuntos de datos
            datasets.append(user_dataset)
    
        return datasets
    

    Luego podemos usar esta función de la siguiente manera:

    # Cargar aquí el conjunto de datos original
    conjunto_datos_original = ...
    
    # Aplicar la función de división non-iid para obtener el diccionario de usuarios
    dict_usuarios = noniid(conjunto_datos_original, clientes=2, min=20, max=50)
    
    # Dividir el conjunto de datos original en base al diccionario de usuarios
    conjuntos_clientes = split_dataset_by_clients(conjunto_datos_original, dict_usuarios)
    
    # conjunto_clientes[0] contendrá las muestras para el cliente 0, conjunto_clientes[1] contendrá las muestras para el cliente 1, etc.
    

Comments are closed.