JavaScript机器学习之线性回归

kart 7年前
   <p>原文: <a href="/misc/goto?guid=4959750221174864354" rel="external">Machine Learning with JavaScript : Part 1</a></p>    <p>译者: <a href="/misc/goto?guid=4959746568903379993">Fundebug</a></p>    <p><strong>为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习</strong></p>    <p>使用JavaScript做机器学习?不是应该用Python吗?是不是我疯了才用JavaScript做如此繁重的计算?难道我不用Python和R是为了装逼?<a href="/misc/goto?guid=4958541835409101228" rel="external">scikit-learn</a>(Python机器学习库)不能使用Python吧?</p>    <p>嗯,我并没有开玩笑…</p>    <p>其实呢,类似于Python的<a href="/misc/goto?guid=4958541835409101228" rel="external">scikit-learn</a>,JavaScript开发者也开发了一些机器学习库,我打算用一下它们。</p>    <h3>JavaScript不能用于机器学习?</h3>    <ol>     <li>太慢(幻觉?)</li>     <li>矩阵操作太难(有函数库啊,比如<strong>math.js</strong>)</li>     <li>JavaScript只能用于前端开发(Node.js开发者笑了)</li>     <li>机器学习库都是Python(JS开发者)</li>    </ol>    <h3>JavaScript机器学习库</h3>    <ol>     <li><a href="/misc/goto?guid=4959750221329862572" rel="external">brain.js</a> (神经网络)</li>     <li><a href="/misc/goto?guid=4959623536042912305" rel="external">Synaptic</a> (神经网络)</li>     <li><a href="/misc/goto?guid=4958837490894008197" rel="external">Natural</a> (自然语言处理)</li>     <li><a href="/misc/goto?guid=4958837491714530926" rel="external">ConvNetJS</a> (卷积神经网络)</li>     <li><a href="/misc/goto?guid=4959750221572178382" rel="external">mljs</a> (一系列AI库)</li>     <li><a href="/misc/goto?guid=4959750221686674654" rel="external">Neataptic</a> (神经网络)</li>     <li><a href="/misc/goto?guid=4959750221803988770" rel="external">Webdnn</a> (深度学习)</li>    </ol>    <p>我们将使用<a href="/misc/goto?guid=4959750221572178382" rel="external">mljs</a>来实现线性回归,源代码在GitHub仓库: <a href="/misc/goto?guid=4959750221901345822" rel="external">machine-learning-with-js</a>。下面是详细步骤:</p>    <h3>1. 安装模块</h3>    <pre>  <code class="language-basic">$ yarn add ml-regression csvtojson</code></pre>    <p>或者使用 <code>npm</code></p>    <pre>  <code class="language-bash">$ npm install ml-regression csvtojson</code></pre>    <ul>     <li><a href="/misc/goto?guid=4959750221991153275" rel="external">ml-regression</a>模块提供了一些<strong>回归算法</strong></li>     <li><a href="/misc/goto?guid=4959750222072386551" rel="external">csvtojson</a>模块用于将CSV数据转换为JSON。</li>    </ul>    <h3> </h3>    <h3>2. 初始化并导入数据</h3>    <p>下载<a href="/misc/goto?guid=4959750222158789378" rel="external">.csv数据</a>。</p>    <p>假设你已经初始化了一个NPM项目,请在<strong>index.js</strong>中输入以下内容:</p>    <pre>  <code class="language-javascript">const ml = require("ml-regression");    const csv = require("csvtojson");    const SLR = ml.SLR; // 线性回归    const csvFilePath = "advertising.csv"; // 训练数据    let csvData = [],    X = [],    y = [];    let regressionModel;</code></pre>    <p> </p>    <p>使用csvtojson模块的fromFile方法加载数据:</p>    <pre>  <code class="language-javascript">csv()      .fromFile(csvFilePath)      .on("json", (jsonObj) => {        csvData.push(jsonObj);      })      .on("done", () => {        dressData();        performRegression();    });</code></pre>    <p> </p>    <h3>3. 转换数据</h3>    <p>导入的数据为json对象数组,我们需要使用<strong>dressData</strong>函数将其转化为两个数据向量<strong>x</strong>和<strong>y</strong>:</p>    <pre>  <code class="language-javascript">// 将JSON数据转换为向量数据    function dressData() {     /**      * 原始数据中每一行为JSON对象      * 因此需要将数据转换为向量数据,并将字符串解析为浮点数      * {    * TV: "10",    * Radio: "100",    * Newspaper: "20",    * "Sales": "1000"    * }      */     csvData.forEach((row) = > {      X.push(f(row.Radio));     y.push(f(row.Sales));    }  )  ;    }    // 将字符串解析为浮点数    function f(s) {     return parseFloat(s);    }</code></pre>    <p> </p>    <h3>4. 训练数据并预测</h3>    <p>编写<strong>performRegression</strong>函数:</p>    <pre>  <code class="language-javascript">// 使用线性回归算法训练数据    function performRegression() {        regressionModel = new SLR(X, y);        console.log(regressionModel.toString(3));        predictOutput();    }</code></pre>    <p><strong>regressionModel</strong>的<strong>toString</strong>方法可以指定参数的精确度。</p>    <p><strong>predictOutput</strong>函数可以根据输入值输出预测值。</p>    <pre>  <code class="language-javascript">// 接收输入数据,然后输出预测值    function predictOutput() {        rl.question("请输入X用于预测(输入CTRL+C退出) : ", (answer) => {            console.log('当X = ${answer}时, 预测值y = ${regressionModel.predict(parseFloat(answer))}');            predictOutput();            });    }</code></pre>    <p> </p>    <p><strong>predictOutput</strong>函数使用了Node.js的<a href="/misc/goto?guid=4959750222238678010" rel="external">Readline</a>模块:</p>    <p> </p>    <pre>  <code class="language-javascript">const readline = require("readline");    const rl = readline.createInterface({        input: process.stdin,        output: process.stdout    });</code></pre>    <p> </p>    <h3>5. 完整程序</h3>    <p> </p>    <p>完整的程序<strong>index.js</strong>是这样的:</p>    <pre>  <code class="language-javascript">const ml = require("ml-regression");    const csv = require("csvtojson");    const SLR = ml.SLR; // 线性回归    const csvFilePath = "advertising.csv"; // 训练数据    let csvData = [],        X = [],        y = [];    let regressionModel;    const readline = require("readline");    const rl = readline.createInterface({        input: process.stdin,        output: process.stdout    });    csv()        .fromFile(csvFilePath)        .on("json", (jsonObj) = > {        csvData.push(jsonObj);    })    .on("done", () = > {        dressData();    performRegression();    }) ;    // 使用线性回归算法训练数据    function performRegression() {        regressionModel = new SLR(X, y);        console.log(regressionModel.toString(3));        predictOutput();    }    // 将JSON数据转换为向量数据    function dressData() {        /**         * 原始数据中每一行为JSON对象         * 因此需要将数据转换为向量数据,并将字符串解析为浮点数         * {        * TV: "10",        * Radio: "100",        * Newspaper: "20",        * "Sales": "1000"        * }         */        csvData.forEach((row) = > {          X.push(f(row.Radio));          y.push(f(row.Sales));  });    }    // 将字符串解析为浮点数  function f(s) {      return parseFloat(s);  }    // 接收输入数据,然后输出预测值  function predictOutput() {      rl.question("请输入X用于预测(输入CTRL+C退出) : ", (answer) = > {          console.log(`当X = ${answer}时, 预测值y = ${regressionModel.predict(parseFloat(answer))}`);          predictOutput();      });  }</code></pre>    <p> </p>    <p>执行 <code>node index.js</code> ,则输出如下:</p>    <pre>  <code class="language-bash">$ node index.js</code></pre>    <p>f(x) = 0.202 * x + 9.31</p>    <p>请输入X用于预测(输入CTRL+C退出) : 151.5</p>    <p>当X = 151.5时, 预测值y = 39.98974927911285</p>    <p>请输入X用于预测(输入CTRL+C退出) :</p>    <p> </p>    <p>恭喜!你已经使用JavaScript训练了一个线性回归模型,如下:</p>    <p>f(x) = 0.202 * x + 9.31</p>    <p> </p>    <p>感兴趣的话,请持续关注 <a href="/misc/goto?guid=4959750221901345822" rel="external">machine-learning-with-js</a>,我将使用JavaScript实现各种机器学习算法。</p>