Тестирование качества предсказаний

Тестирование качества предсказаний является важнейшим этапом работы с нейронными сетями, так как от него зависит точность и надежность модели. В библиотеке Brain.js предусмотрены механизмы как для базового контроля ошибок, так и для более детального анализа поведения сети на новых данных.


Метрики качества предсказаний

В Brain.js чаще всего используют следующие метрики для оценки модели:

  • Mean Squared Error (MSE) — среднеквадратичная ошибка, рассчитывается как среднее значение квадратов разницы между ожидаемыми и предсказанными значениями.
  • Mean Absolute Error (MAE) — средняя абсолютная ошибка, полезна для оценки смещения предсказаний без чрезмерного влияния выбросов.
  • Accuracy (точность) — доля правильно классифицированных примеров в задачах классификации.

Пример вычисления MSE в Brain.js:

const brain = require('brain.js');

const net = new brain.NeuralNetwork();
// обучение сети
net.train(trainingData);

let totalError = 0;
for (const data of testData) {
  const output = net.run(data.input);
  const error = data.output - output;
  totalError += error * error;
}
const mse = totalError / testData.length;
console.log('Mean Squared Error:', mse);

Важно различать тренировочные и тестовые данные: тестовая выборка не должна использоваться при обучении, иначе оценка качества будет завышена.


Разделение данных на обучающие и тестовые

Правильное разделение данных критично для оценки предсказательной способности сети:

  1. Обучающая выборка (Training set) — используется для обучения сети. Обычно составляет 70–80% от общего объема данных.
  2. Тестовая выборка (Test set) — служит для независимой проверки модели. 20–30% данных, не участвующих в обучении.
  3. Валидационная выборка (Validation set) — может использоваться для подбора гиперпараметров и предотвращения переобучения.

Пример разделения данных:

function splitData(data, testRatio = 0.2) {
  const shuffled = data.sort(() => 0.5 - Math.random());
  const testSize = Math.floor(data.length * testRatio);
  const testData = shuffled.slice(0, testSize);
  const trainData = shuffled.slice(testSize);
  return { trainData, testData };
}

const { trainData, testData } = splitData(dataset);

Тестирование на новых данных

Для оценки способности сети к генерализации используют метод run на ранее невидимых данных:

const testSample = { input: [0.4, 0.6] };
const prediction = net.run(testSample.input);
console.log('Prediction:', prediction);

Если сеть обучена корректно, предсказание должно быть близко к ожидаемому значению.

Для более объемной проверки создается цикл тестирования с подсчетом точности и ошибок:

let correct = 0;
for (const sample of testData) {
  const output = net.run(sample.input);
  const predicted = output[0] > 0.5 ? 1 : 0;
  if (predicted === sample.output[0]) correct++;
}
const accuracy = correct / testData.length;
console.log('Accuracy:', accuracy);

Кросс-валидация

Кросс-валидация позволяет более надежно оценить модель, особенно при ограниченном объеме данных. Разделение происходит на k блоков (folds), где каждый блок поочередно используется как тестовый, а остальные — как тренировочные.

Пример псевдокода кросс-валидации:

function kFoldCrossValidation(data, k = 5) {
  const foldSize = Math.floor(data.length / k);
  let accuracies = [];

  for (let i = 0; i < k; i++) {
    const testData = data.slice(i * foldSize, (i + 1) * foldSize);
    const trainData = data.slice(0, i * foldSize).concat(data.slice((i + 1) * foldSize));
    const net = new brain.NeuralNetwork();
    net.train(trainData);
    
    let correct = 0;
    for (const sample of testData) {
      const output = net.run(sample.input);
      const predicted = output[0] > 0.5 ? 1 : 0;
      if (predicted === sample.output[0]) correct++;
    }
    accuracies.push(correct / testData.length);
  }
  const averageAccuracy = accuracies.reduce((a, b) => a + b, 0) / k;
  return averageAccuracy;
}

console.log('K-Fold Accuracy:', kFoldCrossValidation(dataset));

Визуализация предсказаний

Для анализа ошибок удобно визуализировать результаты предсказаний:

const predictions = testData.map(sample => net.run(sample.input)[0]);
console.log('Predictions vs Expected:', predictions.map((p, i) => ({
  predicted: p.toFixed(2),
  expected: testData[i].output[0]
})));

Сравнение фактических и предсказанных значений позволяет выявить систематические отклонения, переобучение или недообучение модели.


Подводные камни и рекомендации

  • Переобучение (overfitting) возникает при слишком долгом обучении на небольшом объеме данных. Контроль достигается регуляризацией, уменьшением количества эпох и использованием кросс-валидации.
  • Недообучение (underfitting) проявляется, когда сеть не способна уловить закономерности данных. Решение — увеличение числа нейронов или изменение структуры сети.
  • Нормализация данных критична для быстрого обучения и стабильной работы сети: входные значения рекомендуется масштабировать в диапазон [0,1] или [-1,1].

Эти методы тестирования позволяют не только оценить точность предсказаний, но и понять слабые места сети, обеспечивая основу для дальнейшей оптимизации архитектуры и обучения.