Come disegnare una trama ghiaione in Python? [chiuso]


11

Sto usando una decomposizione vettoriale singolare su una matrice e ottengo le matrici U, S e Vt. A questo punto, sto cercando di scegliere una soglia per il numero di dimensioni da conservare. Mi è stato suggerito di guardare una trama ghiaione, ma mi chiedo come fare per complottarla in modo intorpidito. Attualmente, sto facendo quanto segue usando le librerie numpy e scipy in Python:

U, S, Vt = svd(A)

Eventuali suggerimenti?


1
prendi la diagonale di S, se non è già una diagonale, quadrala, ordinala in ordine decrescente, prendi la somma cumulativa, dividi per l'ultimo valore, quindi tracciala.
Shabbychef,

@shabbychef: Intendi, prendi la somma cumulativa e dividi per la somma di tutti i valori, giusto?
Legenda

sì. In matlab, sarebbe[U,S,V] = svd(X);S = cumsum(sort(diag(S).^2,1,'descend'));S = S ./ S(end);plot(S);
shabbychef il

Risposte:


13

Ecco un esempio che può essere incollato in un prompt di IPython e generare un'immagine come di seguito (utilizza dati casuali):

import numpy as np
import matplotlib
import matplotlib.pyplot as plt

#Make a random array and then make it positive-definite
num_vars = 6
num_obs = 9
A = np.random.randn(num_obs, num_vars)
A = np.asmatrix(A.T) * np.asmatrix(A)
U, S, V = np.linalg.svd(A) 
eigvals = S**2 / np.sum(S**2)  # NOTE (@amoeba): These are not PCA eigenvalues. 
                               # This question is about SVD.

fig = plt.figure(figsize=(8,5))
sing_vals = np.arange(num_vars) + 1
plt.plot(sing_vals, eigvals, 'ro-', linewidth=2)
plt.title('Scree Plot')
plt.xlabel('Principal Component')
plt.ylabel('Eigenvalue')
#I don't like the default legend so I typically make mine like below, e.g.
#with smaller fonts and a bit transparent so I do not cover up data, and make
#it moveable by the viewer in case upper-right is a bad place for it 
leg = plt.legend(['Eigenvalues from SVD'], loc='best', borderpad=0.3, 
                 shadow=False, prop=matplotlib.font_manager.FontProperties(size='small'),
                 markerscale=0.4)
leg.get_frame().set_alpha(0.4)
leg.draggable(state=True)
plt.show()

inserisci qui la descrizione dell'immagine


Hermann: +1 Grazie per il tuo tempo! So che è passato molto tempo, ma è comunque bello avere :)
Legenda,

che cos'è num_vars? non sembra essere definito nella tua sceneggiatura.
TheChymera,

@TheChymera - Grazie per averlo colto, ho aggiornato la mia risposta.
Josh Hemann,

@Josh Hemann sì, l'ho anche capito nel frattempo - ma penso che potrebbe essere meglio calcolarlo dalla forma di A
TheChymera

1
@JoshHemann puoi spiegarlo: eigvals = S ** 2 / np.cumsum (S) [- 1] ?? Ho visto basarmi su alcuni giornali eigvals = S ** 2 / (n-1) dove n è il numero di funzioni
Mak
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.