Published
Edited
Jan 27, 2021
2 stars
Insert cell
md`# Bike Sharing Daily AI Prediction Model - Tensorflow.js`
Insert cell
tf = require('@tensorflow/tfjs')
Insert cell
file = FileAttachment("023 bike-sharing-daily.csv")
Insert cell
dataset = file.csv()
Insert cell
xCategorical = {
function hotEncodeField(field) {
let tensor = tf.tensor(dataset.map(el => parseFloat(el[field.key])), null, 'int32');
if (!field.zeroIndex) {
tensor = tensor.sub(tf.tensor(1, null, 'int32')); // Make the tensor be 0 index
}
const tensorOneHotEncoded = tf.oneHot(tensor, field.categories)
return tensorOneHotEncoded;
}

const hotEncodedTensors = [];
const selectedFields = [
{key: 'season', categories: 4, zeroIndex: false}, // [1,2,3,4]
{key: 'yr', categories: 2, zeroIndex: true}, // [0,1]
{key: 'mnth', categories: 12, zeroIndex: false}, // [1,2,3,4,5,6,7,8,9,10,11,12]
{key: 'holiday', categories: 2, zeroIndex: true}, // [0,1]
{key: 'weekday', categories: 7, zeroIndex: false}, // [1,2,3,4,5,6,7]
{key: 'workingday', categories: 2, zeroIndex: true}, // [0,1]
{key: 'weathersit', categories: 4, zeroIndex: false} // [1,2,3,4]
]
for (let field of selectedFields) {
hotEncodedTensors.push(hotEncodeField(field))
}
const xCategoricalHotEncodedTensor = tf.concat(hotEncodedTensors, -1);
return xCategoricalHotEncodedTensor.array();
}
Insert cell
xNumericalRaw = {
const selectedXKeys = ['temp', 'hum', 'windspeed'];
const xTrainRawArray = dataset.map(data => {
return Object.keys(data).filter(key => selectedXKeys.includes(key)).map(key => {
return parseFloat(data[key])
})
})
const xTrainRawTensor = tf.tensor(xTrainRawArray)
return xTrainRawTensor;
}
Insert cell
minMaxNormalizer = (tensor) => {
return tensor.sub(xNumericalRaw.min()).div(xNumericalRaw.max().sub(xNumericalRaw.min()));
}
Insert cell
xNumerical = minMaxNormalizer(xNumericalRaw)
Insert cell
xAll = tf.concat([xCategorical, xNumerical], -1)
Insert cell
yAll = tf.tensor(dataset.map(data => [parseFloat(data['cnt'])]))
Insert cell
xTrain = xAll.slice(0, parseInt(xAll.shape[0] * 0.8))
Insert cell
yTrain = yAll.slice(0, parseInt(yAll.shape[0] * 0.8))
Insert cell
xTest = xAll.slice(parseInt(xAll.shape[0] * 0.8), parseInt(xAll.shape[0] * 0.2 + 1))
Insert cell
yTest = yAll.slice(parseInt(yAll.shape[0] * 0.8), parseInt(yAll.shape[0] * 0.2 + 1))
Insert cell
mutable history = ({epoch: 0, logs: null});
Insert cell
model = {
const model = tf.sequential({layers: [
tf.layers.dense({units: 100, inputShape: [xTrain.shape[1]], activation: 'relu'}),
tf.layers.dense({units: 100, activation: 'relu'}),
tf.layers.dense({units: 100, activation: 'relu'}),
tf.layers.dense({units: 100, activation: 'relu'}),
tf.layers.dense({units: 1, activation: 'linear'})
]})
model.compile({optimizer: tf.train.adam(), loss: tf.losses.meanSquaredError, metrics: [tf.metrics.meanAbsolutePercentageError]})
await model.fit(xTrain, yTrain, {epochs: 200, validationSplit: 0.2, batchSize: 50, callbacks: {onEpochEnd: (epoch, {meanAbsolutePercentageError, val_meanAbsolutePercentageError}) => {
mutable history = {epoch, meanAbsolutePercentageError: parseFloat(meanAbsolutePercentageError.toFixed(4)), val_meanAbsolutePercentageError: parseFloat(val_meanAbsolutePercentageError.toFixed(4))}
}}})
return model;
}
Insert cell
model.getWeights().toString()
Insert cell
yPredict = model.predict(xTest);
Insert cell
meanAbsolutePercentageErrorTest = {
const errorArray = await tf.metrics.meanAbsolutePercentageError(yTest, yPredict).array()
const improvedErrorArray = errorArray.filter(value => value < 1000) // Remove strange edge cases
const errorTensor = tf.tensor(improvedErrorArray)
const meanValue = errorTensor.mean()
return meanValue.array();
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more