A powerful TensorFlow.js-based collaborative filtering recommendation system for Node.js. Built with TypeScript and designed for performance, scalability, and ease of use.
- 🧠 Matrix Factorization: Uses embeddings-based collaborative filtering for accurate recommendations
- ⚡ Performance Optimized: Batch processing to handle large datasets efficiently
- 💾 Flexible Storage: Pluggable storage strategies (in-memory included, custom implementations supported)
- 📊 Scalable: Handles dynamic user and entity addition without retraining from scratch
- 📝 TypeScript: Full type safety and excellent IDE support
npm install recommendtfYou also need to install TensorFlow.js:
npm install @tensorflow/tfjsimport { Recommendation } from 'recommendtf';
// Create a new recommendation system
const recommender = new Recommendation({
epoch: 5, // Training epochs
embeddingSize: 16, // Embedding dimensions
learningRate: 0.05, // Learning rate
batchSize: 1000, // Batch size for processing
});
// Training data: user-entity interactions
const interactions = [
{ user: 'user1', entity: 'movie1', rating: 5.0 },
{ user: 'user1', entity: 'movie2', rating: 4.5 },
{ user: 'user2', entity: 'movie1', rating: 4.0 },
{ user: 'user2', entity: 'movie3', rating: 4.8 },
// ... more interactions
];
// Train the model
await recommender.fit(interactions);
// Get recommendations for a user
const recommendations = await recommender.getEntities('user1', 5);
console.log('Recommended entities:', recommendations);
// Find users likely to be interested in an entity
const interestedUsers = await recommender.getUsers('movie1', 5);
console.log('Interested users:', interestedUsers);Main class for the recommendation system.
new Recommendation(options?: RecommendationOptions)Options:
epoch?: number- Number of training epochs (default: 5)embeddingSize?: number- Size of embedding vectors (default: 16)learningRate?: number- Learning rate for optimizer (default: 0.05)batchSize?: number- Batch size for processing (default: 1000)storage?: StorageStrategy- Storage strategy (default: InMemoryStorage)disableIsNode?: boolean- Disable IS_NODE variable (default: false)
The disableIsNode: true will suppress the following warning when running in Node.js:
============================
Hi, looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, visit https://github.com/tensorflow/tfjs-node for more details.
============================
Trains the recommendation model on interaction data.
Parameters:
data- Array of user-entity interactions
Interaction Format:
interface Interaction {
user: string | number; // User identifier
entity: string | number; // Entity identifier
rating?: number; // Optional rating (defaults to 1)
}Calling this method multiple times allows for incremental learning, where new interactions are added without losing previous knowledge.
Gets recommended entities for a user.
Parameters:
user- User identifiercount- Number of recommendations to return (default: 10)
Returns: Array of entity IDs ranked by recommendation score
Gets users most likely to be interested in an entity.
Parameters:
entity- Entity identifiercount- Number of users to return (default: 10)
Returns: Array of user IDs ranked by interest likelihood
Exports the trained model as a JSON-serializable object.
Returns: Promise resolving to serialized model data
Saves the trained model to a JSON file (Node.js only).
Parameters:
filePath- Path where to save the model
Creates a new instance from serialized model data.
Parameters:
modelData- Serialized model datastorage- Optional custom storage strategy
Loads a model from a saved JSON file (Node.js only).
Parameters:
filePath- Path to the saved model filestorage- Optional custom storage strategy
The library supports pluggable storage strategies for managing user and entity mappings.
Stores all mappings in memory. Suitable for development and small to medium datasets.
import { InMemoryStorage } from 'recommendtf';
const storage = new InMemoryStorage();
const recommender = new Recommendation({ storage });Implement the StorageStrategy interface for custom storage solutions:
import { StorageStrategy, Id, SerializableStorageData } from 'recommendtf';
class CustomStorage implements StorageStrategy {
async getUserIndex(id: Id): Promise<number | null> {
// Your implementation
}
async getOrCreateUserIndex(id: Id): Promise<number> {
// Your implementation
}
// ... implement all required methods
}import { Recommendation } from 'recommendtf';
const recommender = new Recommendation({
epoch: 10,
embeddingSize: 32,
learningRate: 0.01,
});
// Movie ratings dataset
const movieRatings = [
{ user: 'alice', entity: 'inception', rating: 5.0 },
{ user: 'alice', entity: 'interstellar', rating: 4.8 },
{ user: 'bob', entity: 'comedy_movie', rating: 4.5 },
{ user: 'bob', entity: 'inception', rating: 3.2 },
// ... more ratings
];
await recommender.fit(movieRatings);
// Get movie recommendations for Alice
const aliceRecommendations = await recommender.getEntities('alice', 5);
console.log('Movies for Alice:', aliceRecommendations);
// Find users who might like Inception
const inceptionFans = await recommender.getUsers('inception', 10);
console.log('Inception fans:', inceptionFans);
// Save the trained model
await recommender.save('./models/movie-recommender.json');// Load a pre-trained model
const recommender = await Recommendation.fromPath(
'./models/product-recommender.json'
);
// Get product recommendations for a customer
const productRecommendations = await recommender.getEntities(
'customer_123',
10
);
// Find customers interested in a specific product
const interestedCustomers = await recommender.getUsers('product_456', 20);const recommender = new Recommendation();
// Initial training
await recommender.fit(initialData);
// Later, add more data without losing previous learning
await recommender.fit(newInteractions);
// The model automatically handles new users and entities
const recommendations = await recommender.getEntities('new_user', 5);The library automatically processes data in batches to optimize memory usage and prevent blocking the event loop:
- Training: Data is processed in configurable batch sizes
- Embedding Creation: Large embedding matrices are created incrementally
- Memory Management: Intermediate tensors are properly disposed
// For large datasets
const recommender = new Recommendation({
batchSize: 5000, // Larger batches for better performance
embeddingSize: 64, // Higher dimensional embeddings
epoch: 20, // More training epochs
});
// For memory-constrained environments
const recommender = new Recommendation({
batchSize: 500, // Smaller batches
embeddingSize: 8, // Lower dimensional embeddings
epoch: 5, // Fewer epochs
});The library currently supports json export/import only.
// Save to JSON file (larger file size)
await recommender.save('./models/my-model.json');
// Load from JSON file
const recommender = await Recommendation.fromPath('./models/my-model.json');
// Export/import as object (for in-memory operations)
const modelData = await recommender.export();
// Store modelData in database, cache, or other storage
const recommender = await Recommendation.from(modelData);Contributions are welcome! Please feel free to submit a Pull Request.
For questions and support, please open an issue on the GitHub repository.