如何使用JavaScript構(gòu)建機器學(xué)習(xí)模型
目前,機器學(xué)習(xí)領(lǐng)域建模的主要語言是 Python 和 R,前不久騰訊推出的機器學(xué)習(xí)框架 Angel 則支持 Java 和 Scala。本文作者 Abhishek Soni 則用行動告訴我們,開發(fā)機器學(xué)習(xí)模型,JavaScript 也可以。
JavaScript?我不是應(yīng)該使用 Python 嗎?甚至 Scikit-learn 在 JavaScript 上都不工作。
這是可能的,實際上,連我自己都驚訝于開發(fā)者對此忽視的態(tài)度。就 Scikit-learn 而言,Javascript 的開發(fā)者事實上已經(jīng)推出了適用的庫,它會在本文中有所提及。那么,讓我們看看 Javascript 在機器學(xué)習(xí)上能夠做什么吧。
根據(jù)人工智能先驅(qū) Arthur Samuel 的說法,機器學(xué)習(xí)為計算機提供了無需明確編程的學(xué)習(xí)能力。換句話說,它使得計算機能夠自我學(xué)習(xí)并執(zhí)行正確的指令,無需人類提供全部指導(dǎo)。
谷歌已經(jīng)把自己移動優(yōu)先的策略轉(zhuǎn)換到人工智能優(yōu)先很久了。
為什么 JavaScript 在機器學(xué)習(xí)界未被提及過?
- 慢(真的假的?)
- 矩陣操作很困難(這里有庫,比如 math.js)
- 僅用于 Web 開發(fā)(然而這里還有 Node.js)
- 機器學(xué)習(xí)庫通常是在 Python 上的(還好,JS 的開發(fā)者人數(shù)也不少)
在 JavaScript 中有一些可供使用的預(yù)制庫,其中包含一些機器學(xué)習(xí)算法,如線性回歸、SVM、樸素貝葉斯等等,以下是其中的一部分。
- brain.js(神經(jīng)網(wǎng)絡(luò))
- Synaptic(神經(jīng)網(wǎng)絡(luò))
- Natural(自然語言處理)
- ConvNetJS(卷積神經(jīng)網(wǎng)絡(luò))
- mljs(一組具有多種功能的子庫)
首先,我們將使用 mljs 回歸庫來進行一些線性回歸操作。
參考代碼:https://github.com/abhisheksoni27/machine-learning-with-js
1. 安裝庫
$ npm install ml-regression csvtojson
$ yarn add ml-regression csvtojson
ml-regression 正如其名,負責機器學(xué)習(xí)的線性回歸。
csvtojson 是一個用于 node.js 的快速 CSV 解析器,它允許加載 CSV 數(shù)據(jù)文件并將其轉(zhuǎn)換為 JSON。
2. 初始化并加載數(shù)據(jù)
下載數(shù)據(jù)文件(.csv),并將其加入你的項目。
鏈接:http://www-bcf.usc.edu/~gareth/ISL/Advertising.csv
如果你已經(jīng)初始化了一個空的 npm 項目,打開 index.js,輸入以下代碼。
const ml = require('ml-regression');
const csv = require('csvtojson');
const SLR = ml.SLR; // Simple Linear Regression
const csvFilePath = 'advertising.csv'; // Data
let csvData = [], // parsed Data
X = [], // Input
y = []; // Output
let regressionModel;
我把文件放在了項目的根目錄下,如果你想放在其他地方,請記得更新 csvFilePath。
現(xiàn)在我們使用 csvtojson 的 fromFile 方法加載數(shù)據(jù)文件:
csv()
.fromFile(csvFilePath)
.on('json', (jsonObj) => {
csvData.push(jsonObj);
})
.on('done', () => {
dressData(); // To get data points from JSON Objects
performRegression();
});
3. 打包數(shù)據(jù),準備執(zhí)行
JSON 對象被存儲在 csvData 中,我們還需要輸入數(shù)據(jù)點數(shù)組和輸出數(shù)據(jù)點。我們通過一個填充 X 和 Y 變量的 dressData 函數(shù)來運行數(shù)據(jù)。
function dressData() {
/**
* One row of the data object looks like:
* {
* TV: "10",
* Radio: "100",
* Newspaper: "20",
* "Sales": "1000"
* }
*
* Hence, while adding the data points,
* we need to parse the String value as a Float.
*/
csvData.forEach((row) => {
X.push(f(row.Radio));
y.push(f(row.Sales));
});
}
function f(s) {
return parseFloat(s);
}
4. 訓(xùn)練模型開始預(yù)測
數(shù)據(jù)已經(jīng)打包完畢,是時候訓(xùn)練我們的模型了。
為此,我們需要寫一個 performRegression 函數(shù):
function performRegression() {
regressionModel = new SLR(X, y); // Train the model on training data
console.log(regressionModel.toString(3));
predictOutput();
}
performRegression 函數(shù)有一個方法 toString,它為浮點輸出獲取一個名為 precision 的參數(shù)。predictOutput 函數(shù)能讓你輸入數(shù)值,然后將模型的輸出傳到控制臺。它是這樣的(注意,我使用的是 Node.js 的 readline 工具):
function predictOutput() {
rl.question('Enter input X for prediction (Press CTRL+C to exit) : ', (answer) => {
console.log(`At X = ${answer}, y = ${regressionModel.predict(parseFloat(answer))}`);
predictOutput();
});
}
以下是為了增加閱讀用戶的代碼
const readline = require('readline'); // For user prompt to allow predictions
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
5. 大功告成!
遵循以上步驟,你的 index.js 應(yīng)該是這樣:
const ml = require('ml-regression');
const csv = require('csvtojson');
const SLR = ml.SLR; // Simple Linear Regression
const csvFilePath = 'advertising.csv'; // Data
let csvData = [], // parsed Data
X = [], // Input
y = []; // Output
let regressionModel;
const readline = require('readline'); // For user prompt to allow predictions
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
csv()
.fromFile(csvFilePath)
.on('json', (jsonObj) => {
csvData.push(jsonObj);
})
.on('done', () => {
dressData(); // To get data points from JSON Objects
performRegression();
});
function performRegression() {
regressionModel = new SLR(X, y); // Train the model on training data
console.log(regressionModel.toString(3));
predictOutput();
}
function dressData() {
/**
* One row of the data object looks like:
* {
* TV: "10",
* Radio: "100",
* Newspaper: "20",
* "Sales": "1000"
* }
*
* Hence, while adding the data points,
* we need to parse the String value as a Float.
*/
csvData.forEach((row) => {
X.push(f(row.Radio));
y.push(f(row.Sales));
});
}
function f(s) {
return parseFloat(s);
}
function predictOutput() {
rl.question('Enter input X for prediction (Press CTRL+C to exit) : ', (answer) => {
console.log(`At X = ${answer}, y = ${regressionModel.predict(parseFloat(answer))}`);
predictOutput();
});
}
到你的終端上運行 node index.js,得到的輸出會是這樣:
$ node index.js f(x) = 0.202 * x + 9.31 Enter input X for prediction (Press CTRL+C to exit) : 151.***t X = 151.5, y = 39.98974927911285 Enter input X for prediction (Press CTRL+C to exit) :
恭喜!你剛剛在 JavaScript 中訓(xùn)練了***個線性回歸模型。(PS. 你注意到速度了嗎?)































