web-dev-qa-db-fra.com

Normalisation VS. Numpy moyen de normaliser?

Je suis censé normaliser un tableau. J'ai lu sur la normalisation et trouve une formule:

 enter image description here

J'ai écrit la fonction suivante pour cela:

def normalize_list(list):
    max_value = max(list)
    min_value = min(list)
    for i in range(0, len(list)):
        list[i] = (list[i] - min_value) / (max_value - min_value)

Cela est censé normaliser un tableau d’éléments.

Ensuite, je suis tombé sur ceci: https://stackoverflow.com/a/21031303/6209399 Ce qui indique que vous pouvez normaliser un tableau en procédant simplement comme suit:

def normalize_list_numpy(list):
    normalized_list = list / np.linalg.norm(list)
    return normalized_list

Si je normalise ce tableau de tests test_array = [1, 2, 3, 4, 5, 6, 7, 8, 9] avec ma propre fonction et avec la méthode numpy, j'obtiens les réponses suivantes:

My own function: [0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0]
The numpy way: [0.059234887775909233, 0.11846977555181847, 0.17770466332772769, 0.23693955110363693, 0.29617443887954614, 0.35540932665545538, 0.41464421443136462, 0.47387910220727386, 0.5331139899831830

Pourquoi les fonctions donnent-elles des réponses différentes? Existe-t-il d'autres moyens de normaliser un tableau de données? Que fait numpy.linalg.norm(list)? Qu'est-ce que je me trompe?

5
OuuGiii

Il existe différents types de normalisation. Vous utilisez la normalisation min-max. La normalisation min-max de scikit learn est la suivante. 

import numpy as np
from sklearn.preprocessing import minmax_scale

# your function
def normalize_list(list_normal):
    max_value = max(list_normal)
    min_value = min(list_normal)
    for i in range(len(list_normal)):
        list_normal[i] = (list_normal[i] - min_value) / (max_value - min_value)
    return list_normal

#Scikit learn version 
def normalize_list_numpy(list_numpy):
    normalized_list = minmax_scale(list_numpy)
    return normalized_list

test_array = [1, 2, 3, 4, 5, 6, 7, 8, 9]
test_array_numpy = np.array(test_array)

print(normalize_list(test_array))
print(normalize_list_numpy(test_array_numpy))

Sortie:

[0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0]    
[0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0]

MinMaxscaler utilise exactement votre formule pour la normalisation/mise à l'échelle: http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.minmax_scale.html

@OuuGiii: NOTE: Ce n'est pas une bonne idée d'utiliser les noms de fonction intégrés Python en tant que noms varibale. list() est une fonction intégrée à Python. Son utilisation en tant que variable doit donc être évitée. 

6
utengr

La question/réponse à laquelle vous faites référence ne met pas explicitement en relation votre propre formule avec la version np.linalg.norm(list) que vous utilisez ici.

Une solution NumPy serait la suivante:

import numpy as np
def normalize(x):
    x = np.asarray(x)
    return (x - x.min()) / (np.ptp(x))

print(normalize(test_array))    
# [ 0.     0.125  0.25   0.375  0.5    0.625  0.75   0.875  1.   ]

Ici np.ptp est pic à pic, c'est-à-dire

Plage de valeurs (maximum - minimum) le long d'un axe.

Cette approche adapte les valeurs à l'intervalle [0, 1] comme indiqué par @phg.

La définition plus traditionnelle de la normalisation serait de passer à une variance de 0 moyenne et unité:

x = np.asarray(test_array)
res = (x - x.mean()) / x.std()
print(res.mean(), res.std())
# 0.0 1.0

Ou utilisez sklearn.preprocessing.normalize en tant que fonction prédéfinie.

Utiliser test_array / np.linalg.norm(test_array) crée un résultat de longueur unité; vous verrez que np.linalg.norm(test_array / np.linalg.norm(test_array)) est égal à 1. Vous parlez donc de deux champs différents, l'un étant la statistique et l'autre l'algèbre linéaire.

4
Brad Solomon

La puissance de python réside dans sa propriété broadcast , qui vous permet de vectoriser des opérations de tableau sans effectuer de boucle explicite. Ainsi, vous n'avez pas besoin d'écrire une fonction en utilisant explicitement pour la boucle, ce qui est lent et prend du temps, surtout si votre jeu de données est trop volumineux.

La façon pythonique de faire normalisation min-max est

test_array = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
normalized_test_array = (test_array - min(test_array)) / (max(test_array) - min(test_array)) 

sortie >> [0., 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.]

0
ewalel