Машинне навчання стало незамінним інструментом для аналізу фінансових ринків. У цій статті я розповім про свій досвід створення додатка для прогнозування курсу біткоїна за допомогою TensorFlow.js та Node.js.
Протягом останніх років криптовалюти, особливо біткоїн, привертають значну увагу інвесторів та трейдерів. Висока волатильність цього активу створює як можливості для заробітку, так і значні ризики. Я вирішив дослідити, чи можна використати сучасні технології машинного навчання для прогнозування коливань ціни біткоїна.
Моя мета — створити простий, але ефективний додаток, який:
- Завантажує історичні дані про ціну біткоїна
- Обробляє та аналізує ці дані
- Будує модель машинного навчання
- Робить прогноз на майбутні зміни ціни
Технологічний стек
Для реалізації проекту я обрав наступні технології:
- Node.js — середовище виконання JavaScript
- TensorFlow.js — бібліотека машинного навчання від Google
- CoinGecko API — джерело історичних даних про криптовалюти
Ключовою перевагою цього стеку є можливість написати весь код на JavaScript, що спрощує розробку та дозволяє легко перенести логіку між серверною частиною та клієнтом, якщо знадобиться.
Архітектура додатка
Мій додаток складається з трьох основних компонентів:
- Сервіс збору даних — відповідає за отримання історичних даних через API
- Препроцесор даних — нормалізує та підготовлює дані для навчання
- Модель прогнозування — створює, навчає та використовує модель машинного навчання
Збір даних
Для отримання історичних даних я використав CoinGecko API, яке надає безкоштовний доступ до цінової історії криптовалют:
// Функція для отримання даних
async function fetchBitcoinData(days = 60) {
console.log(Завантаження даних про біткоїн за ${days} днів...);
try {
const response = await fetch(
https://api.coingecko.com/api/v3/coins/bitcoin/market_chart?vs_currency=usd&days=${days}&interval=daily
);
if (!response.ok) {
throw new Error(Помилка API: ${response.status});
}
const data = await response.json();
return data.prices.map(price => ({
timestamp: price[0],
price: price[1]
}));
} catch (error) {
console.error('Помилка отримання даних:', error);
throw error;
}
}
Препроцесинг даних
Для ефективного навчання нейронної мережі необхідно правильно підготувати дані. Я реалізував:
- Нормалізацію даних — приведення всіх значень до діапазону [0, 1]:
function normalizeData(data) {
const max = Math.max(...data);
const min = Math.min(...data);
return {
normalizedData: data.map(val => (val - min) / (max - min)),
min,
max
};
}
- Підготовку часових рядів — формування вікон даних для прогнозування:
function prepareData(data, windowSize = 7) {
const X = [];
const y = [];
for (let i = 0; i < data.length - windowSize; i++) {
X.push(data.slice(i, i + windowSize));
y.push(data[i + windowSize]);
}
// Перетворюємо в тензори TensorFlow
const xTensor = tf.tensor2d(X);
const yTensor = tf.tensor2d(y, [y.length, 1]);
return [xTensor, yTensor];
}
Модель машинного навчання
Я створив просту нейронну мережу з одним прихованим шаром:
async function trainTensorFlowModel(X, y) {
// Створюємо просту модель з 1 прихованим шаром
const model = tf.sequential();
model.add(tf.layers.dense({
units: 10,
activation: 'relu',
inputShape: [X.shape[1]]
}));
model.add(tf.layers.dense({
units: 1,
activation: 'linear'
}));
// Компілюємо модель
model.compile({
optimizer: tf.train.adam(0.01),
loss: 'meanSquaredError'
});
// Тренуємо модель
console.log('\nНавчання моделі TensorFlow...');
const startTime = Date.now();
await model.fit(X, y, {
epochs: 100,
callbacks: {
onEpochEnd: (epoch, logs) => {
if (epoch % 10 === 0) {
console.log(Епоха ${epoch+1}/100, Похибка: ${logs.loss.toFixed(6)});
}
}
}
});
const endTime = Date.now();
console.log(Навчання завершено за ${(endTime - startTime) / 1000} секунд);
return model;
}
Виклики та проблеми
Під час розробки я зіткнувся з кількома технічними проблемами:
1. Складнощі з бекендами TensorFlow.js
TensorFlow.js може працювати у трьох режимах:
- Чистий JavaScript (найповільніший, але найбільш сумісний)
- Node.js з CPU (швидший, використовує нативні модулі)
- Node.js з GPU (найшвидший, потребує CUDA)
Я зіткнувся з проблемами при встановленні нативних модулів Node.js. Помилка “Помилкова інструкція (збережено знімок оперативної пам’яті)” виникала при спробі використати GPU-версію.
Рішення: Я перейшов на CPU-версію, яка все одно забезпечує хорошу продуктивність для моїх потреб.
2. Проблеми з імпортами у ES модулях
Сучасний JavaScript має два типи модулів: CommonJS (require) та ES модулі (import/export). Я зіткнувся з помилками коли намагався використовувати require в ES модулях.
Рішення: Я перейшов повністю на ES модулі, використовуючи import замість require.
// Замість
const tf = require('@tensorflow/tfjs-node');
// Використовуємо
import * as tf from '@tensorflow/tfjs-node';
3. Балансування між точністю та складністю моделі
Початково я спробував реалізувати складну модель LSTM (Long Short-Term Memory), але зіткнувся з проблемами продуктивності та перенавчання.
Рішення: Я перейшов до простішої моделі з лише одним прихованим шаром, яка виявилася достатньою для моїх цілей. Іноді простіші моделі працюють краще, особливо коли даних небагато.
Результати та висновки
Я успішно створив додаток, який:
- Завантажує історичні дані про ціну біткоїна
- Нормалізує та підготовлює дані для навчання
- Створює та навчає модель машинного навчання
- Робить прогноз на наступний день
Останній прогноз показав очікуване зростання ціни біткоїна на 1.57% — з $82,676.78 до $83,973.14.
Ключові висновки:
- TensorFlow.js ефективний для прототипування — дозволяє швидко створювати та тестувати моделі машинного навчання.
- Важливість препроцесингу даних — нормалізація та правильна підготовка часових рядів критично важливі для успішного навчання моделі.
- Складніше не завжди краще — для багатьох задач прості моделі можуть давати результати, порівнянні зі складними, при значно меншій обчислювальній вартості.
- Необхідність кросплатформної сумісності — проблеми з нативними модулями показали важливість забезпечення сумісності на різних платформах.
Подальший розвиток
Для вдосконалення додатка в майбутньому я планую:
- Включити більше факторів у модель (об’єми торгів, новинний сентимент)
- Порівняти різні архітектури моделей (LSTM, GRU, трансформери)
- Реалізувати валідацію моделі на історичних даних (бектестінг)
- Створити веб-інтерфейс для зручного використання
Висновок
Мій проект демонструє, що навіть з простими інструментами та підходами можна створити функціональну систему прогнозування фінансових часових рядів. TensorFlow.js у поєднанні з Node.js надає потужний та гнучкий фреймворк для таких завдань.
Хоча жоден прогноз не може гарантувати точність на волатильних ринках, подібні інструменти можуть надати цінні дані для прийняття більш обґрунтованих інвестиційних рішень.
Примітка: Цей додаток створено виключно в освітніх цілях. Його прогнози не слід розглядати як інвестиційні поради. Інвестування в криптовалюти пов’язане зі значними ризиками.