iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 21
0
AI & Data

學習PHP Machine Learning的冒險歷程系列 第 21

[2020鐵人賽Day21] 邂逅PHP Machine Learning-類神經網路(NN)-鳶尾花分類(無標準化)

前言

今天的有主要﹑次要目標兩個,主要目標為成功執行MLP(或稱為NN),次要目標是利用無標準化資料進行訓練,與明天的標準化資料進行訓練進行比較。

實作

資料分割

首先跟KNN一樣需要將樣本分為20%訓練與80%的驗證。如果要了結資料為什麼要如此劃分可以參考:
tensorflow:訓練集、測試集、驗證集
深度學習--訓練集驗證集測試集合理劃分比例
[Day29]機器學習:交叉驗證
machine-learning - 關於如何將數據集劃分為訓練和驗證集的經驗規則?
有很多法則都可以參考,可以選擇一個你覺得最符合你的資料分割模式,我們就使用最簡單的80/20分割。

訓練並統計成果

大家還記得在KNN的時候出現的混淆矩陣嗎?(傳送門)我們將資料直接輸入到模型中訓練,然後可以獲得MLP(NN)的準確率評估成果。

https://ithelp.ithome.com.tw/upload/images/20191007/20091333NhXIbqK300.jpg
(1) Overall acurracy:推估正確/總樣本數 = 10/30 = 0.333
(2) Kappa:(pa-pe) / (1-pe)

其中pa = overall acrracy = 0.333
pe = (0 * 0 + 0 * 0 + 30 * 10) / 30 / 30 = 0.333

所以kappa為:(pa-pe)/(1-pe) :(0.667-0.320) / (1-0.320) = 0

結語

跟KNN(0.967)比較,MLP(NN)的準確率比較低,可能是沒有標準化,所以非常低,明天測試標準化之後會不會有比較好的結果。

完整範例Code

<?php
    require_once __DIR__ . '/vendor/autoload.php';

    use Phpml\Dataset\CsvDataset;
    use Phpml\Classification\MLPClassifier;
    use Phpml\NeuralNetwork\ActivationFunction\PReLU;
    use Phpml\NeuralNetwork\ActivationFunction\Sigmoid;

    //讀取Excel
    $dataset = new CsvDataset('iris.csv',4);

    //取得相關數值
    $getSample = $dataset->getSamples();
    $getTargets = $dataset->getTargets();

    //取出分類
    $targetsSingle = Array();
    for($i=0; $i<count($getTargets); $i++){
        if(!in_array($getTargets[$i], $targetsSingle)){
            $targetsSingle[] = $getTargets[$i];
        }
    }
    
    //陣列內容字串轉float
    //因在訓練MLP提供的樣本內容值需要為float
    $getSampleFloat= Array();
    for($i=0; $i<count($getSample); $i++){
        for($t=0; $t<count($getSample[$i]); $t++){
            $getSampleFloat[$i][$t] = (float)$getSample[$i][$t];
        }   
    }

    //------20% 80% Start------
    $count_total = count($getSampleFloat);
    $count_20percent = round($count_total * 0.2);
    $count_80percent = $count_total - $count_20percent;

    $samples_20percent = Array(); //宣告20% samples 為Array
    $labels_20percent = Array();  //宣告20% labels  為Array
    $samples_80percent = Array(); //宣告80% samples 為Array
    $labels_80percent = Array();  //宣告80% labels  為Array

    /**
     * 取得20%數量的亂數
     */
    $randValue = Array(); //定義為陣列
    $count = $count_20percent; //產生指定數量
    for ($i=1; $i<=$count; $i++) {
        $randValueTemp = mt_rand(0,count($getSampleFloat)-1); //產生0~(總數量-1)的亂數
        if (in_array($randValueTemp, $randValue)) { //如果已產生過迴圈重跑
            $i--;
        }else{
            $randValue[] = $randValueTemp; //若無重復則將亂數塞入陣列
        }
    }

    asort($randValue);  //排序
    foreach($randValue as $value){  
        //把陣列內的亂數讀出,就將要的20% samples跟labels寫入到指定變數內
        $samples_20percent[] = $getSampleFloat[$value];
        $labels_20percent[] = $getTargets[$value];

        //刪除已取出資料的陣列元素
        unset($getSampleFloat[$value]);
        unset($getTargets[$value]);
    }

    //20%擷取完畢資料,剩下的資料為80%的部分,array_values()方法函式會返回所指定陣列中所有的值並將其建立新索引(由0開始)。
    $samples_80percent = array_values($getSampleFloat);
    $labels_80percent = array_values($getTargets);
    //------20% 80% End------

    //$mlp = new MLPClassifier(Sample的數量, [[第一個隱藏層(兩個神經元), new 激活函數, [第二個隱藏層(兩個神經元), new 激活函數]], [分類的三種類別]);
    $mlp = new MLPClassifier(4, [[2, new PReLU], [2, new Sigmoid]], $targetsSingle);

    //訓練MLP僅提供樣本和標籤
    $mlp->train(
        $samples = $samples_80percent,
        $targets = $labels_80percent 
    );

    echo("<pre>");
    var_dump($mlp->predict($samples_20percent));
    var_dump($labels_20percent);
    echo("</pre>");
    exit();
?>

上一篇
[2020鐵人賽Day20]邂逅PHP Machine Learning-類神經網路(NN)-鳶尾花分類
下一篇
[2020鐵人賽Day22] 邂逅PHP Machine Learning-類神經網路(NN)-鳶尾花分類(標準化)
系列文
學習PHP Machine Learning的冒險歷程30

尚未有邦友留言

立即登入留言