One-hot encoding — это метод представления категориальных данных в виде бинарных векторов. Каждое уникальное значение категориальной переменной преобразуется в вектор, где все элементы равны 0, кроме одного, соответствующего текущему значению, который равен 1. Этот подход широко используется в машинном обучении и нейронных сетях, включая библиотеку Synaptic для JavaScript, где входные данные сети должны быть числовыми и нормализованными.
Для ручного создания one-hot кодирования сначала необходимо определить множество уникальных категорий. Например, если есть массив цветов:
const colors = ["red", "green", "blue", "green", "red"];
Следующий шаг — формирование словаря уникальных значений:
const uniqueColors = [...new Set(colors)];
console.log(uniqueColors); // ["red", "green", "blue"]
Каждой категории присваивается индекс:
const colorIndex = {};
uniqueColors.forEach((color, idx) => {
colorIndex[color] = idx;
});
console.log(colorIndex); // { red: 0, green: 1, blue: 2 }
Теперь можно создать функцию, которая преобразует категорию в one-hot вектор:
function oneHotEncode(value, categories) {
const vector = new Array(categories.length).fill(0);
const idx = categories.indexOf(value);
if (idx !== -1) vector[idx] = 1;
return vector;
}
Пример использования:
const encodedRed = oneHotEncode("red", uniqueColors);
console.log(encodedRed); // [1, 0, 0]
Для преобразования всего массива категориальных данных удобно
использовать метод map:
const encodedColors = colors.map(color => oneHotEncode(color, uniqueColors));
console.log(encodedColors);
// [[1,0,0],[0,1,0],[0,0,1],[0,1,0],[1,0,0]]
Такой формат данных полностью совместим с входом нейронной сети Synaptic, где каждый элемент массива можно подать на соответствующий нейрон.
Библиотека Synaptic работает с входными и выходными данными в виде числовых массивов. Например, для создания сети с 3 входными нейронами, 4 скрытыми и 3 выходными можно использовать следующий код:
const synaptic = require('synaptic');
const { Layer, Network } = synaptic;
const inputLayer = new Layer(3);
const hiddenLayer = new Layer(4);
const outputLayer = new Layer(3);
inputLayer.project(hiddenLayer);
hiddenLayer.project(outputLayer);
const myNetwork = new Network({
input: inputLayer,
hidden: [hiddenLayer],
output: outputLayer
});
Для обучения сети данные нужно подавать в формате, полученном после one-hot кодирования:
const trainingSet = [
{ input: oneHotEncode("red", uniqueColors), output: [1,0,0] },
{ input: oneHotEncode("green", uniqueColors), output: [0,1,0] },
{ input: oneHotEncode("blue", uniqueColors), output: [0,0,1] }
];
const trainer = new synaptic.Trainer(myNetwork);
trainer.train(trainingSet, {
rate: 0.1,
iterations: 2000,
error: 0.005,
shuffle: true
});
При работе с большим количеством категорий имеет смысл использовать
словари для быстрого поиска индекса категории вместо поиска через
indexOf. Пример оптимизированной функции:
function oneHotEncodeFast(value, indexMap) {
const vector = new Array(Object.keys(indexMap).length).fill(0);
if (value in indexMap) vector[indexMap[value]] = 1;
return vector;
}
Использование:
const encoded = oneHotEncodeFast("green", colorIndex);
console.log(encoded); // [0,1,0]
Этот метод значительно ускоряет преобразование массивов данных с тысячами записей.
One-hot encoding вручную на JavaScript позволяет полностью контролировать процесс подготовки категориальных данных к обучению нейронных сетей в Synaptic. Такой подход обеспечивает гибкость, прозрачность и совместимость с форматом входных и выходных массивов сети. В сочетании с оптимизацией через словари можно эффективно обрабатывать большие объемы данных, не прибегая к сторонним библиотекам.