Кодирование категориальных переменных

Категориальные переменные представляют собой значения, которые принимают дискретные категории, а не числовые показатели. Прямое использование таких данных в нейронных сетях невозможно, так как большинство моделей ожидает числовой ввод. Библиотека Synaptic не предоставляет встроенных инструментов для автоматического кодирования категориальных данных, поэтому требуется предварительная подготовка входных данных.


Прямое числовое кодирование

Простейший метод преобразования категориальных признаков — присвоение каждой категории уникального числа. Например, для категориального признака Цвет со значениями Красный, Синий, Зелёный можно использовать сопоставление:

const colors = { Красный: 0, Синий: 1, Зелёный: 2 };

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


One-Hot кодирование

One-Hot кодирование устраняет проблему ложного порядка. Каждая категория представляется бинарным вектором длиной равной количеству категорий. Только один элемент вектора равен единице, остальные — нули. Для примера с цветами:

  • Красный → [1, 0, 0]
  • Синий → [0, 1, 0]
  • Зелёный → [0, 0, 1]

В JavaScript это можно реализовать следующим образом:

function oneHotEncode(value, categories) {
    return categories.map(category => category === value ? 1 : 0);
}

const categories = ['Красный', 'Синий', 'Зелёный'];
console.log(oneHotEncode('Синий', categories)); // [0, 1, 0]

One-Hot кодирование широко используется при подготовке данных для Synaptic, так как оно сохраняет категориальную природу признака без введения искусственного порядка.


Использование бинарного кодирования (Binary Encoding)

Бинарное кодирование — компромисс между числовым и One-Hot кодированием. Каждой категории присваивается уникальное число, затем число переводится в двоичную форму. Пример:

Цвет Число Бинарный
Красный 0 00
Синий 1 01
Зелёный 2 10

В JavaScript реализация может выглядеть так:

function binaryEncode(value, categories) {
    const index = categories.indexOf(value);
    const length = Math.ceil(Math.log2(categories.length));
    const binaryString = index.toString(2).padStart(length, '0');
    return binaryString.split('').map(Number);
}

console.log(binaryEncode('Зелёный', categories)); // [1, 0]

Этот метод уменьшает размерность входного вектора по сравнению с One-Hot кодированием, особенно при большом количестве категорий.


Масштабирование и нормализация

После кодирования категориальных признаков часто требуется объединение с числовыми признаками. Для нейронных сетей на основе Synaptic важно, чтобы все входные данные находились в одинаковом диапазоне, обычно [0,1] или [-1,1].

Пример масштабирования числовых признаков:

function normalize(value, min, max) {
    return (value - min) / (max - min);
}

const feature = 75; // возраст
console.log(normalize(feature, 0, 100)); // 0.75

Интеграция с Synaptic

Для построения сети с категориальными входами необходимо собрать единый входной массив, включающий One-Hot векторы и нормализованные числовые признаки. Пример подготовки данных для обучения:

const synaptic = require('synaptic');
const { Layer, Network, Trainer } = synaptic;

const categories = ['Красный', 'Синий', 'Зелёный'];

const data = [
    { color: 'Красный', age: 25, output: [1] },
    { color: 'Синий', age: 40, output: [0] },
];

const trainingSet = data.map(item => ({
    input: [...oneHotEncode(item.color, categories), normalize(item.age, 0, 100)],
    output: item.output
}));

const inputLayer = new Layer(4); // 3 категории + 1 числовой признак
const hiddenLayer = new Layer(5);
const outputLayer = new Layer(1);

inputLayer.project(hiddenLayer);
hiddenLayer.project(outputLayer);

const myNetwork = new Network({
    input: inputLayer,
    hidden: [hiddenLayer],
    output: outputLayer
});

const trainer = new Trainer(myNetwork);
trainer.train(trainingSet, {
    rate: 0.1,
    iterations: 2000,
    error: 0.005,
    shuffle: true
});

Выбор метода кодирования

  • One-Hot кодирование — предпочтительно для небольшого количества категорий, когда важно отсутствие упорядоченности.
  • Бинарное кодирование — полезно при большом числе категорий, чтобы сократить размер входного вектора.
  • Прямое числовое кодирование — редко используется для категориальных признаков, подходит только если категории имеют естественный порядок.

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