누구나 할 수있는 SVM에 의한 패턴 인식

소개



최근 기계 학습에 관심이 있으며 조금씩 공부하고 있습니다.
그러나 동기 부여를 유지하는 것은 상당히 어렵습니다 ...
그래서 동기 부여를 유지하기 위해 실제로 움직이는 것을 만들어 놀아 보았습니다.

이 기사에서는 Node.js에서 SVM(Support Vector Machine)을 쉽게 구현할 수 있는 단계를 제공합니다.

대상자


  • Node.js를 만진 적이있는 사람
  • npm에 대한 지식이 약간있는 사람
  • 기계 학습에 관심이 있지만 동기 부여를 유지할 수없는 사람
  • (SVM 설명은이 기사에서는 생략 됨)

  • 이번에 만드는 것



    학습 데이터에서 모델을 생성하고 모델에서 테스트 데이터를 분류하는 프로그램을 만듭니다.
    사용할 모듈로 node-svm을 사용합니다.

    버전


    $ node -v
    v10.16.0
    $ npm -v
    6.9.0
    

    Node.js 버전에 따라 node-svm을 설치할 수 없으므로주의가 필요합니다.
    나는 v12.6.0에서 설치할 수 없었다.

    절차



    준비


  • 작업 할 디렉토리 만들기
  • npm init 에서 초기화
  • $ mkdir test_svm
    $ cd test_svm
    $ npm init
    

    모듈 설치



    node-svm 이외에 다음 모듈을 설치합니다.
    - 학습 데이터 및 테스트 데이터를 읽으려면 fs- 읽은 데이터를 구문 분석하기 위해 csv-parse
    $ npm install --save fs
    $ npm install --save csv-parse
    $ npm install --save node-svm
    

    구현



    main.js
    // モジュールの読み込み
    const fs = require("fs");
    const csvSync = require("csv-parse/lib/sync");
    const svm = require("node-svm");
    
    // 学習データ、テストデータのパス
    const learningDataPath = "learning_data.csv";
    const testDataPath = "test_data.csv";
    
    // 生成したモデルを格納するための変数
    var newModel = null;
    
    // メイン処理
    if (require.main === module) {
        var arrLD = readFile(learningDataPath);
        var normArrLD = normalizeArr(arrLD);
        var arrTD = readFile(testDataPath);
        initModel(normArrLD).then(() => {   // 学習データからモデルの生成
            estimate(arrTD);                // モデル生成完了後、テスト
        })
    }
    
    /**
     * ファイルを読み込み、配列として返す関数
     * @param {string} filePath 読み込むファイルのパス
     * @return {Array.<Array.<number>>} 学習データの二次元配列
     */
    function readFile(filePath) {
        var file = fs.readFileSync(filePath);
        var arr = csvSync(file);
        // 以下の処理で、配列内の値が文字列のため数値にパース
        var columnNum = arr.length;
        var rowNum = arr[0].length;
        for(var i=0; i<columnNum; i++) {
            for(var j=0; j<rowNum; j++) {
                arr[i][j] = parseFloat(arr[i][j]);
            }
        }
        return arr;
    }
    
    /**
     * 二次元配列を入力データと正解データに分割し、正規化する関数
     * @param {Array.<Array.<number>>} arr 正規化前の配列
     * @return {Array.<Array.<number>, number>} 正規化後の配列
     */
    function normalizeArr(arr) {
        var columnNum = arr.length;
        var rowNum = arr[0].length;
        var normArr = Array(columnNum);     // 長さががデータ数の配列を用意
        for (var i=0; i<columnNum; i++) {
            normArr[i] = Array(2);          // 学習データと正解データを分割するための配列を用意 normArr[i]=[学習データ,正解データ]
            normArr[i][0] = Array(rowNum-1);// 長さが学習データの次元数の配列を用意 normArr[i]=[[学習データ[0],...,学習データ[rowNum-1]],正解データ]
            // 以下の処理で、正規化
            for (var j=0; j<rowNum-1; j++) {
                normArr[i][0][j] = arr[i][j];
            }
            normArr[i][1] = arr[i][rowNum-1];
        }
        return normArr;
    }
    
    /**
     * 正規化された配列からモデルを生成する関数
     * @param {Array.<Array.<number>, number>} arr 正規化された配列
     * @return {Promise} Promiseのインスタンス
     */
    function initModel(arr) {
        return new Promise(function (resolve, reject) {
            var clf = new svm.CSVC();         // 分類器の生成(今回の設定はデフォルト)
            clf.train(arr).spread(function (model, report) {
                newModel = svm.restore(model);// モデルの生成
                resolve("モデル生成完了");      // モデル生成完了後、thenメソッドが呼ばれる
            });
        });
    }
    
    /**
     * モデルからテストデータの分類を行う関数
     * @param {Array.<Array.<number>>} テストデータ
     */
    function estimate(arr) {
        if(newModel) {  // モデルのnullチェック
            var result = Array(arr.length);
            for(var i=0; i<arr.length; i++) {
                result[i] = newModel.predictSync(arr[i]);   // モデルからテストデータを分類
                console.log(result[i]);                     // 結果の表示
            }
        }
    }
    

    모델 생성이 비동기적으로 수행되므로 Promise를 사용하여 모델 생성 -> 테스트 데이터 분류를 순서대로 처리합니다.

    학습 데이터 준비



    이번에는 RGB 값에서 색상을 분류하는 학습 데이터를 만듭니다.
    왼쪽에서 R값, G값, B값, 정답 데이터입니다.
    정답 데이터는 1이 빨간색, 2가 녹색, 3이 파란색으로 표시됩니다.

    learning_data.csv
    255, 49, 44, 1
    235, 114, 0, 1
    185, 0, 0, 1
    180, 9, 72, 1
    92, 194, 24, 2
    0, 144, 66, 2
    69, 193, 112, 2
    0, 228, 69, 2
    0, 9 ,72, 3
    65, 164, 255, 3
    107, 180, 231, 3
    108, 81, 194, 3
    

    테스트 데이터 준비



    test_data.csv
    228,79,107
    


    위의 색상을 테스트 데이터로 설정합니다.
    빨간색이므로 1(빨간색)으로 분류되면 기쁘네요.

    학습 데이터와 테스트 데이터는 main.js 와 같은 계층에 놓습니다.
    지금까지 파일 구성이 다음과 같다고 생각합니다.

    test_svm/
    ├ main.js
    ├ node_modules/
    ├ package.json
    ├ learning_data.csv
    └ test_data.csv

    실행


    $ node main.js 
    1
    

    이번에 생성한 모델은 [228,79,107]을 1(빨간색)으로 분류했습니다.
    예상대로 결과입니다!

    마지막으로



    나는 SVM에 대한 지식이 거의 없지만 모듈을 사용하여 쉽게 구현할 수있었습니다.
    역시 실제로 움직이고 있는 것을 보면, 안에서 무엇이 행해지고 있는지 궁금하네요~
    이 기사에서는 색상을 분류하는 모델을 생성했지만 다른 것을 분류 할 수도 있습니다.
    원한다면 놀아주세요.

    좋은 웹페이지 즐겨찾기