L’analisi delle componenti principali e la decomposizione del valore singolare sono tra i due concetti comuni dell’algebra lineare nell’apprendimento automatico. Dopo aver raccolto dati grezzi, è possibile scoprire la struttura? Per esempio, se consideriamo i tassi di interesse della settimana precedente, c’è modo di capire le tendenze del mercato?
Queste domande diventano più complicate quando abbiamo grandi quantità di dati. Trovare la risposta a queste domande è simile alla ricerca di un ago nel pagliaio. Così, utilizziamo la decomposizione del valore singolare per districare ed estrarre le informazioni complicate. Questo articolo vi aiuterà a capire il concetto di decomposizione del valore singolare in dettaglio.

Decomposizione del valore singolare

Questa tecnica statistica multivariata aiuta a risolvere problemi complessi nelle scienze atmosferiche. L’analisi della funzione ortogonale empirica e l’analisi delle componenti principali sono insiemi simili di procedure per la stessa tecnica introdotta nel 1956 da Edward Lorenz.
La decomposizione del valore singolare aiuta a ridurre gli insiemi di dati contenenti un gran numero di valori. Inoltre, questo metodo è anche utile per generare soluzioni significative per un minor numero di valori. Tuttavia, questi meno valori comprendono anche un’immensa variabilità disponibile nei dati originali.
I dati rivelano grandi correlazioni spaziali nelle scienze geofisiche e atmosferiche. Un’analisi di Singular Value Decomposition supporta e produce risultati per una dimostrazione più compatta di queste correlazioni. Utilizzando set di dati multivariati, è possibile produrre intuizioni sulle variazioni temporali e spaziali. Queste variazioni mostrano i dati dopo l’analisi.
Anche se ci sono meno limitazioni alla tecnica, dovreste capirle prima di calcolare la Singular Value Decomposition dei set di dati. In primo luogo, ci dovrebbero essere anomalie nei dati che la prima struttura catturerà. Se state analizzando i dati per trovare correlazioni spaziali indipendenti dalle tendenze, dovreste de-trendare i dati prima di applicarli all’analisi.

Vettori singolari e valori singolari

Le matrici AAᵀ e AᵀA in algebra lineare sono molto particolari. Moltiplicando la Aᵀ con la matrice dopo aver considerato loro × n matrice A, possiamo formare AAᵀ e AᵀA singolarmente. Le matrici includono:
– Quadrata
– Simmetriche
– Matrici uguali con entrambi gli autovalori positivi
– Semidefinite positive, e
– Stessa r di A con entrambi i ranghi
Una proprietà importante delle matrici simmetriche è che sono simmetriche, e scegliamo che gli autovettori siano ortonormali. Usiamo molto queste matrici di covarianza nell’apprendimento automatico.

Esempio di decomposizione a valore singolare

Per capire il concetto, supponiamo che la matrice m × n, A, raccolga il set di dati di allenamento. Questi insiemi di dati prenderanno la riga per ogni vettore di addestramento. Qui, N indica che la dimensione di ogni vettore sarà molto grande.

Alimentando A in un algoritmo di clustering, si genererà un numero fisso di centri di cluster come output. Poiché ‘n’ è abbastanza grande, l’algoritmo sarà instabile o richiederà troppo tempo. Quindi, utilizzeremo la decomposizione dei valori singolari per ridurre il numero di variabili. Useremo un metodo trasparente per il calcolo, considerando che stiamo ancora risolvendo il problema con coordinate non trasformate.

Passo 1: Lettura dei dati

Possiamo iniziare a leggere i dati compilando A. Quindi iniziamo il tutorial in linguaggio C:
/intestazione della subroutine per eseguire l’analisi dei cluster:
#include “cluster.h”//numero massimo di cluster:
#define MAX_CLUSTER 10int main(intargc, char **argv) {
char *infile; //file di input
char *outfile; //file di uscita
FILE *fs; //puntatore al file
double **a; //matrice di dati di allenamento/U
int m; //numero di righe nella matrice
int n; //numero di colonne nella matrice
intnsv; //numero di valori singolari if (argc!=4) {
printf(“sintassi: cluster_svdnsv allena centri\n”);
printf(” dove:\n”);
printf(“nsv = numero di valori singolari (0 = usa dati non trasformati)\n”);
printf(“infile = file ASCII di input contenente i dati di allenamento\n”);
printf(“output = file di output ASCII contenente i centri del cluster\n”);
printf(“\n”);
printf(“formato del file:\n”);
printf(“- intestazione di una riga contenente il numero di righe e il numero di colonne\n”);
printf(“- lista delle righe principali di ogni elemento della matrice\n”);
exit(1);
} se (sscanf(argv[1], “%d”, &nsv)!=1) {
fprintf(stderr, “Error parsing first command line argument\n”);
exit(1);
}
infile=argv[2];
outfile=argv[3]; fs=fopen(infile, “r”);
se (fs==NULL) {
fprintf(stderr, “Error opening input file, %s\n”, infile);
exit(1);
} se (fscanf(fs, “%d %d”, &m, &n)!=2) {
fprintf(stderr, “Errore di formato nel file di input: %s linea 0”, infile);
exit(1);
}
se (nsv>n) {
fprintf(stderr, “Parametro linea di comando nsv=%d fuori range\n”, nsv);
exit(1);
} a=nuovo doppio *[m];
a[0]=nuovo doppio[m*n];
per (inti=1; i<m; i++) a[i]=a[0]+i*n;
per (inti=0; i<m; i++) {
for (int j=0; j<n; j++) {
se (fscanf(fs, “%lg”, a[i]+j)!=1) {
fprintf(stderr, “Errore di formato nel file di input, %s, linea %d\n”, infile, i);
exit(1);
}
}
} fclose(fs);

Passo 2: eseguire SVD

Ora useremo la routine di decomposizione artificiale del valore singolare che il file header, svd.h contiene:
#ifndef SVD_H
#define SVD_H//subroutine per la decomposizione del valore singolare:
int //restituisce un codice di errore (0 per il successo)
svd (double **a, //matrice in ingresso – sostituita da U in uscita
int m, //numero di righe
int n, //numero di colonne
doppio *s, //valori singolari
double **vt); //V–vettori singolari destri#endif
Le routine di decomposizione dei valori singolari sono complesse per quanto riguarda il tipo di matrice e vettore utilizzati. Tuttavia, si può facilmente riassumere la codifica completa attraverso la funzione wrapper. La routine sarà altrettanto semplice quando ci si affida a una routine di decomposizione dei valori singolari. Aggiungeremo i seguenti codici dopo la sezione precedente:
doppio *ave;
doppio *s; //valori singolari
doppio **vt; //vettori singolari destri //prima calcoliamo e rimuoviamo le medie aritmetiche:
ave=nuovo doppio[n]
for (inti=0; i<n; i++) ave[i]=0;
for (inti=0; i<m; i++) {
for (int j=0; j<n; j++) {
ave[j]+=a[i][j];
}
}
for (inti=0; i<n; i++) ave[i]/=m;
for (inti=0; i<m; i++) {
for (int j=0; j<n; j++) {
a[i][j]-=ave[j];
}
} if (nsv>0) {
//fare spazio ai valori singolari:
s=new double[n]; //make space for right singular vectors:
vt=new double *[n];
vt[0]=nuovo doppio[n*n];
for (inti=1; i<n; i++) vt[i]=vt[0]+i*n; //eseguire la decomposizione:
int err=svd(a, m, n, s, vt);
se (err!=0) {
fprintf(stderr, “Errore nella subroutine svd\n”);
exit(err);
}
}

Passo 3: Esecuzione dell’analisi dei cluster

Il processo dell’algoritmo di clustering genererà un insieme di c centri di cluster utilizzando {ᵢ ; i ∈ [1, c]}:
#ifndef CLUSTER_H
#define CLUSTER_Hint //restituisce il numero di centri del cluster
cluster (doppio ** x, //vettori di addestramento
int m, //numero di vettori di allenamento
int n, //dimensione di ogni vettore
intmax_nc, //numero massimo di centri del cluster
doppio **mu); //centri di cluster restituiti#endif
Continuiamo dalla sezione precedente e generiamo i centri dei cluster:
double **mu_p; //matrice dei centri del cluster
intnc; //numero di centri del cluster //fare spazio ai centri del cluster:
mu_p=nuovo doppio *[MAX_CLUSTER];
mu_p[0]=nuovo doppio[MAX_CLUSTER*n];
for (inti=1; i<MAX_CLUSTER; i++) mu_p[i]=mu_p[0]+i*n; if (nsv>0) {
//fare spazio ai centri dei cluster:
nc=cluster(a, m, nsv, MAX_CLUSTER, mu_p);
} else {
//realizza lo spazio per i centri del cluster:
nc=cluster(a, m, n, MAX_CLUSTER, mu_p);
} if (nc<= 0) {
fprintf(stderr, “Cluster algorithm failed”);
exit(-1);
}
Poiché useremo i dati di allenamento trasformati per l’algoritmo di clustering, il sistema trasformato includerà i centri dei cluster.

Passo 4: Memorizzare i risultati

Ora è possibile memorizzare i centri dei cluster utilizzando la seguente equazione nel sistema di coordinate non trasformato.

P in questa equazione indica il numero di coordinate.
double **mu; //centri del cluster in coordinate non trasformate //allocate lo spazio per i centri del cluster non trasformati:
mu=nuovo doppio *[nc];
mu[0]=nuovo doppio[nc*n];
for (inti=1; i<nc; i++) mu[i]=mu[0]+i*n; //eseguire la trasformazione delle coordinate:
for (inti=0; i<nc; i++) {
for (int j=0; j<n; j++) {
mu[i][j]=ave[j];
se (nsv>0) {
for (int k=0; k<nsv; k++) mu[i][j]+=vt[k][j]*s[k]*mu_p[i][k];
} else {
mu[i][j]+=mu_p[i][j];
}
}
} //scrivere i risultati in un file:
fs=fopen(outfile, “w”);
se (fs==NULL) {
fprintf(stderr, “Error opening output file, %s\n”, outfile);
exit(1);
} fprintf(fs, “%d %d\n”, nc, n);
for (inti=0; i<nc; i++) {
for (int j=0; j<n; j++) fprintf(fs, “%16.8lg”, mu[i][j]);
fprintf(fs, “\n”);
} fclose(fs); //ripulire:
delete [] mu[0];
cancellare [] mu; cancellare [] mu_p[0];
cancellare [] mu_p; cancellare [] ave;
cancellare [] a[0];
cancellare [] a;
se (nsv>0) {
cancellare [] s;
cancellare [] vt[0];
cancellare [] vt;
} return 0;
}

Conclusione

In questo articolo, abbiamo spiegato la definizione della decomposizione dei valori singolari e vi abbiamo aiutato a capire la costruzione del modello in linguaggio C. Puoi utilizzare questo metodo per recuperare le variabili atmosferiche in base alle misurazioni satellitari. Puoi anche usare questa tecnica per interpolare misure sparse o per un algoritmo di apprendimento automatico. Questa tecnica aiuta con la regressione e la classificazione del set di dati.