[PYTHON] Mon mémo numpy / scipy inversé

Mémo numpy inversé

C'est moche. Je ne pense pas que vous l'aimerez tant que vous ne vous y serez pas habitué. Mais je ne perdrai pas. Eh, num, je veux te montrer mon python avec un mouvement numpy. ** * Je pense que cet article sera revu petit à petit. ** **

Mon idiome mineur

Ce qui suit est un style d'écriture que je vois rarement dans les articles de commentaires, Je vais l'utiliser dans cet article car c'est presque un idiome pour moi.

#Faites quelque chose basé sur la matrice de gramme
# *Est une modification pour l'avoir développé lorsqu'il est inséré dans une fonction
fuga = hoge(*np.meshgrid(x, y))

#Sortez le hoge sur l'axe des abscisses de la matrice A
#Quelque chose comme une carte. Pour une raison quelconque, tout le monde utilise l'instruction for, mais n'est-il pas plus facile de comprendre si numpy est écrit comme un type de fonction?
fuga = np.apply_along_axis(hoge, x, A)

#C'est un idiome, ou c'est généralement un produit scalaire,
#Pourquoi tout le monde n'utilise pas ce np.Est-ce juste des points? C'est bien d'écrire de façon nette, mais ...
hoge @ fuga

Faire je

Je pensais que je n'avais pas besoin de cette zone, mais je suis surpris que je sois recherché sur Google.

np.eye(5)

Faites juste une séquence d'égalité

Série de nombres à différence égale avec une différence de 1 de 0 à 100.

np.arange(0, 100, 1)

Cependant, le dernier sera mis à 1 si vous gardez le silence.

np.arange(100)

Et. Eh bien, c'est basique.

Ordre inverse

np.flip

Mise en relation

Celui qui se connecte en parallèle ou verticalement est np.vstack Celui qui se connecte en série ou horizontalement np.hstack Mais cette fonction n'est pas np.vstack (hoge, fuga) Utilisez-le comme np.vstack ((hoge, fuga)). Il existe également np.concatenate.

Faire une matrice de gramme

Faites une matrice de gramme normalement. Dans un tel cas, meshgrid est bon. … Mais maillage lui-même me donne envie de l'appeler art numpy Suis-je le seul à avoir beaucoup de compétences en écriture?

xg, yg = np.meshgrid(x, y)
gram = xg * yg

Mais vous pouvez aussi écrire comme ça. Dans ce cas, dans le sens où il est très similaire à la méthode du noyau ci-dessous. J'aime celui-ci car il est facile à comprendre. (La méthode du noyau est un produit interne généralisé, n'est-ce pas?)

from operator import mul
gram = mul(*np.meshgrid(x, y))

Méthode du noyau

Pour le moment, je l'ai écrit avec le noyau gaussien. Tout ce que vous avez à faire est de remplacer le mul dans la matrice de gramme ci-dessus par le noyau.

def kernel(a: np.ndarray, b: np.ndarray, v: float) -> np.ndarray:
    return np.exp(- v * np.square(a - b))

gram = kernel(*np.meshgrid(x, x))

Avec régularisation quadratique

lmd = 0.1  #adapté
gram = kernel(*np.meshgrid(x, x)) + lmd * np.eye(x.shape[0])

En appliquant cela, j'avais l'habitude d'écrire de manière ludique le golf de retour du noyau.

def solve_kernel(x: np.ndarray, y: np.ndarray,
                 kernel: Callable, lmd: float) -> np.ndarray:
    K = kernel(*np.meshgrid(x, x)) + lmd * np.eye(x.shape[0])
    alpha = np.linalg.solve(K, y)
    return np.vectorize(lambda xs: np.sum(alpha * kernel(x, xs)))

La régression du noyau peut être écrite en seulement 4 lignes même si PEP8 est protégé. numpy c'est super ...

Essayez de faire une chose semblable à une montagne en trois dimensions

Faisons une montagne gaussienne avec 100 lignes et 100 colonnes. Vous pouvez également utiliser meshgrid pour cela. C'est triste que ce soit un peu de magie noire, mais ce n'est pas grave.

def mount(x: int, y: int) -> np.ndarray:
    return np.exp(-(np.square(x) + np.square(y)) / 1000)


x_y = 100, 100
g = mount(*np.meshgrid(*(np.arange(-n/2, n/2, 1) for n in x_y)))

Pourquoi as-tu fait ça? C'est celui que j'ai écrit pour l'expérience de clustering. La combinaison de meshgrid et * peut être dorée ou battue pour avoir enfreint les conventions de codage.

Quand tu n'aimes pas les déclarations

Il existe plusieurs façons. Eh bien, la carte et ainsi de suite sont nouvelles, donc ça va.

Utiliser les fonctions universelles

Vous pouvez créer une fonction universelle, une fonction qui se comporte comme numpy, il y a donc une façon de l'utiliser.

A = [[2, 4, 8], [1, 1, 1]]
def test(x):
    return x * 2

np.vectorize(test)(A)
>array([[4, 8, 16], [2, 2, 2]])

Au fait, il peut également être utilisé comme décorateur, mais je ne sais pas si cela est autorisé dans le sens des conventions de codage. Il semble qu'il y ait diverses choses telles que le nombre d'arguments doit être juste un nombre pour devenir une fonction correctement.

Utilisez np.apply_along_axis

Cette méthode est tout à fait applicable car vous pouvez spécifier l'axe. De plus, le fonctionnaire dit que c'est rapide. Je ne sais pas ce qui est le plus rapide, vectoriser.

#De la même manière que ci-dessus
np.apply_along_axis(test, 0, A)

Il semble qu'il y ait des restrictions dimensionnelles afin de se déplacer correctement. Il existe plusieurs autres fonctions. https://numpy.org/devdocs/reference/routines.functional.html

Résoudre des équations simultanées (si elles peuvent être résolues)

Équations simultanées ordinaires. Par exemple: 5x + 3 = y x + 1 = y En représentation matricielle: $AX=Y$ Pour résoudre ce problème, procédez comme suit.

X = np.linalg.solve(A, Y)

Dans ce cas, le nombre inconnu était la variable X. Cependant, en pratique, la plupart du temps, vous souhaitez connaître la constante A à partir de la valeur mesurée X. Par conséquent, A et X sont ici dans des positions opposées dans la méthode des moindres carrés. Il semble préférable d'utiliser cette fonction sans émettre explicitement la matrice inverse.

Résolvez la méthode des moindres carrés (s'il n'y a pas de solution)

Pour les motifs pour lesquels il n'y a pas de solution, la méthode des moindres carrés sera utilisée. «Il n'y a pas de solution» est, par exemple, la suivante.

8x + 4 = y 5x + 3 = y x + 1 = y

Il n'y a pas de solution car ces équations simultanées sont contradictoires les unes avec les autres. Puisque la solution de la méthode des moindres carrés est l'équation suivante

X^TXA = X^TY
A = np.linalg.solve(X.T @ X, X.T @ Y)

Vous pouvez également utiliser une pseudo matrice inverse.

A = pinv(x) @ y

Cependant, comme il existe déjà une fonction correctement, ce qui suit est la bonne réponse au lieu de ce qui précède.

A = np.linalg.lstsq(X, Y)[0]

Méthode du carré minimum avec régularisation

Je ne sais pas quoi faire de la régularisation. J'ai cherché sur Google, mais je n'ai pas trouvé la bonne réponse, alors je me demande si je devrais l'écrire moi-même. $(X^TX + \lambda I)A = X^TY$

lmd = 1
seisoku = lmd * np.eye(min(X.shape))
A = np.linalg.solve(X.T @ X + seisoku , X.T @ Y)

Résolvez la plus petite solution de norme (si la solution est infinie)

Dans un tel cas, la solution est infinie. 8x_1 + x_2 + 6x_3 = 4 5x_1 + x_2 + 2X_3 = 3 Trouvez la solution optimale pour cette équation. $A = X^T{(XX^T)}^{-1}Y$

A = X.T @ np.linalg.inv(X @ X.T) @ Y

N'est-ce pas? Cependant, le processus inverse de Moore Penrose est incroyable, donc je peux y aller normalement.

A = pinv(X) @ Y

Cependant, la bonne réponse est la suivante.

A = np.linalg.lstsq(X, Y)[0]

Cette fonction est incroyable.

Méthode du carré minimum avec régularisation (lorsque la solution est infinie)

Je ne sais pas comment attaquer ça aussi. Cependant, la formule est facile à faire. $A = X^T{(XX^T + \lambda I)}^{-1}Y$

lmd = 1
seisoku = lmd * np.eye(min(X.shape))
A = X.T @ np.linalg.inv(X @ X.T + seisoku) @ Y

Hmm ... (・ ั ω ・ ั) Est-ce mon manque d'étude que je n'ai pas pu trouver avec la régularisation? Ce n'est pas grave car ce n'est pas trop difficile ...

Autres problèmes d'optimisation divers

https://docs.scipy.org/doc/scipy/reference/optimize.html#module-scipy.optimize

Fais le plus rapidement

Les opérateurs tels que `` ** '' sont relativement lents dans numpy. Vous ne devriez pas faire e ** hoge, c'est plus rapide d'utiliser np.exp. C'était le cas avec le package de conversion Wavelet que j'ai écrit. (Donc ce n'est pas lisible ...)

hoge = np.arange(1000)
e ** hoge  #lent
np.exp(hoge)  #vite

hoge ** 2  #lent
np.square(hoge)  #vite

hoge ** (0.5)  #lent
np.sqart(hoge)  #vite

hoge ** (3)  #lent
np.power(hoge, 3)  #vite

hoge ** (3.4)  #lent
np.float_power(hoge, 3.4)  #vite

En plus de cela, il existe diverses choses comme np.power, mais il est plus rapide d'utiliser les fonctions de base et optimisées.

Produit matriciel

Je ne sais pas pourquoi tout le monde n'utilise pas l'opérateur @. Je pense que c'est plus facile à lire que np.dot ... Êtes-vous en retard?

np.arange(10)[email protected](10)

Nombre complexe lié

Conjugaison compliquée

np.conj

Axe réel axe imaginaire lié

hoge.real, hoge.imag Vous pouvez écrire comme ça, donc lorsque vous remplacez celui-ci

fuga.real, fuga.imag = hoge.real, hoge.imag

La raison pour laquelle je veux cela est qu'il est surprenant que certains traitements soient effectués uniquement sur l'axe imaginaire et uniquement sur l'axe réel.

Transformée de Fourier

Je pense que la transformation de Fourier utilise souvent scipy. C'est aussi numpy.

scipy.fftpack.fft(wave)

Conversion inverse

comp  #Soit une matrice de nombres complexes après transformation de Fourier
scipy.fftpack.ifft(comp)

Cupy lié

Convertir en cupy

cp.asarray(numpy_array)

Convertir en numpy

cp.asnumpy(cupy_array)

cupy lui-même est différent de numpy à sa manière, alors soyez prudent.

Cas divisé

Utilisez np.where. Si x correspond à l'expression conditionnelle, le deuxième argument est émis, et sinon, le troisième argument est émis.

x = np.arange(10)
np.where(x > 5, x * 10, x)
> array([0, 1, 2, 3, 4, 5, 60, 70, 80, 90])

Déclaration conditionnelle liée

Lorsqu'une expression conditionnelle est insérée, elle se comporte comme R.

x = np.arange(10)
x > 5
> array([False, False, False, False, False, False, True, True, True, True])

Mathématiques

np.det(hoge)  #Formule matricielle
np.norm(hoge)  #Norme

Remplir avec zéro

hoge est un tableau Ensuite, remplissez les 3e et plus tôt et 5e transitions. constante signifie remplir de constantes. La dernière est la constante à remplir avec la gauche et la droite. Il existe divers autres modes.

np.pad(hoge, [3, 5], 'constant' ,[0, 0])

Image creuse

Essayez de ne creuser que la partie de grande valeur. Créez un tableau de True et False comme précédemment et évider avec une expression conditionnelle. Dans l'exemple, après avoir fait quelque chose comme une montagne avec numpy, le sommet de la montagne est coupé. À ce stade, np.nan peut être nécessaire. C'est parce que nan est ignoré par imshow de matplotlib.

def mount(x: int, y: int) -> np.ndarray:
    return np.exp(-(np.square(x) + np.square(y)) / 1000)


#Une fonction à évider.
#Une matrice où les valeurs sont une matrice ordinaire et le cluster est booléen
def make_single_cluster(values, cluster):
    img = np.nan * np.zeros_like(values)
    img[cluster] = tvalues[cluster]
    return img


x_y = 100, 100
#Cette fois j'ai essayé d'ajouter un peu de bruit
X = np.random.rand(*x_y) / 100
#Faire une montagne
X += mount(*np.meshgrid(*(np.arange(-n/2, n/2, 1) for n in x_y)))

plt.imshow(make_single_cluster(X, X > 0.5))
plt.show()

Figure_1.png

matlab lecture / écriture

scipy a une fonction de lecture / écriture matlab.

import scipy.io as sio
sio.loadmat('hoge.mat')

data = {'fuga', np.arange(100)}
sio.savemat(fuga.mat, data)

Malheureusement, je n'ai jamais utilisé matlab, donc je ne suis pas sûr.

L'intégration

C'est aussi scipy C'est magique.

from scipy.integrate import quad
def test(x):
    return x ** 2 - x
print(quad, test, -5, 5)

Une autre chose est d'intégrer deux fois. C'est dblquad

Fonction spéciale

Au fait, vous aimez les mathématiques, non? Regardez ce lien. https://docs.scipy.org/doc/scipy/reference/special.html#module-scipy.special

Recommended Posts

Mon mémo numpy / scipy inversé
Mon Numpy (Python)
[Mon mémo] python
[Python] Mémo Numpy
Mémo de calcul de base Numpy
Mémo inversé Pandas
[Self memo] Préparation-démarrage de Django
[Mon mémo] python -v / python -V
Astuces Python (mon mémo)
Mémo Qiita de mes pensées
Utilisez OpenBLAS avec numpy, scipy
[Mémo] Petite histoire de pandas, stupide