- What is K-Nearest Neighbor (KNN) Algorithm
- Use Case : Recommend the right products to a customer
- Steps Needed To Implement KNN Algorithm
- Full Code Demonstration
- Code Breakdown and Analysis
- Conclusion
KNN
is one of the simplest forms of machine learning algorithms mostly used for classification
. KNN
algorithm assumes the similarity
between the new case/data and available cases/dataset and put the new case into the category that is most similar to the available categories.
For example, if we have a dataset of tomatoes and bananas. KNN
will store similar measures like shape and color. When a new object comes it will check its similarity with the color (red or yellow) and shape features and based on the most similar features it will put it in either tomatoes or bananas category.
We will use The KNN
algorithm to recommend products to users based on their purchase history
. It works by finding other users who have similar
purchase histories to the current user, and then recommending products that those similar users have bought, but the current user has not.
In order to find similar users, the algorithm looks at the purchase histories of all users and calculates how similar each user is to the current user. The more similar a user is, the more weight their purchase history is given when recommending products.
For example, if User A has bought a certain set of products, and Users B, C, and D have also bought those same products and other different products, the KNN
algorithm will recommend the other different products to User A. This is because Users B, C, and D are similar to User A based on their purchase history.
Overall, the KNN
algorithm recommends products to a user based on the purchasing behavior of other users who have similar purchase histories.
To implement KNN
algorithm to recommend products for a certain user, you would need the following inputs:
1. The purchase history of the user you want to recommend products for.
2. The purchase history of all other users.
3. A value of k
that determines the number of nearest neighbors to consider when making recommendations.
4. A similarity measure to determine the similarity between the purchase histories of users. This can be based on various factors, such as shared purchases.
With these inputs, you can use the KNN
algorithm to find the k
nearest neighbors (similar users) to the user based on their purchase history, and then recommend products that those neighbors (users) have purchased but the user has not.
I'm going to demonstrate the full code for the KNN
algorithm in JavaScript and then break it down step by step to analyze how it works.
Here's a full example of KNN
algorithm in JavaScript :
//[1] Define the user purchase history as an array of purchased products
const userPurchases = ['A', 'B'];
//[2] Define the purchase histories of other users as arrays of purchased products
const userHistories = [
{
name: 'User1',
purchases: ['A', 'B', 'C'],
},
{
name: 'User2',
purchases: ['B', 'C'],
},
{
name: 'User3',
purchases: ['A', 'C', 'D'],
},
{
name: 'User4',
purchases: ['A', 'B', 'C', 'E'],
}
];
//[3] Define the number of nearest neighbors to consider (similar users)
const k = 2;
//[4] Calculate the similarity between the current user and each other user
function getSimilarities(userPurchases, userHistories) {
const result = [];
userHistories.map((history) => {
let similarity = 0;
// Iterate over each product in the user's purchase history
for (const product of history.purchases) {
// If the user purchased this product
if (userPurchases.includes(product)) {
similarity++;
}
}
// Return the similarity score and the user's name
result.push({ similarity, name: history.name });
});
return result;
}
//[4-1] store the result of the similarity measure
const similarities = getSimilarities(userPurchases, userHistories);
//[4-2] Sort the similarities in descending order
similarities.sort((a, b) => b.similarity - a.similarity);
//[5] Get the names of the k nearest neighbors based on k value and the result of step [4]
const nearestNeighbors = similarities.slice(0, k).map((similarity) => similarity.name);
//[6] Iterate over each of the nearest neighbors
function recommendProducts(userPurchases, userHistories, nearestNeighbors) {
// Define an array of recommended products
const recommendedProducts = [];
nearestNeighbors.forEach((neighbor) => {
// Iterate over each product in the neighbor's purchase history
for (const product of userHistories.find((user) => user.name === neighbor).purchases) {
// If the neighbor has purchased this product and the current user has not
if (userPurchases.indexOf(product) === -1) {
// Add this product to the recommended products array
recommendedProducts.push(product);
}
}
});
return recommendedProducts;
}
const productsToTRecommend = recommendProducts(userPurchases, userHistories, nearestNeighbors);
// Print the recommended products
console.log(productsToTRecommend); //Output: [ 'C', 'C', 'E' ]
Here's a step-by-step breakdown of the code:
-
First, we define an array
userPurchases
that represents the products purchased by the user we want to recommend new products to.const userPurchases = ['A', 'B'];
-
We define an array of objects
userHistories
that represents the purchase history of all users. Each object has aname
property and apurchases
property, which is an array of products purchased by that user.const userHistories = [ { name: 'User1', purchases: ['A', 'B', 'C'], }, { name: 'User2', purchases: ['B', 'C'], }, { name: 'User3', purchases: ['A', 'C', 'D'], }, { name: 'User4', purchases: ['A', 'B', 'C', 'E'], } ];
-
We define a variable
k
that represents the number of nearest neighbors (similar users) we want to consider when recommending products.const k = 2;
-
We define a function
getSimilarities
that calculates the similarity score between the user we want to recommend products to and all other users.function getSimilarities(userPurchases, userHistories) { const result = []; userHistories.map((history) => { let similarity = 0; // Iterate over each product in the user's purchase history for (const product of history.purchases) { // If the user purchased this product if (userPurchases.includes(product)) { similarity++; } } // Return the similarity score and the user's name result.push({ similarity, name: history.name }); }); return result; } const similarities = getSimilarities(userPurchases, userHistories);
-
This code defines a function
getSimilarities()
that takes two arguments:userPurchases
anduserHistories
. It then creates an empty array result to store the similarity scores and user names for each user in userHistories. -
The
map
method is called onuserHistories
, which iterates over each element inuserHistories
and applies a function to each element. The function calculates the similarity score between each user's purchase history anduserPurchases
. -
To calculate the similarity score, the function first initializes a variable
similarity
to0
. Then, it iterates over each product in the user's purchase history using afor-of
loop. For each product, it checks ifuserPurchases
includes the product. If it does, the similarity score is incremented by 1. -
After calculating the similarity score, the function pushes an object with the user's name and similarity score to the
result
array. -
Finally, the function returns the
result
array.
-
We store the result of calling
getSimilarities()
function in a variablesimilarities
.const similarities = getSimilarities(userPurchases, userHistories);
- The result of calling
getSimilarities()
function will be :[ { similarity: 2, name: 'User1' }, { similarity: 1, name: 'User2' }, { similarity: 1, name: 'User3' }, { similarity: 2, name: 'User4' } ]
- We sort the
similarities
array indescending
order based on thesimilarity
score.similarities.sort((a, b) => b.similarity - a.similarity);
- By sorting the array in
descending
order, we can easily select the topk
similar users using theslice
method as we will do in the next step.
-
We extract the top
k
similar users from thesimilarities
array and store their names in an arraynearestNeighbors
.const nearestNeighbors = similarities.slice(0, k).map((similarity) => similarity.name);
- The result of logging
nearestNeighbors
variable will be :[ 'User1', 'User4' ]
-
We define a function
recommendProducts()
that recommends products based on the purchase history of thek
nearest neighbors. The function returns an array of recommended products.function recommendProducts(userPurchases, userHistories, nearestNeighbors) { // Define an array of recommended products const recommendedProducts = []; nearestNeighbors.forEach((neighbor) => { // Iterate over each product in the neighbor's purchase history for (const product of userHistories.find((user) => user.name === neighbor).purchases) { // If the neighbor has purchased this product and the current user has not if (userPurchases.indexOf(product) === -1) { // Add this product to the recommended products array recommendedProducts.push(product); } } }); return recommendedProducts; }
-
The function starts by defining an empty array called
recommendedProducts
, which will eventually contain the products that we recommend to the user. -
The function then iterates over each neighbor in the
nearestNeighbors
array using theforEach
method. For each neighbor, the function finds their purchase history using thefind
method to search theuserHistories
array for the object with aname
property equal to the neighbor's name. -
For each product in the neighbor's purchase history, the function checks if the current user has not already purchased the product (using the
indexOf
method to search theuserPurchases array
). -
If the product has not been purchased by the current user, the function adds it to the
recommendedProducts
array using thepush
method. -
Finally, the function returns the
recommendedProducts
array, which contains the products that we recommend to the user based on the purchase histories of their nearest neighbors -
The result of calling
recommendProducts()
function will be :[ 'C', 'C', 'E' ]
-
To make sure that the
recommendProducts()
function return array contains only unique products, we can use aSet
data structure to store the recommended products. -
A Set automatically
removes duplicates
, so you can simply add all the recommended products to the set and then convert the set back to an array -
Here's an updated version of the
recommendProducts()
function that uses aSet
to store the recommended products:function recommendProducts() { // Define a Set of recommended products const recommendedProductsSet = new Set(); nearestNeighbors.forEach((neighbor) => { // Iterate over each product in the neighbor's purchase history for (const product of userHistories.find((user) => user.name === neighbor).purchases) { // If the neighbor has purchased this product and the current user has not if (userPurchases.indexOf(product) === -1) { // Add this product to the recommended products Set recommendedProductsSet.add(product); } } }); // Convert the recommended products Set to an array const recommendedProducts = Array.from(recommendedProductsSet); return recommendedProducts; } const productsToTRecommend = recommendProducts(); // Print the recommended products console.log(productsToTRecommend); //Output: [ 'C', 'E' ] instead of [ 'C', 'C', 'E' ]
The KNN
algorithm is one of the simplest classification algorithms. Itβs easy to implement and understand, but has a major drawback of becoming significantly slows as the size of that dataset in use grows. Finally, we looked at an example of how the KNN
algorithm could be used to recommend the right products or services to customers using javascript.
π΄οΈ Linkedin: Dragon Slayer π²
π Articles: All Articles written by D.S