2
votes

Générer aléatoirement des vecteurs similaires?

J'ai le vecteur suivant:

def rand_cos_sim(v, costheta):
# Form the unit vector parallel to v:
u = v / np.linalg.norm(v)

# Pick a random vector:
r = np.random.multivariate_normal(np.zeros_like(v), np.eye(len(v)))

# Form a vector perpendicular to v:
uperp = r - r.dot(u)*u

# Make it a unit vector:
uperp = uperp / np.linalg.norm(uperp)

# w is the linear combination of u and uperp with coefficients costheta
# and sin(theta) = sqrt(1 - costheta**2), respectively:
w = costheta*u + np.sqrt(1 - costheta**2)*uperp

return w


new_vector = rand_cos_sim(my_vector, 1)
print(new_vector)

# [ 0.00170622 -0.08531119  0.51186714  0.8531119   0.01706224 -0.05118671]

Quelqu'un pourrait-il suggérer un moyen de générer au hasard des vecteurs similaires, avec juste des valeurs légèrement différentes? La sortie souhaitée serait, par exemple:

[0.002, -0.06, 0.2, 0.4, 0.02, -0.02]

Pour donner un peu de contexte, ce vecteur représente un échantillon que je nourris dans un modèle de classification. Mon plan est de générer au hasard un ensemble d'échantillons similaires et de les introduire dans le même modèle pour observer la variation de sa sortie. L'objectif final est de vérifier si le modèle génère des sorties similaires pour des échantillons similaires.

J'ai essayé decréer un vecteur aléatoire en fonction de la similitude cosinus et de définir la similitude cosinus souhaitée sur 1, mais avec cette méthode, je ne peux obtenir qu'un seul vecteur similaire (voir ci-dessous). Et j'aurais besoin d'au moins 10.

import numpy as np
my_vector = np.array([0.001, -0.05, 0.3, 0.5, 0.01, -0.03])

Je n'ai pas de mesure de similitude particulière à l'esprit, cela pourrait être soit euclidien, soit cosinus, selon ce qui fonctionne le mieux. Toutes les suggestions sont les bienvenues.

Veuillez noter que le my_vector j'ai fourni est à des fins d'illustration, en réalité mes vecteurs auront différentes plages de valeurs en fonction du modèle que je teste et des données différentes.

Merci.


0 commentaires

3 Réponses :


3
votes

Peut-être que je simplifie à l'extrême, mais ne pourriez-vous pas simplement générer des vecteurs aléatoires de la même taille que le vôtre, puis les ajouter à votre un pour les rendre similaires (ou en ajouter un, puis multiplier puisque votre exemple semble moins varier sur les plus petits nombres)?

def similar_vector(my_vector):
    return (0.95+numpy.random.rand(len(my_vector))*0.1)*my_vector


0 commentaires

3
votes

Je pense que le meilleur moyen est d'ajouter un nombre aléatoire entre deux valeurs. Regardez au hasard à cet effet.

import numpy as np
import random
my_vector = np.array([0.001, -0.05, 0.3, 0.5, 0.01, -0.03])

for i in range(len(my_vector)):
    my_vector[i] += random.uniform(.001,.1)

print(my_vector)

Vous pouvez régler cela en modifiant la plage de valeurs


0 commentaires

3
votes

Vous pouvez générer des facteurs multiplicatifs aléatoires en appelant numpy.random.lognormal . Utilisez mean=0 et une petite valeur de sigma pour générer des valeurs aléatoires proches de 1.

Par exemple,

In [23]: my_vector = np.array([0.001, -0.05, 0.3, 0.5, 0.01, -0.03])                                                                 

In [24]: a = np.random.lognormal(sigma=0.1, size=my_vector.shape)                                                                    

In [25]: a                                                                                                                           
Out[25]: 
array([1.07162745, 0.99891183, 1.02511718, 0.85346562, 1.04191125,
       0.87158183])

In [26]: a * my_vector                                                                                                               
Out[26]: 
array([ 0.00107163, -0.04994559,  0.30753516,  0.42673281,  0.01041911,
       -0.02614745])


0 commentaires