Главный компонентный анализ и сингулярное стоимостное разложение являются одними из двух общих концепций линейной алгебры в машинном обучении. После сбора исходных данных можно ли обнаружить структуру? Например, когда мы рассматриваем процентные ставки предыдущей недели, можно ли как-то вычислить тренды на рынке?
Эти вопросы усложняются, когда мы имеем большие объемы данных. Поиск ответа на эти вопросы похож на поиск иголки в стоге сена. Таким образом, мы используем сингулярное разложение значений, чтобы распутать и извлечь сложную информацию. Эта статья поможет вам детально разобраться в понятии сингулярного стоимостного разложения.
Разложение по единичному значению
Этот многомерный статистический метод помогает решать сложные задачи в науках об атмосфере. Эмпирический анализ ортогональных функций и анализ основных компонентов являются аналогичными наборами процедур для той же техники, введенными в 1956 году Эдвардом Лоренцом.
Разложение единичных значений помогает уменьшить наборы данных, содержащие большое количество значений. Более того, этот метод также полезен для получения значительных решений при меньшем количестве значений. Однако меньшее количество значений также включает в себя огромную вариабельность, доступную в исходных данных.
Данные выявляют большие пространственные корреляции в геофизических и атмосферных науках. Анализ разложения по единичному значению поддерживает и дает результаты для более компактной демонстрации этих корреляций. Используя многомерные наборы данных, можно получить представление о временных и пространственных вариациях. Эти вариации демонстрируют данные после анализа.
Несмотря на то, что существует меньше ограничений в методике, вы должны понять их, прежде чем рассчитывать разложение наборов данных по единичному значению. Во-первых, в данных должны быть аномалии, которые будут зафиксированы первой структурой. Если вы анализируете данные, чтобы найти пространственные корреляции, не зависящие от трендов, то перед применением к анализу следует разобрать данные.
Единые векторы и единичные значения
Матрица AAᵀ и AᵀA в линейной алгебре очень особенная. Умножив Aᵀ на матрицу после их рассмотрения × n матрицы A, мы можем сформировать AAᵀ и AᵀA по отдельности. Матрицы включают в себя:
– Квадрат
– Симметричный
– Те же матрицы с обоими положительными собственными значениями
– Положительный полубесконечный, и
– Тот же r, что и A с обоими рангами
Основным свойством симметричных матриц является то, что они симметричны, и мы выбираем собственные векторы, чтобы быть ортонормальными. Мы используем эти ковариационные матрицы в машинном обучении.
Пример разложения по единичному значению
Чтобы понять концепцию, предположим, что матрица m × n, A, собирает набор обучающих данных. Эти наборы данных возьмут строку для каждого вектора обучения. Здесь N указывает на то, что размерность каждого вектора будет очень большой.
Подавая A в алгоритм кластеризации, вы будете генерировать на выходе фиксированное количество кластерных центров. Поскольку ‘n’ довольно большое, алгоритм будет нестабильным или слишком длинным. Поэтому мы будем использовать сингулярное разложение значений для уменьшения количества переменных. Мы будем использовать прозрачный метод вычисления, учитывая, что мы все еще решаем проблему с неперемещенными координатами.
Шаг 1: Чтение данных
Мы можем начать читать данные с заполнения A. Итак, давайте начнем учебник на языке Си:
//заголовок подпрограммы для выполнения кластерного анализа:
#включаем “cluster.h” //максимальное количество кластеров:
#define MAX_CLUSTER 10int main(intargc, char **argv) {
char *infile; //input file
char *outfile; //выходной файл
ФАЙЛ *fs; // указатель файла
двойной **a; // матрица данных тренинга/
int m; // количество строк в матрице
int n; // количество колонок в матрице
intnsv; //номер единственного значения если (argc!=4) {
printf(“синтаксис: cluster_svdnsv train centers\n”);
printf(” where:\n”);
printf(“nsv = количество сингулярных значений (0 = использование непереведённых данных)\n”);
printf(“infile = ASCII входной файл, содержащий обучение data\n”);
printf(“output = выходной файл ASCII, содержащий кластер centers\n”);
printf(“\n”);
printf(“формат файла:\n”);
printf(“- заголовок одной строки, содержащий количество строк и номер columns\n”);
printf(“- список основных строк каждой матрицы element\n”);
выход(1);
} if (sscanf(argv[1], “%d”, &nsv)!=1) {
fprintf(stderr, “Ошибка при разборе первой командной строки argument\n”);
exit(1);
}
infile=argv[2];
outfile=argv[3]; fs=fopen(infile, “r”);
if (fs==NULL) {
fprintf(stderr, “Ошибка при открытии входного файла, %s\n”, в файле);
выход(1);
} если (fscanf(fs, “%d %d”, &m, &n)!=2) {
fprintf(stderr, “Ошибка форматирования во входном файле: %s строка 0”, в файле);
exit(1);
}
если (nsv>n) {
fprintf(stderr, “Параметр командной строки nsv=%d из range\n”, nsv);
exit(1);
} a=new double *[m];
a[0]=new double[m*n];
for (inti=1; i<m; i++) a[i]=a[0]+i*n;
for (inti=0; i<m; i++) {
для (int j=0; j<n; j++) {
если (fscanf(fs, “%lg”, a[i]+j)!=1) {
fprintf(stderr, “Ошибка форматирования во входном файле, %s, строка %d\n”, в файле, i);
выход(1);
}
}
fclose(fs);
Шаг 2: Выполнение SVD
Теперь мы будем использовать искусственную сингулярную рутину разложения значений, которую содержит заголовочный файл svd.h:
#ifndef SVD_H
#define SVD_H//подпрограмма для сингулярного разложения значений:
int // возвращает код ошибки (0 для успеха)
svd (двойная **a, //входная матрица – заменена на U на выходе)
в м, //количество рядов
int n, //номер колонок
двойные *с, //синглярные значения
double **vt); //V–right singular vectors#endif
Процедуры разложения единичных значений сложны по типу используемой матрицы и вектора. Тем не менее, вы можете легко суммировать полное кодирование с помощью функции обертки. Рутина будет так же проста, когда вы полагаетесь на рутину разложения единичных значений. Мы добавим следующие коды после предыдущего раздела:
двойная *переменная *переменная *переменная *переменная *переменная *переменная;
двойные *с; //сингвальные значения
double **vt; //правый сингулярные векторы //первыми вычисляем и удаляем арифметические средства:
ave=new double[n];
for (inti=0; i<n; i++) ave[i]=0;
for (inti=0; i<m; i++) {
для (int j=0; j<n; j++) {
ave[j]+=a[i][j];
}
}
для (inti=0; i<n; i++) ave[i]/=m;
for (inti=0; i<m; i++) {
для (int j=0; j<n; j++) {
a[i][j]-=ave[j];
}
если (nsv>0) {
///создайте пространство для единичных значений:
s=new double[n]; //make space for right singular vectors:
vt=new double *[n];
vt[0]=new double[n*n];
for (inti=1; i<n; i++) vt[i]=vt[0]+i*n; //выполняем декомпозицию:
int err=svd(a, m, n, s, vt);
if (err!=0) {
fprintf(stderr, “Error in svd subroutine\n”);
exit(err);
}
}
Шаг 3: Выполнение кластерного анализа
В процессе работы алгоритма кластеризации с помощью {ᵢ ; i ∈ [1, c]} будет сгенерировано множество кластерных центров c :
#ifndef CLUSTER_H
#define CLUSTER_Hint // возвращает количество кластерных центров
кластер (двойные ***, //векторы обучения
int m, //количество тренировочных векторов
int n, // размер каждого вектора
intmax_nc, //максимальное число кластерных центров
двойной **mu); //возвращенные кластерные центры#endif
Мы продолжим с вышеприведенного раздела и создадим кластерные центры:
double **mu_p; //matrix кластерных центров
intnc; //количество кластерных центров //создание пространства для кластерных центров:
mu_p=new double *[MAX_CLUSTER];
mu_p[0]=new double[MAX_CLUSTER*n];
for (inti=1; i<MAX_CLUSTER; i++) mu_p[i]=mu_p[0]+i*n; if (nsv>0) {
///создайте пространство для кластерных центров:
nc=cluster(a, m, nsv, MAX_CLUSTER, mu_p);
} else {
///создайте пространство для кластерных центров:
nc=cluster(a, m, n, MAX_CLUSTER, mu_p);
} если (nc<= 0) {
fprintf(stderr, “Кластерный алгоритм не работает”);
exit(-1);
}
Так как для алгоритма кластеризации мы будем использовать преобразованные обучающие данные, то преобразованная система будет включать в себя кластерные центры.
Шаг 4: Хранение результатов
Теперь вы можете хранить кластерные центры, используя следующее уравнение в непереведенной системе координат.
P в этом уравнении означает количество координат.
double **mu; //кластерные центры в непереведенных координатах //выделяют место для непереведенных кластерных центров:
mu=new double *[nc];
mu[0]=new double[nc*n];
for (inti=1; i<nc; i++) mu[i]=mu[0]+i*n; //выполняем координатное преобразование:
for (inti=0; i<nc; i++) {
для (int j=0; j<n; j++) {
mu[i][j]=ave[j];
если (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];
}
}
} // запишите результаты в файл:
fs=fopen(outfile, “w”);
если (fs==NULL) {
fprintf(stderr, “Ошибка при открытии выходного файла, %s\n”, outfile);
выход(1);
} fprintf(fs, “%d %d\n”, nc, n);
для (inti=0; i<nc; i++) {
для (int j=0; j<n; j++) fprintf(fs, “%16.8lg”, mu[i][j]);
fprintf(fs, “\n”);
} fclose(fs); // очистить:
удалить [] mu[0];
удалить [] mu; удалить [] mu_p[0];
удалить [] mu_p; удалить [] ave;
удалять [] a[0];
удалять [] a;
if (nsv>0) {
удалить [] s;
удалить [] vt[0];
удалять [] vt;
} вернуть 0;
}
Заключение
В этой статье мы объяснили определение сингулярной стоимостной декомпозиции и помогли разобраться в построении модели на языке Си. Вы можете использовать этот метод для восстановления атмосферных переменных по спутниковым измерениям. Вы также можете использовать этот метод для интерполяции разреженных измерений или для алгоритма машинного обучения. Этот метод помогает в регрессии и классификации набора данных.