Нормировка входных данных в нерокомпьютинге применяется давно. Основная её цель — это привести все разнородные (различные единицы измерений) входные сигналы к единому формату. Но если в отдельных случаях для обучения искусственного нейрона можно обойтись и без нормирования, то в случае VMR, этот фокус не пройдёт. Дело в том, что предварительное нормирование входных данных к диапазоно от -1 до 1 включительно является обязательной подготовкой к последующей инвариантности.
Формулы для нормирования в LibVMR линейные, т.к. нелинейность достигается с помощью ядерных преобразований. Сначала для каждой объясняющей переменной находим максимальное (max) и минимальное (min) значения, а потом уже взяв конкретное значение переменной, загоняем его в диапазон от -1 до 1 включительно:
v' = 2 * (v – min) / (max – min) – 1
где:
v' – нормированное значение ненормированной переменной v
Помимо самого нормирования входных данных нам ещё необходимо отделить значения объясняющих переменных и зависимой переменной, разнеся их по разным массивам.
Создадим код на Java:
package libvmr;
/**
* Векторная машина Решетова
* @author Yury V. Reshetov
* @version 1.0
*/
public class VMR {
/**
* Максимумы столбцов обучающей выборки
*/
private double[] maxs = null;
/**
* Минимумы столбцов обучающей выборки
*/
private double[] mins = null;
/**
* Значения зависимых переменных
*/
private double[] ideals = null;
/**
* Нормирование обучающей выборки
* @param samples ненормированная обучающая выборка
* @return Нормированная обучающая выборка
*/
private double[][] normSetting(double[][] samples) {
// Вытаскиваем последний столбец обучающей выборки - результаты
this.ideals = new double[samples.length];
for (int i = 0; i < samples.length; i++) {
this.ideals[i] = this.convertToRange(samples[i][samples[0].length - 1], 1d, 0d);
}
double[][] normsamples = new double[samples.length][samples[0].length - 1];
// Ищем максимумы и минимумы
this.maxs = new double[normsamples[0].length];
this.mins = new double[normsamples[0].length];
for (int j = 0; j < normsamples[0].length; j++) {
double max = samples[0][j];
double min = max;
for (int i = 1; i < normsamples.length; i++) {
if (samples[i][j] > max) {
max = samples[i][j];
}
if (samples[i][j] < min) {
min = samples[i][j];
}
}
this.maxs[j] = max;
this.mins[j] = min;
}
// Нормализуем
for (int i = 0; i < normsamples.length; i++) {
for (int j = 0; j < normsamples[0].length; j++) {
normsamples[i][j] = this.convertToRange(samples[i][j],this.maxs[j],this.mins[j]);
}
}
return normsamples;
}
/**
* Преобразование переменных из диапазона от минимального значения до максимального включительно к диапазону от -1 до 1 включительно
* @param value значение переменной
* @param maximmumvalue максимальное значение переменной
* @param minimumvalue минимальное значение переменной
* @return нормированное значение переменной в диапазоне от -1 до 1 включительно
*/
private double convertToRange(double value, double maximmumvalue, double minimumvalue) {
return 2d * (value - minimumvalue) / (maximmumvalue - minimumvalue) - 1d;
}
}
Комментариев нет:
Отправить комментарий