機械学習と深層学習 - C言語によるシミュレーション①

www.ohmsha.co.jp

ディープラーニングにより実現された知的処理システムの例

システム名 説明
DQN(Deep Q-Network)
ConvNet VGG
CD-DNN-HMM

学習

検査

機械学習の分類(処理の原理に基づく分類)

分類 説明
記号処理 記号処理・記号操作の技術を基礎とした学習手法 機能学習
教示学習
進化的計算 など
統計的処理 学習データを確率的なデータであると仮定し、
これに主として数学的な処理を施すことで学習する手法
統計的手法
ニューラルネットワーク
深層学習 など

機械学習の分類(学習方法に基づく分類)

分類 説明
教師あり学習 ある事例とそれに対する正解がペアで与えられて
学習項目の一つ一つについて先生から教えを受けるような学習
画像認識
音声認識
教師なし学習 正解不正解を先生に教えてもらうのではなく、
与えられた学習データを機械学習システム自身が判断することで学ぶ
入力データの自動分類
強化学習 一つ一つの事項についての正解不正解は与えられないが
最後の結果評価のみが与えられる環境での学習
Q学習
DQN

機械学習の基礎

演繹的学習と帰納的学習

前者はある基礎的抽象的な概念から具体的な知識を得るような学習方法。

後者は複数の具体的な事実から具体的な知識を得るような学習方法。

帰納的学習の例題「株価の予想」

X社の株価は、X社の関連企業A社~J社の株価変動によって決定されるものとする。

まずは学習データセットを用意する。

学習データの番号 前日の関連会社の株価変動(1:上昇、0:下降)
左からA,B,C,D,E,F,G,H,I,J社
翌日のX社の株価変動
1 1000001001 1
2 0101011101 1
3 0100011010 0
4 1001101001 1
5 1001101111 0
6 0000001100 1
7 1111001101 0
8 0111011101 0
9 0011011100 0
10 1110000110 0

次に知識の表現方法を検討する。

(例)

  • パターンマッチングによる
  • 論理式による
  • if-then形式のプロダクションルールによる など

今回は関連会社A~J社の株価動向パターンを表現し、そのパターンにマッチするかどうかで予測する。

学習データセットには正例と負例がある。

正例とは正解として選び出さなければならないデータ

負例とは不正解とすべきデータ

学習データ(正例)を上昇と予想できれば、得点+1

学習データ(負例)を下降と予想できれば、得点+1

学習データ(正例)を下降と予想してしまったら、得点0

学習データ(負例)を上昇と予想してしまったら、得点0

最後に処理フローについて。

  1. 学習データセットの読み込み(学習データと教師データの組)

  2. 乱数による解候補パターンの生成

  3. 解候補パターンを用いて、1つの学習データに対するX社株価の予想

  4. 予想値と教師データを比較し得点をつける

ldata.txt

1 0 0 0 0 0 1 0 0 1     1
0 1 0 1 0 1 1 1 0 1     1
0 1 0 0 0 1 1 0 1 0     0
1 0 0 1 1 0 1 0 0 1     1
1 0 0 1 1 0 1 1 1 1     0
0 0 0 0 0 0 1 1 0 0     1
1 1 1 1 0 0 1 1 0 1     0
0 1 1 1 0 1 1 1 0 1     0
0 0 1 1 0 1 1 1 0 0     0
1 1 1 0 0 0 0 1 1 0     0
0 0 1 1 1 0 0 0 1 0     0
1 0 0 0 1 0 1 0 1 1     0
0 1 0 0 1 0 0 0 1 1     0
0 1 1 0 1 0 0 1 1 1     0
0 0 1 0 1 0 1 0 1 0     0
/*
 * learnstock.c
 *
 *  Created on: 2019/01/26
 */

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#define NUMBER_OF_TEST                 (10000)
#define NUMBER_OF_ASSOCIATED_COMPANY   (10)
#define MAXCHAR_OF_LEARNING_DATA_SET   (32)

typedef struct
{
    uint16_t learning_data;
    bool    teacher_data;
} tLEARNING_DATA_SET;

static int16_t readLearningDataSetFile(char* file_name, tLEARNING_DATA_SET** learning_data_set_table);
static tLEARNING_DATA_SET retrieveLearningDataSet(char* learning_data_set_str);
static uint16_t createCandidateAnswerPattern(void);
static int16_t calculateScore(int number_data_set, tLEARNING_DATA_SET* learning_data_set_table, uint16_t answer_pattern);

int main(int args, char* argv[])
{
    tLEARNING_DATA_SET* learning_data_set_table;

    int16_t    number_of_learning_data_set;
    uint16_t   answer_pattern;
    uint16_t    best_answer_pattern;
    int16_t     score = 0;
    int16_t     best_score = -1;
    int16_t    i;

    if(args != 2)
    {
        printf("Usage: <*.exe> <infile>\n");

        return -1;
    }

    if((number_of_learning_data_set = readLearningDataSetFile(argv[1], &learning_data_set_table)) == -1)
    {
        printf("readLearningDataSetFile fail.");
        return -2;
    }

#if 0
   printf("number_of_learning_data_set = %d\n", number_of_learning_data_set);
   for(i = 0; i < number_of_learning_data_set; i++)
   {
       printf("[%d] 0x%x 0x%x\n", i, learning_data_set_table[i].learning_data, learning_data_set_table[i].teacher_data);
   }
#endif

    for(i = 0; i < NUMBER_OF_TEST; i++)
    {
        answer_pattern = createCandidateAnswerPattern();
        score = calculateScore(number_of_learning_data_set, learning_data_set_table, answer_pattern);
        if(best_score < score)
        {
            best_score = score;
            best_answer_pattern = answer_pattern;
        }
    }

    printf("Best Score : %d\n", best_score);
    printf("Best Answer Patter : 0x%x\n", best_answer_pattern);

    return 0;
}


static int16_t readLearningDataSetFile(char* file_name, tLEARNING_DATA_SET** learning_data_set_table)
{
    int32_t number_of_data_set;
    int32_t i;
    char    data_set[MAXCHAR_OF_LEARNING_DATA_SET];
    FILE*   fp;

    fp = fopen(file_name, "r");
    if(fp == NULL)
    {
        return -1;
    }

    number_of_data_set = 0;
    while(fgets(data_set, sizeof(data_set), fp) != NULL)
    {
        number_of_data_set++;
    }

    printf("Number of dataset : %d\n", number_of_data_set);

    fseek(fp, 0, SEEK_SET);

    *learning_data_set_table = (tLEARNING_DATA_SET*)malloc(sizeof(tLEARNING_DATA_SET) * number_of_data_set);
    //printf("%p\n", *learning_data_set_table);

    for(i = 0; i < number_of_data_set; i++)
    {
        tLEARNING_DATA_SET learning_data_set;

        fgets(data_set, sizeof(data_set), fp);

        learning_data_set = retrieveLearningDataSet(data_set);

        (*learning_data_set_table)[i].learning_data = learning_data_set.learning_data;
        (*learning_data_set_table)[i].teacher_data = learning_data_set.teacher_data;
    }

    return number_of_data_set;
}

static tLEARNING_DATA_SET retrieveLearningDataSet(char* learning_data_set_str)
{
    tLEARNING_DATA_SET data_set;

    uint16_t learning_data;
    bool     teaching_data;
    char*    token;

    uint16_t i;

    token = strtok(learning_data_set_str, " ");
    learning_data = (uint16_t)atoi(token);

    for(i = 1; i < NUMBER_OF_ASSOCIATED_COMPANY; i++)
    {
        token = strtok(NULL, " ");
        learning_data = ((learning_data << 1) + (uint16_t)atoi(token));
    }
    data_set.learning_data = learning_data;

    token = strtok(NULL, " ");
    teaching_data = (uint16_t)atoi(token);
    data_set.teacher_data = teaching_data;

    return data_set;

}

static uint16_t createCandidateAnswerPattern(void)
{
    uint16_t pattern = 0;
    uint16_t i;

    srand((unsigned)time(NULL));
    pattern = rand() % 2;

    for(i = 1; i < NUMBER_OF_ASSOCIATED_COMPANY; i++)
    {
        pattern = (pattern << 1) + (uint16_t)(rand() % 2);
    }

    return pattern;
}

static int16_t calculateScore(int number_data_set, tLEARNING_DATA_SET* learning_data_set_table, uint16_t answer_pattern)
{
    uint16_t learning_data;
    bool     teaching_data;

    uint16_t count_of_match;
    uint16_t score;

    uint16_t i, j;

    uint16_t wild_card_bit_pos;

    //printf("Answer Pattern = 0x%x\n", answer_pattern);
    srand((unsigned)time(NULL));

    score = 0;
    for(i = 0; i < number_data_set; i++)
    {
        learning_data = learning_data_set_table[i].learning_data;
        teaching_data = learning_data_set_table[i].teacher_data;

        count_of_match = 0;
        for(j = 0; j < NUMBER_OF_ASSOCIATED_COMPANY; j++)
        {
            wild_card_bit_pos = rand() % NUMBER_OF_ASSOCIATED_COMPANY;

            if(j == wild_card_bit_pos)
            {
                count_of_match += 2;
                continue;
            }

            if((answer_pattern & (1 << j)) == (learning_data & (1 << j)))
            {
                printf("+");
                count_of_match++;
            }
        }

        if((count_of_match == NUMBER_OF_ASSOCIATED_COMPANY) &&
           (teaching_data == 1))
        {
            score++;
        }
        else if((count_of_match == NUMBER_OF_ASSOCIATED_COMPANY) &&
           (teaching_data == 0))
        {
            score++;
        }

        printf("\n");
    }

    return score;
}