做者:Rising Odegua 與 Stephen Oni | 來源 TensorFlowhtml
Danfo.js 是個 JavaScript 開源庫,提供了高性能、直觀易用的數據結構,支持結構化數據的操做和處理。Danfo.js 深受 Python Pandas 庫的啓發,並提供了相似的接口/API。所以熟悉 Pandas API 且瞭解 JavaScript 的用戶能夠輕鬆上手。node
Danfo.js 的一大目標是爲 JavaScript 開發者提供數據處理、機器學習和 AI 工具。這與咱們的願景一致,本質上也符合 TensorFlow.js 團隊向 Web 引入 ML 的目標。Numpy 和 Pandas 等開源庫全面革新了 Python 中數據操做的便利性。所以不少工具都圍繞它們構建,進一步推進了 Python 中 ML 生態系統的蓬勃發展。git
Danfo.js 創建在 TensorFlow.js 上。也就是說,就像 Numpy 爲 Pandas 的算術運算提供技術支持同樣,咱們是利用 TensorFlow.js 爲咱們的低級算術運算提供技術支持。程序員
Danfo.js 的主要特性github
Danfo.js 速度快。它基於 TensorFlow.js 構建,與張量無縫兼容。您能夠在 Danfo 中加載張量,也能夠將 Danfo 數據結構轉換爲張量。利用這兩個庫,既有了數據處理庫 (Danfo.js),也有了強大的 ML 庫 (TensorFlow.js)。web
如下示例將展現如何從張量對象建立 Danfo DataFrame:npm
const dfd = require("danfojs-node") const tf = require("@tensorflow/tfjs-node") let data = tf.tensor2d([[20,30,40], [23,90, 28]]) let df = new dfd.DataFrame(data) let tf_tensor = df.tensor console.log(tf_tensor); tf_tensor.print()
輸出:json
Tensor { kept: false, isDisposedInternal: false, shape: [ 2, 3 ], dtype: 'float32', size: 6, strides: [ 3 ], dataId: {}, id: 3, rankType: '2' } Tensor [[20, 30, 40], [23, 90, 28]]
您能夠輕鬆地將數組、JSON 或對象轉換爲 DataFrame 對象操做。segmentfault
JSON 對象到 DataFrame:api
const dfd = require("danfojs-node") json_data = [{ A: 0.4612, B: 4.28283, C: -1.509, D: -1.1352 }, { A: 0.5112, B: -0.22863, C: -3.39059, D: 1.1632 }, { A: 0.6911, B: -0.82863, C: -1.5059, D: 2.1352 }, { A: 0.4692, B: -1.28863, C: 4.5059, D: 4.1632 }] df = new dfd.DataFrame(json_data) df.print()
輸出:
帶列標籤的對象數組到 DataFrame:
const dfd = require("danfojs-node") obj_data = {'A': [「A1」, 「A2」, 「A3」, 「A4」], 'B': ["bval1", "bval2", "bval3", "bval4"], 'C': [10, 20, 30, 40], 'D': [1.2, 3.45, 60.1, 45], 'E': ["test", "train", "test", "train"] } df = new dfd.DataFrame(obj_data) df.print()
輸出:
您能夠輕鬆處理浮點和非浮點數據中的缺失數據(以 NaN 表示):
const dfd = require("danfojs-node") let data = {"Name":["Apples", "Mango", "Banana", undefined], "Count": [NaN, 5, NaN, 10], "Price": [200, 300, 40, 250]} let df = new dfd.DataFrame(data) let df_filled = df.fillna({columns: ["Name", "Count"], values: ["Apples", df["Count"].mean()]}) df_filled.print()
輸出:
基於智能標籤的切片、花式索引和大數據集查詢:
const dfd = require("danfojs-node") let data = { "Name": ["Apples", "Mango", "Banana", "Pear"] , "Count": [21, 5, 30, 10], "Price": [200, 300, 40, 250] } let df = new dfd.DataFrame(data) let sub_df = df.loc({ rows: ["0:2"], columns: ["Name", "Price"] }) sub_df.print()
輸出:
強大的 IO 工具,用於從平面文件(CSV 和分隔)加載數據。完整和分塊都可:
const dfd = require("danfojs-node") //read the first 10000 rows dfd.read_csv("file:///home/Desktop/bigdata.csv", chunk=10000) .then(df => { df.tail().print() }).catch(err=>{ console.log(err); })
DataFrame 和 Series 支持 OneHotEncoders、LabelEncoders 等強大的數據預處理函數和 StandardScaler 和 MinMaxScaler 等 Scaler:
const dfd = require("danfojs-node") let data = ["dog","cat","man","dog","cat","man","man","cat"] let series = new dfd.Series(data) let encode = new dfd.LabelEncoder() encode.fit(series) let sf_enc = encode.transform(series) let new_sf = encode.transform(["dog","man"])
輸出:
交互式、靈活且直觀的 API,用於在瀏覽器中繪製 DataFrame 和 Series:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://cdn.jsdelivr.net/npm/danfojs@0.1.1/dist/index.min.js"></script> <title>Document</title> </head> <body> <div id="plot_div"></div> <script> dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv") .then(df => { var layout = { title: 'A financial charts', xaxis: {title: 'Date'}, yaxis: {title: 'Count'} } new_df = df.set_index({ key: "Date" }) new_df.plot("plot_div").line({ columns: ["AAPL.Open", "AAPL.High"], layout: layout }) }).catch(err => { console.log(err); }) </script> </body> </html>
輸出:
示例:泰坦尼克號倖存預測
如下是使用 Danfo.js 和 TensorFlow.js 的簡單端到端分類任務。使用 Danfo 進行數據集的數據加載、操做和預處理,而後導出張量對象。
const dfd = require("danfojs-node") const tf = require("@tensorflow/tfjs-node") async function load_process_data() { let df = await dfd.read_csv("https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv") //A feature engineering: Extract all titles from names columns let title = df['Name'].apply((x) => { return x.split(".")[0] }).values //replace in df df.addColumn({ column: "Name", value: title }) //label Encode Name feature let encoder = new dfd.LabelEncoder() let cols = ["Sex", "Name"] cols.forEach(col => { encoder.fit(df[col]) enc_val = encoder.transform(df[col]) df.addColumn({ column: col, value: enc_val }) }) let Xtrain,ytrain; Xtrain = df.iloc({ columns: [`1:`] }) ytrain = df['Survived'] // Standardize the data with MinMaxScaler let scaler = new dfd.MinMaxScaler() scaler.fit(Xtrain) Xtrain = scaler.transform(Xtrain) return [Xtrain.tensor, ytrain.tensor] //return the data as tensors }
接下來使用 TensorFlow.js 建立一個簡單的神經網絡。
function get_model() { const model = tf.sequential(); model.add(tf.layers.dense({ inputShape: [7], units: 124, activation: 'relu', kernelInitializer: 'leCunNormal' })); model.add(tf.layers.dense({ units: 64, activation: 'relu' })); model.add(tf.layers.dense({ units: 32, activation: 'relu' })); model.add(tf.layers.dense({ units: 1, activation: "sigmoid" })) model.summary(); return model }
最後進行訓練,首先將模型和處理後的數據加載爲張量。這能夠直接饋送到神經網絡。
async function train() { const model = await get_model() const data = await load_process_data() const Xtrain = data[0] const ytrain = data[1] model.compile({ optimizer: "rmsprop", loss: 'binaryCrossentropy', metrics: ['accuracy'], }); console.log("Training started....") await model.fit(Xtrain, ytrain,{ batchSize: 32, epochs: 15, validationSplit: 0.2, callbacks:{ onEpochEnd: async(epoch, logs)=>{ console.log(`EPOCH (${epoch + 1}): Train Accuracy: ${(logs.acc * 100).toFixed(2)}, Val Accuracy: ${(logs.val_acc * 100).toFixed(2)}n`); } } }); }; train()
您可能注意到 Danfo 的 API 與 Pandas 很是類似,即便不是 Javascript 程序員也能夠輕鬆閱讀和理解代碼。您可參考以上演示的完整源代碼 (https://gist.github.com/risen...。
結語
基於網絡的機器學習已經日趨成熟,對應的專用高效數據科學工具必不可少。相似 Danfo.js 的工具讓基於網絡的應用能夠輕鬆支持 ML 特性,從而讓應用生態系統更加豐富多彩。
這場變革始於 TensorFlow.js 爲 Python 帶來的 ML 功能。咱們但願爲 Danfo.js 做爲高效的同伴一路提供支持。咱們對 Danfo.js 的發展充滿期待!但願它也能成爲網絡社區的關鍵成員。