Hire the author: Lakshay G
Introduction
The project is available here on github. The INR vs USD topic has always been a hot topic for the past few decades. So, I decided to build an INR USD predictor tool to predict the INR value against 1 USD using brainjs. In this tutorial, I will show you how to build an INR USD predictor using brainjs. I will cover up everything ranging from how to retrieve the dataset and manipulate it according to our need to building the full-stack react app.
Technology stack: brain.js, node.js and react.js
Motivation
Google says “Machine Learning is the future,” and the future of Machine Learning is going to be very bright. I wanted to start with machine learning from a very basic level and javascript is the scripting language I prefer to code in. INR vs USD is such a hot topic that it motivated me to do some projects related to it.
Goal
My goal with this project is to make the readers successfully implement it with the greatest ease and then deploy it online for free.
Glossary
neural network: A neural network is a series of algorithms that endeavors to recognize underlying relationships in a set of data through a process that mimics the way the human brain operates
AI: It stands for artificial intelligence (intelligence demonstrated by machines).
NaN: In computing, NaN stands for Not a Number.
Project Requirements
- Basic programming fundamentals are a must
- Must have a little bit idea about JavaScript, React.js, Node.js, and npm packages(brain.js)
Step by Step tutorial
Backend
- The first step is to retrieve the data set from the internet. I downloaded it as a CSV format from here and converted it into
JSON
format online. The file used in the project can be directly downloaded from here. The training object looks like this:
{
"Date": "1973-01-02",
"Open": 8.02,
"High": 8.02,
"Low": 8.02,
"Close": 8.02
}
Now, while using brainjs we need to have an input property and an output property in our training data of an array of objects. For the input property, I will be using 4 attributes, these are date(Timestamp), open, high, and low whereas for output I will be using the close attribute. Now, this is not very good data for doing predictions because these are not very significant values that affect the value of INR against USD. If you get any better data set online it will do much better predictions.
2. The second step is to manipulate this data according to our needs.
We need to convert this data as shown below:
{'input': input, 'output': output}
where input and output are arrays respectively consisting of properties described in step 1.
3. The third step is to finally set up the server file to create the required API routes, this is how the file looks like:
const brain = require('brain.js') | |
const data = require('./data') | |
const express = require('express') | |
var app = express() | |
const cors = require('cors') | |
app.use(cors()) | |
var trainingData = [] | |
var testingData = [] | |
var maxClose = Math.max.apply(Math, data.map(function(o) { | |
return o.Close | |
})); | |
var maxHigh = Math.max.apply(Math, data.map(function(o) { | |
return o.High | |
})); | |
var maxLow = Math.max.apply(Math, data.map(function(o) { | |
return o.Low | |
})); | |
var maxOpen = Math.max.apply(Math, data.map(function(o) { | |
return o.Open | |
})); | |
for (var i = 0; i < 0.9*data.length; i++) { | |
var input = [new Date(data[i].Date).getTime() / new Date().getTime(), data[i].High / maxHigh, data[i].Low / maxLow, data[i].Open / maxOpen] | |
var output = [data[i].Close / maxClose] | |
trainingData.push({ | |
'input': input, | |
'output': output | |
}) | |
} | |
const net = new brain.NeuralNetwork() | |
app.listen(process.env.PORT || 3001, async () => { | |
net.train(trainingData) | |
console.log('Server started') | |
}) | |
app.get('/predicted', async (req, res) => { | |
for (var i = parseInt(0.9*data.length); i < data.length; i++) { | |
var predict = net.run([new Date(data[i].Date).getTime() / new Date().getTime(), data[i].High / maxHigh, data[i].Low / maxLow, data[i].Open / maxOpen]) | |
var actual = data[i].Close | |
testingData.push({ | |
'Date':data[i].Date, | |
'predicted':predict*maxClose, | |
'actual':actual | |
}) | |
} | |
console.log(testingData) | |
res.json(testingData) | |
}) | |
app.get('/:days', async (req, res) => { | |
var high = trainingData[trainingData.length - 1].input[1] / maxHigh; | |
var low = trainingData[trainingData.length - 1].input[2] / maxLow | |
var open = trainingData[trainingData.length - 1].input[3] / maxOpen | |
for (var i = 0; i < trainingData.length; i++) { | |
if (parseFloat(new Date().getTime() / (req.params.days * 86400000 + new Date().getTime())).toFixed(4) == trainingData[i].input[0].toFixed(4)) { | |
high = trainingData[i].input[1]; | |
low = trainingData[i].input[2]; | |
open = trainingData[i].input[3]; | |
break; | |
} | |
} | |
var output = net.run([parseFloat(new Date().getTime() / (req.params.days * 86400000 + new Date().getTime())), high, low, open]) | |
console.log(output[0] * maxClose) | |
res.json({ | |
'result': output[0] * maxClose | |
}) | |
}) | |
Now, the route (:/days
) is the main heart of this INR USD predictor, which predicts the INR value after req.params.days
against 1 USD and the route(/predicted
) does some predictions on the original dataset and is used for displaying the result in the front-end.
4. Now the server is ready for deployment, follow this in order to deploy it for free on Heroku.
Frontend
- The first step is to create a react-app (use npx create-react-app appname)
- First Lets code the App.js file first for the design and this is how it looksThis file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
import React,{useEffect, useState} from 'react'; import logo from './logo.svg'; import axios from 'axios' import './App.css'; function App() { const[data,setData] = useState({ flag:false, result:'' }) const[predicted,setPredicted] = useState([]) useEffect(()=>{ async function tablePredicted(){ const res = await axios.get(`http://localhost:3001/predicted`) if(res.data) setPredicted(res.data) } tablePredicted() },[]) const{result,flag} = data; async function predict(par){ setData({ ...data, flag:true }) const response = await axios.get(`http://localhost:3001/${par}`) setData({ ...data, flag:false, result:response.data.result }) console.log(result) } return ( <React.Fragment> <div style={{textAlign:'center',fontSize:'larger'}}>Check the value of 1 USD after <input type = "number" onChange={(e)=>{ predict(e.target.value) console.log(e.target.value) }}></input> days in INR</div> <div style={{textAlign:'center', fontSize:'10rem'}}> {!flag && <div><i class="fa fa-inr" aria-hidden="true"></i>{result}</div> } </div> <React.Fragment> </React.Fragment> {predicted.length && <table class="table"> <thead> <tr> <th>Date</th> <th>Predicted</th> <th>Actual</th> </tr> </thead> <tbody> {predicted.map((result)=>( <tr> <td>{result.Date}</td> <td>{result.predicted}</td> <td>{result.actual}</td> </tr> ))} </tbody> </table>} </React.Fragment> ); } export default App; - Now, the client application is ready for deployment (follow this for help) and it will finally look like

You just need to input the number of days after which you want the INR value against 1 USD.
Learning Tools and Strategies
- Don’t write messy code, everything should be well understood. Doing this will automatically help you when it comes to debugging.
- Do a console.log() at each major step you feel is important, or that you feel may throw some kind of error. This is so that you can get the result of each major code-snippet.
- The last most important thing is to make sure that the training data consists of only numbers and not strings, otherwise, brain.js neural network will not train it and throw an error NaN which means Not a Number.
Search terms
inr usd predictor brainjs, inr vs usd, brainjs inr usd predictor
Reflective Analysis
After implementing this project my theoretical knowledge related to neural networks has increased because I was visually able to see what was happening. Explore more of this brain.js documentation here. The most common mistake people are expected to make is to insert strings in training data rather than numbers and as a result, the neural network is not able to train the data and throws NaN error.
Conclusions and Future Directions
It is a basic and very easy implementation of the INR USD predictor using brain.js by training the neural network to predict accurate results. The good thing about this project is that it is going to return very fast results because the network will be trained once when the server is deployed rather than with every request. The server application and the client application are deployed separately, so I would suggest trying deploying them both together as a single application.
Citations
I used https://www.deccanherald.com/sites/dh/files/article_images/2020/05/19/iStock-1063408740-1497894930-1585041865.jpg for the featured image.
The project is available here, and if you want to code along click here.
Hire the author: Lakshay G
Overall Great Article 🙂 . One thing which can be done is to not use the complete training data and use some of the training data as a way of test the model. In the UI we can show both Predicted and Actual Value that way. I will suggest to use around 80% data for training and remaining 20% can be used for testing and show user comparison of actual and predicted value.
Update: Feedback has been addressed. I would like to give kudos to Lakshay Gupta it was interesting to know there are libraries for machine learning in JavaScript 🙂
Thanks for the positive feedback Vinayak! Much appreciated