{"id":46711,"date":"2022-07-01T00:00:00","date_gmt":"2022-07-01T07:00:00","guid":{"rendered":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/"},"modified":"2025-11-13T12:56:06","modified_gmt":"2025-11-13T20:56:06","slug":"predicting-red-wine-quality-using-tensorflowjs-and-griddb","status":"publish","type":"post","link":"https:\/\/www.griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/","title":{"rendered":"Predicting Red Wine Quality using TensorflowJS and GridDB"},"content":{"rendered":"<h2>Introduction<\/h2>\n<p>In this article, we will be using TensorFlowJS and GridDB to train a model and predict the Quality of Red Wine. For this tutorial we will be using the following Libraries for NodeJS.<\/p>\n<ul>\n<li>TensorflowJS &#8211; For training models<\/li>\n<li>DanfoJS &#8211; For working with DataFrames<\/li>\n<\/ul>\n<p><a href=\"https:\/\/github.com\/griddbnet\/Blogs\/tree\/main\/Predicting%20RedWine%20Quality%20Using%20TensorflowJS%20and%20GridDB\"> Full code for article can be found here <\/a><\/p>\n<p>It is useful to work with Node Notebooks for this as they make experimenting with Data Science and ML easier. Visual Studio Code is a great editor that supports Node Notebooks and we are going to use it for this article. Note: For Danfo JS and Tensorflow JS we need at least node version 12 where as griddb works on node version 10.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">const dfd = require(\"danfojs-node\")\nvar fs     = require('fs');\nconst tf = dfd.tensorflow\nconst tfvis = require('@tensorflow\/tfjs-vis')<\/code><\/pre>\n<\/div>\n<p>The Dataset used will be from <a href=\"https:\/\/www.kaggle.com\/datasets\/midouazerty\/redwine\">This Kaggle Dataset<\/a><\/p>\n<p>We will start with loading our dataset into a CSV and inserting into GridDB.<\/p>\n<h2>Loading Data into GridDB and then Fetching Data from GridDB<\/h2>\n<p>First we connect to the GridDB Server. We have it running on the same machine(localhost).<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">var griddb = require('griddb_node');\n\nconst createCsvWriter = require('csv-writer').createObjectCsvWriter;\nconst csvWriter = createCsvWriter({\n  path: 'out.csv',\n  header: [\n    {id: \"fixed acidity\", title:\"fixed acidity\"}, \n    {id: \"volatile acidity\", title:\"volatile acidity\"}, \n    {id: \"citric acid\", title:\"citric acid\"}, \n    {id: \"residual sugar\", title:\"residual sugar\"}, \n    {id: \"chlorides\", title:\"chlorides\"}, \n    {id: \"free sulfur dioxide\", title:\"free sulfur dioxide\"}, \n    {id: \"total sulfur dioxide\" , title:\"total sulfur dioxide\"}, \n    {id: \"density\", title:\"density\"}, \n    {id: \"pH\", title:\"pH\"}, \n    {id: \"sulphates\", title:\"sulphates\"}, \n    {id: \"alcohol\", title:\"alcohol\"}, \n    {id: \"quality\", title:\"quality\"} \n  ]\n});\n\nconst factory = griddb.StoreFactory.getInstance();\nconst store = factory.getStore({\n    \"host\": '239.0.0.1',\n    \"port\": 31999,\n    \"clusterName\": \"defaultCluster\",\n    \"username\": \"admin\",\n    \"password\": \"admin\"\n});\n\/\/ For connecting to the GridDB Server we have to make containers and specify the schema.\nconst conInfo = new griddb.ContainerInfo({\n    'name': \"redwinequality\",\n    'columnInfoList': [\n      [\"name\", griddb.Type.STRING],\n      [\"fixedacidity\", griddb.Type.DOUBLE],\n      [\"volatileacidity\", griddb.Type.DOUBLE],\n      [\"citricacid\", griddb.Type.DOUBLE],\n      [\"residualsugar\", griddb.Type.DOUBLE],\n      [\"chlorides\", griddb.Type.DOUBLE],\n      [\"freesulfurdioxide\", griddb.Type.INTEGER],\n      [\"totalsulfurdioxide\", griddb.Type.INTEGER],\n      [\"density\", griddb.Type.DOUBLE],\n      [\"pH\", griddb.Type.DOUBLE],\n      [\"sulphates\", griddb.Type.DOUBLE],\n      [\"alcohol\", griddb.Type.DOUBLE],\n      [\"quality\", griddb.Type.INTEGER],\n    ],\n    'type': griddb.ContainerType.COLLECTION, 'rowKey': true\n});\n\n\n\/\/ \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\n\nconst csv = require('csv-parser');\n\nconst fs = require('fs');\nvar lst = []\nvar lst2 = []\nvar i =0;\nfs.createReadStream('.\/dataset\/winequality-red.csv')\n  .pipe(csv())\n  .on('data', (row) => {\n    lst.push(row);\n  })\n  .on('end', () => {\n\n    var container;\n    var idx = 0;\n    \n    for(let i=0;i&lt;lst.length;i++){\n        lst[i][\"fixed acidity\"] = parseFloat(lst[i][\"fixed acidity\"])\n\n        lst[i]['volatile acidity'] = parseFloat(lst[i][\"volatile acidity\"])\n        lst[i]['citric acid'] = parseFloat(lst[i][\"citric acid\"])\n        lst[i]['residual sugar'] = parseFloat(lst[i][\"residual sugar\"])\n        lst[i]['chlorides'] = parseFloat(lst[i][\"chlorides\"])\n        lst[i]['free sulfur dioxide'] = parseInt(lst[i][\"free sulfur dioxide\"])\n        lst[i]['total sulfur dioxide'] = parseInt(lst[i][\"total sulfur dioxide\"])\n        lst[i]['density'] = parseFloat(lst[i][\"density\"])\n        lst[i]['pH'] = parseFloat(lst[i][\"pH\"])\n        lst[i]['sulphates'] = parseFloat(lst[i][\"sulphates\"])\n        lst[i]['alcohol'] = parseFloat(lst[i][\"alcohol\"])\n        lst[i]['quality'] = parseFloat(lst[i][\"quality\"])\n\n\n\n\n\n        console.log(parseFloat(lst[i][\"fixed acidity\"]))\n    store.putContainer(conInfo, false)\n        .then(cont => {\n            container = cont;\n            return container.createIndex({ 'columnName': 'name', 'indexType': griddb.IndexType.DEFAULT });\n        })\n        .then(() => {\n            idx++;\n            container.setAutoCommit(false);\n            return container.put([String(idx), lst[i]['fixed acidity'],lst[i][\"volatile acidity\"],lst[i][\"citric acid\"],lst[i][\"residual sugar\"],lst[i][\"chlorides\"],lst[i][\"free sulfur dioxide\"],lst[i][\"total sulfur dioxide\"],lst[i][\"density\"],lst[i][\"pH\"],lst[i][\"sulphates\"],lst[i][\"alcohol\"],lst[i][\"quality\"]]);\n        })\n        .then(() => {\n            return container.commit();\n        })\n       \n        .catch(err => {\n            if (err.constructor.name == \"GSException\") {\n                for (var i = 0; i &lt; err.getErrorStackSize(); i++) {\n                    console.log(\"[\", i, \"]\");\n                    console.log(err.getErrorCode(i));\n                    console.log(err.getMessage(i));\n                }\n            } else {\n                console.log(err);\n            }\n        });\n    }\n    store.getContainer(\"redwinequality\")\n    .then(ts => {\n        container = ts;\n      query = container.query(\"select *\")\n      return query.fetch();\n  })\n  .then(rs => {\n      while (rs.hasNext()) {\n          let rsNext = rs.next();\n          lst2.push(\n            \n                {\n                    'fixed acidity': rsNext[1],\n                    \"volatile acidity\": rsNext[2],\n                    \"citric acid\": rsNext[3],\n                    \"residual sugar\": rsNext[4],\n                    \"chlorides\": rsNext[5],\n                    \"free sulfur dioxide\": rsNext[6],\n                    \"total sulfur dioxide\": rsNext[7],\n                    \"density\": rsNext[8],\n                    \"pH\": rsNext[9],\n                    \"sulphates\": rsNext[10],\n                    \"alcohol\": rsNext[11],\n                    \"quality\": rsNext[12]\n                \n                }\n\n              \n            \n            \n          );\n          \n      }\n\n      \n\n        csvWriter\n        .writeRecords(lst2)\n        .then(()=> console.log('The CSV file was written successfully'));\n\n\n      return \n  }).catch(err => {\n      if (err.constructor.name == \"GSException\") {\n          for (var i = 0; i &lt; err.getErrorStackSize(); i++) {\n              console.log(\"[\", i, \"]\");\n              console.log(err.getErrorCode(i));\n              console.log(err.getMessage(i));\n          }\n      } else {\n          console.log(err);\n      }\n  });   \n    \n  });\n <\/code><\/pre>\n<\/div>\n<p>Then in the same code we fetch the data from GridDB and write it to a csv file. The reason why we did this was because the project file runs on node version 12 where as the griddb code runs on node version 10.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">let df = await dfd.readCSV(\".\/out.csv\")<\/code><\/pre>\n<\/div>\n<p>We then read from the csv file in our node notebook and perform our Exploratory Data Analysis on it. After which we can move to preprocessing and modelling.<\/p>\n<p>We have made a dataframe from the data we got from GridDB in a variable named <code>df<\/code>.<\/p>\n<h2>Exploratory Data Analysis:<\/h2>\n<p>In the EDA phase, we check the data to get an idea of what the data looks like. The simplest thing to do is to check how many rows are there, what are the columns, and what are the data types of each of the columns.<\/p>\n<p>Checking the shape of the dataframe. We have 1599 rows and 12 columns.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">console.log(df.shape)\n\n\/\/  Output\n\/\/ [ 1599, 12 ]<\/code><\/pre>\n<\/div>\n<p>Now checking the columns. We have different quantities given in each row, and then we the quality variable, which we are going to use as our target. console.log(df.columns)<\/p>\n<h2>Output<\/h2>\n<p>[&#8216;fixed acidity&#8217;,&#8217;volatile acidity&#8217;,&#8217;citric acid&#8217;,&#8217;residual sugar&#8217;,&#8217;chlorides&#8217;,&#8217;free sulfur dioxide&#8217;, &#8216;total sulfur dioxide&#8217;,&#8217;density&#8217;,&#8217;pH&#8217;,&#8217;sulphates&#8217;,&#8217;alcohol&#8217;,&#8217;quality&#8217;]<\/p>\n<p>The print function in danfoJS allows printing 10 rows at most, so printing the column types has to be done in two parts.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">df.loc({columns:['fixed acidity',\n'volatile acidity',\n'citric acid',\n'residual sugar',\n'chlorides',\n'free sulfur dioxide','total sulfur dioxide',\n'density']}).ctypes.print()\n\n\/\/  Output\n\/\/ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2564\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557\n\/\/ \u2551 fixed acidity        \u2502 float32 \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 volatile acidity     \u2502 float32 \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 citric acid          \u2502 float32 \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 residual sugar       \u2502 float32 \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 chlorides            \u2502 float32 \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 free sulfur dioxide  \u2502 int32   \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 total sulfur dioxide \u2502 int32   \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 density              \u2502 float32 \u2551\n\/\/ \u255a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2567\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255d<\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">df.loc({columns:['pH',\n'sulphates',\n'alcohol',\n'quality']}).ctypes.print()\n\n\/\/  Output\n\n\/\/ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2564\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557\n\/\/ \u2551 pH        \u2502 float32 \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 sulphates \u2502 float32 \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 alcohol   \u2502 float32 \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 quality   \u2502 int32   \u2551\n\/\/ \u255a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2567\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255d<\/code><\/pre>\n<\/div>\n<p>We will now look at a summary of statistics for all the columns to check their minimums, maximums, means, standard deviations etc.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">df.loc({columns:['fixed acidity',\n'volatile acidity',\n'citric acid',\n'residual sugar',\n'chlorides',\n'free sulfur dioxide','total sulfur dioxide',\n'density']}).describe().round(2).print()\n\n\/\/ Output\n\/\/ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2564\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2564\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2564\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2564\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2564\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2564\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2564\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2564\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557\n\/\/ \u2551            \u2502 fixed acidity     \u2502 volatile acidity  \u2502 citric acid       \u2502 residual sugar    \u2502 chlorides         \u2502 free sulfur dio\u2026  \u2502 total sulfur di\u2026  \u2502 density           \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 count      \u2502 1599              \u2502 1599              \u2502 1599              \u2502 1599              \u2502 1599              \u2502 1599              \u2502 1599              \u2502 1599              \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 mean       \u2502 8.32              \u2502 0.53              \u2502 0.27              \u2502 2.54              \u2502 0.09              \u2502 15.87             \u2502 46.47             \u2502 1                 \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 std        \u2502 1.74              \u2502 0.18              \u2502 0.19              \u2502 1.41              \u2502 0.05              \u2502 10.46             \u2502 32.9              \u2502 0                 \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 min        \u2502 4.6               \u2502 0.12              \u2502 0                 \u2502 0.9               \u2502 0.01              \u2502 1                 \u2502 6                 \u2502 0.99              \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 median     \u2502 7.9               \u2502 0.52              \u2502 0.26              \u2502 2.2               \u2502 0.08              \u2502 14                \u2502 38                \u2502 1                 \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 max        \u2502 15.9              \u2502 1.58              \u2502 1                 \u2502 15.5              \u2502 0.61              \u2502 72                \u2502 289               \u2502 1                 \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 variance   \u2502 3.03              \u2502 0.03              \u2502 0.04              \u2502 1.99              \u2502 0                 \u2502 109.41            \u2502 1082.1            \u2502 0                 \u2551\n\/\/ \u255a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2567\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2567\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2567\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2567\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2567\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2567\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2567\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2567\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255d<\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">df.loc({columns:['pH','sulphates','alcohol','quality']}).describe().round(2).print()\n\n\/\/ Output\n\/\/ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2564\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2564\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2564\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2564\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557\n\/\/ \u2551            \u2502 pH                \u2502 sulphates         \u2502 alcohol           \u2502 quality           \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 count      \u2502 1599              \u2502 1599              \u2502 1599              \u2502 1599              \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 mean       \u2502 3.31              \u2502 0.66              \u2502 10.42             \u2502 5.64              \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 std        \u2502 0.15              \u2502 0.17              \u2502 1.07              \u2502 0.81              \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 min        \u2502 2.74              \u2502 0.33              \u2502 8.4               \u2502 3                 \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 median     \u2502 3.31              \u2502 0.62              \u2502 10.2              \u2502 6                 \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 max        \u2502 4.01              \u2502 2                 \u2502 14.9              \u2502 8                 \u2551\n\/\/ \u255f\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562\n\/\/ \u2551 variance   \u2502 0.02              \u2502 0.03              \u2502 1.14              \u2502 0.65              \u2551\n\/\/ \u255a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2567\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2567\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2567\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2567\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255d<\/code><\/pre>\n<\/div>\n<p>Now to visualize the distributions, we use box plots and histograms.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">## Distribution of Column Values\nconst { Plotly } = require('node-kernel');\nlet cols = df.columns\nfor(let i = 0; i &lt; cols.length; i++)\n{\n    let data = [{\n        x: df[cols[i]].values,\n        type: 'box'}];\n    let layout = {\n        height: 400,\n        width: 700,\n        title: 'Distribution of '+cols[i],\n        xaxis: {title: cols[i]}};\n    \/\/ There is no HTML element named `myDiv`, hence the plot is displayed below.\n    Plotly.newPlot('myDiv', data, layout);\n}<\/code><\/pre>\n<\/div>\n<p>And here is the box plot for two of the columns.<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2022\/05\/BoxPlot.png\"><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2022\/05\/BoxPlot.png\" alt=\"\" width=\"618\" height=\"748\" class=\"aligncenter size-full wp-image-28291\" srcset=\"\/wp-content\/uploads\/2022\/05\/BoxPlot.png 618w, \/wp-content\/uploads\/2022\/05\/BoxPlot-248x300.png 248w, \/wp-content\/uploads\/2022\/05\/BoxPlot-600x726.png 600w\" sizes=\"(max-width: 618px) 100vw, 618px\" \/><\/a><\/p>\n<p>Now Plotting a Scatter Plot between Quality and the other Columns.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">## Scatter Plot between Wine Quality and Column\nlet cols = [...cols]\ncols.pop('quality')\nfor(let i = 0; i &lt; cols.length; i++)\n{\n    let data = [{\n        x: df[cols[i]].values,\n        y: df['quality'].values,\n        type: 'scatter',\n        mode: 'markers'}];\n    let layout = {\n        height: 400,\n        width: 700,\n        title: 'Red Wine Quality vs '+cols[i],\n        xaxis: {title: cols[i]},\n        yaxis: {title: 'Quality'}};\n    \/\/ There is no HTML element named `myDiv`, hence the plot is displayed below.\n    Plotly.newPlot('myDiv', data, layout);    \n}<\/code><\/pre>\n<\/div>\n<p>The plot for two example columns is below:<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2022\/05\/BoxPlot.png\"><img decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2022\/05\/Scatter.png\" alt=\"\" width=\"618\" height=\"748\" class=\"aligncenter size-full wp-image-28291\" \/><\/a><\/p>\n<p>Looking at the plots we can say that these columns could be used to predict the quality of the wine and a model could definitely be made.<\/p>\n<h2>Data Preprocessing:<\/h2>\n<p>Since our data is mostly tidy, we only need to drop any null values<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">df_drop = df.dropNa({ axis: 0 }).loc({columns:['quality','density']})<\/code><\/pre>\n<\/div>\n<h2>Model<\/h2>\n<p>We will create a simple Neural Network with one input layer and one output layer<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">function createModel() {\n    \/\/ Create a sequential model\n    const model = tf.sequential();\n  \n    \/\/ Add a single input layer\n    model.add(tf.layers.dense({inputShape: [1], units: 10, useBias: true}));\n  \n    \/\/ Add an output layer\n    model.add(tf.layers.dense({units: 1, useBias: true}));\n  \n    return model;\n}\n\/\/ Create the model\nconst model = createModel();\ntfvis.show.modelSummary({name: 'Model Summary'}, model);<\/code><\/pre>\n<\/div>\n<p>The Model Summary we get shows the layers and the number of neurons in each layer<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2022\/05\/modelsummary.png\"><img decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2022\/05\/modelsummary.png\" alt=\"\" width=\"618\" height=\"748\" class=\"aligncenter size-full wp-image-28291\" \/><\/a><\/p>\n<p>Now that we have created our model, we need to convert our data into a tensor format for tensorflow to be able to train the model on it.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">function convertToTensor(data) {\n    \/\/ Wrapping these calculations in a tidy will dispose any\n    \/\/ intermediate tensors.<\/code>\n\n    return tf.tidy(() => {\n      \/\/ Step 1. Shuffle the data\n      tf.util.shuffle(data);\n    \n      \/\/ Step 2. Convert data to Tensor\n      const inputs = data.map(d => d[0]);\n      const labels = data.map(d => d[1]);\n      \/\/ console.log(inputs);\n      \/\/ console.log(data);\n    \n      const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);\n      const labelTensor = tf.tensor2d(labels, [labels.length, 1]);\n    \n      \/\/Step 3. Normalize the data to the range 0 - 1 using min-max scaling\n      const inputMax = inputTensor.max();\n      const inputMin = inputTensor.min();\n      const labelMax = labelTensor.max();\n      const labelMin = labelTensor.min();\n    \n      const normalizedInputs = inputTensor.sub(inputMin).div(inputMax.sub(inputMin));\n      const normalizedLabels = labelTensor.sub(labelMin).div(labelMax.sub(labelMin));\n    \n      return {\n        inputs: normalizedInputs,\n        labels: normalizedLabels,\n        \/\/ Return the min\/max bounds so we can use them later.\n        inputMax,\n        inputMin,\n        labelMax,\n        labelMin,\n      }\n    });\n    \n\n}<\/pre>\n<\/div>\n<p>And create a function that specifies how the model is going to train. We set the loss as the Mean Squared Error between the predicted and actual quality values.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">async function trainModel(model, inputs, labels) {\n  \/\/ Prepare the model for training.\n  model.compile({\n    optimizer: \"adam\",\n    loss: tf.losses.meanSquaredError,\n    metrics: ['mse'],\n  });\n\n  const batchSize = 2;\n  const epochs = 5;\n\n  await model.fit(inputs, labels, {\n    batchSize,\n    epochs,\n    shuffle: true,\n    callbacks: tfvis.show.fitCallbacks(\n      { name: 'Training Performance' },\n      ['loss', 'mse'],\n      { height: 200, callbacks: ['onEpochEnd'] }\n    )\n  });\n  return model;\n}<\/code><\/pre>\n<\/div>\n<p>Finally, we can now train our model. For demonstration we have set the epochs to 5 only. They should be set depending on the model and the data. We also leave the first 100 rows of our dataset for testing.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">const tensorData = convertToTensor(df_drop.values)\nconst {inputs, labels} = tensorData;\n\/\/ Train the model\nlet model = await trainModel(model, inputs.slice([100],[-1]), labels.slice([100],[-1]));\nconsole.log('Done Training');\n\n\/\/ Output\n\/\/ Epoch 1 \/ 5\n\/\/ Epoch 2 \/ 5\n\/\/ Epoch 3 \/ 5\n\/\/ Epoch 4 \/ 5\n\/\/ Epoch 5 \/ 5\n\/\/ Done Training\n\n\n\/\/ 11819ms 7392us\/step - loss=0.0450 mse=0.0450 \n\n\/\/ 10833ms 6775us\/step - loss=0.0190 mse=0.0190 \n\n\/\/ 10878ms 6803us\/step - loss=0.0192 mse=0.0192 \n\n\/\/ 10642ms 6655us\/step - loss=0.0192 mse=0.0192 \n\n\/\/ 11025ms 6895us\/step - loss=0.0193 mse=0.0193 <\/code><\/pre>\n<\/div>\n<p>Now that our model has finished training, we can evaluate our model. For this we can use the evaluate function to test to the model on the test set, which was the first 100 rows of our dataset that we left from training.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">model.evaluate(inputs.slice([0],[100]), labels.slice([0],[100]))[0].print() \/\/ Loss\nmodel.evaluate(inputs.slice([0],[100]), labels.slice([0],[100]))[1].print() \/\/ Metric\n\n\/\/ Output\n\/\/ Tensor\n    \/\/ 0.018184516578912735<\/code><\/pre>\n<\/div>\n<p><a href=\"https:\/\/github.com\/griddbnet\/Blogs\/tree\/main\/Predicting%20RedWine%20Quality%20Using%20TensorflowJS%20and%20GridDB\"> Full code for article can be found here <\/a><\/p>\n<p>We have learnt how to use tensorflowJS with GridDB in order to train a model, and make predictions with it.<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2022\/05\/Visor.PNG\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2022\/05\/Visor.PNG\" alt=\"\" width=\"618\" height=\"748\" class=\"aligncenter size-full wp-image-28291\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction In this article, we will be using TensorFlowJS and GridDB to train a model and predict the Quality of Red Wine. For this tutorial we will be using the following Libraries for NodeJS. TensorflowJS &#8211; For training models DanfoJS &#8211; For working with DataFrames Full code for article can be found here It is [&hellip;]<\/p>\n","protected":false},"author":41,"featured_media":28281,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[121],"tags":[],"class_list":["post-46711","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Predicting Red Wine Quality using TensorflowJS and GridDB | GridDB: Open Source Time Series Database for IoT<\/title>\n<meta name=\"description\" content=\"Introduction In this article, we will be using TensorFlowJS and GridDB to train a model and predict the Quality of Red Wine. For this tutorial we will be\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Predicting Red Wine Quality using TensorflowJS and GridDB | GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"og:description\" content=\"Introduction In this article, we will be using TensorFlowJS and GridDB to train a model and predict the Quality of Red Wine. For this tutorial we will be\" \/>\n<meta property=\"og:url\" content=\"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/\" \/>\n<meta property=\"og:site_name\" content=\"GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/griddbcommunity\/\" \/>\n<meta property=\"article:published_time\" content=\"2022-07-01T07:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-13T20:56:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.griddb.net\/wp-content\/uploads\/2022\/05\/50474-alcohol_2560x1707.jpeg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1707\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"griddb-admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:site\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"griddb-admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/\"},\"author\":{\"name\":\"griddb-admin\",\"@id\":\"https:\/\/griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\"},\"headline\":\"Predicting Red Wine Quality using TensorflowJS and GridDB\",\"datePublished\":\"2022-07-01T07:00:00+00:00\",\"dateModified\":\"2025-11-13T20:56:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/\"},\"wordCount\":694,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/griddb.net\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2022\/05\/50474-alcohol_2560x1707.jpeg\",\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/\",\"url\":\"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/\",\"name\":\"Predicting Red Wine Quality using TensorflowJS and GridDB | GridDB: Open Source Time Series Database for IoT\",\"isPartOf\":{\"@id\":\"https:\/\/griddb.net\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2022\/05\/50474-alcohol_2560x1707.jpeg\",\"datePublished\":\"2022-07-01T07:00:00+00:00\",\"dateModified\":\"2025-11-13T20:56:06+00:00\",\"description\":\"Introduction In this article, we will be using TensorFlowJS and GridDB to train a model and predict the Quality of Red Wine. For this tutorial we will be\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/#primaryimage\",\"url\":\"\/wp-content\/uploads\/2022\/05\/50474-alcohol_2560x1707.jpeg\",\"contentUrl\":\"\/wp-content\/uploads\/2022\/05\/50474-alcohol_2560x1707.jpeg\",\"width\":2560,\"height\":1707},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/griddb.net\/en\/#website\",\"url\":\"https:\/\/griddb.net\/en\/\",\"name\":\"GridDB: Open Source Time Series Database for IoT\",\"description\":\"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL\",\"publisher\":{\"@id\":\"https:\/\/griddb.net\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/griddb.net\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/griddb.net\/en\/#organization\",\"name\":\"Fixstars\",\"url\":\"https:\/\/griddb.net\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb.net\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"contentUrl\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"width\":200,\"height\":83,\"caption\":\"Fixstars\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/griddbcommunity\/\",\"https:\/\/x.com\/GridDBCommunity\",\"https:\/\/www.linkedin.com\/company\/griddb-by-toshiba\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\",\"name\":\"griddb-admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb.net\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g\",\"caption\":\"griddb-admin\"},\"url\":\"https:\/\/www.griddb.net\/en\/author\/griddb-admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Predicting Red Wine Quality using TensorflowJS and GridDB | GridDB: Open Source Time Series Database for IoT","description":"Introduction In this article, we will be using TensorFlowJS and GridDB to train a model and predict the Quality of Red Wine. For this tutorial we will be","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/","og_locale":"en_US","og_type":"article","og_title":"Predicting Red Wine Quality using TensorflowJS and GridDB | GridDB: Open Source Time Series Database for IoT","og_description":"Introduction In this article, we will be using TensorFlowJS and GridDB to train a model and predict the Quality of Red Wine. For this tutorial we will be","og_url":"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/","og_site_name":"GridDB: Open Source Time Series Database for IoT","article_publisher":"https:\/\/www.facebook.com\/griddbcommunity\/","article_published_time":"2022-07-01T07:00:00+00:00","article_modified_time":"2025-11-13T20:56:06+00:00","og_image":[{"width":2560,"height":1707,"url":"https:\/\/www.griddb.net\/wp-content\/uploads\/2022\/05\/50474-alcohol_2560x1707.jpeg","type":"image\/jpeg"}],"author":"griddb-admin","twitter_card":"summary_large_image","twitter_creator":"@GridDBCommunity","twitter_site":"@GridDBCommunity","twitter_misc":{"Written by":"griddb-admin","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/#article","isPartOf":{"@id":"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/"},"author":{"name":"griddb-admin","@id":"https:\/\/griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233"},"headline":"Predicting Red Wine Quality using TensorflowJS and GridDB","datePublished":"2022-07-01T07:00:00+00:00","dateModified":"2025-11-13T20:56:06+00:00","mainEntityOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/"},"wordCount":694,"commentCount":0,"publisher":{"@id":"https:\/\/griddb.net\/en\/#organization"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2022\/05\/50474-alcohol_2560x1707.jpeg","articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/","url":"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/","name":"Predicting Red Wine Quality using TensorflowJS and GridDB | GridDB: Open Source Time Series Database for IoT","isPartOf":{"@id":"https:\/\/griddb.net\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/#primaryimage"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2022\/05\/50474-alcohol_2560x1707.jpeg","datePublished":"2022-07-01T07:00:00+00:00","dateModified":"2025-11-13T20:56:06+00:00","description":"Introduction In this article, we will be using TensorFlowJS and GridDB to train a model and predict the Quality of Red Wine. For this tutorial we will be","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb.net\/en\/blog\/predicting-red-wine-quality-using-tensorflowjs-and-griddb\/#primaryimage","url":"\/wp-content\/uploads\/2022\/05\/50474-alcohol_2560x1707.jpeg","contentUrl":"\/wp-content\/uploads\/2022\/05\/50474-alcohol_2560x1707.jpeg","width":2560,"height":1707},{"@type":"WebSite","@id":"https:\/\/griddb.net\/en\/#website","url":"https:\/\/griddb.net\/en\/","name":"GridDB: Open Source Time Series Database for IoT","description":"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL","publisher":{"@id":"https:\/\/griddb.net\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/griddb.net\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/griddb.net\/en\/#organization","name":"Fixstars","url":"https:\/\/griddb.net\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb.net\/en\/#\/schema\/logo\/image\/","url":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","contentUrl":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","width":200,"height":83,"caption":"Fixstars"},"image":{"@id":"https:\/\/griddb.net\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/griddbcommunity\/","https:\/\/x.com\/GridDBCommunity","https:\/\/www.linkedin.com\/company\/griddb-by-toshiba"]},{"@type":"Person","@id":"https:\/\/griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233","name":"griddb-admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb.net\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g","caption":"griddb-admin"},"url":"https:\/\/www.griddb.net\/en\/author\/griddb-admin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts\/46711","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/comments?post=46711"}],"version-history":[{"count":1,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts\/46711\/revisions"}],"predecessor-version":[{"id":51383,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts\/46711\/revisions\/51383"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/media\/28281"}],"wp:attachment":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/media?parent=46711"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/categories?post=46711"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/tags?post=46711"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}