LoginSignup
11
10

More than 5 years have passed since last update.

UnityとF#で機械学習① k-nearest neighbour algorithm

Last updated at Posted at 2016-03-13

はじめに

F#と機械学習に関する本は、日本語のものは見当たらないので、英語の本で勉強することになります。いくつかある中で、最近発刊された"F# for Machine Learning Essentials" (Sudipta Mukherjee 著)は手軽に勉強できそうな感じだったので、ちょっと見て見ることにしました(以下では「原著」と呼ぶ)。ここでは、第1章に出てくる k-nearest neighbour algorithmをUnityで実行してみました。

扱う問題

こちらにある手書き文字のデータを使い、文字認識を行います。各手書き文字は28*28の行列を一列に広げたものとして表現され、入力するデータと一番近いデータをk-nearest neighbour algorithm (参考資料)で抽出します。

Unityでの実行

UnityでのF#の使い方は、こちらの過去記事を参考にしてください。

こちらの記事でも書いた通り、UnityからF#のライブラリを呼び出すにはnamespaceを定義しますが、namespaceは直接に値や関数を持てないので、moduleを指定する必要があります。原著のサンプルコードではmoduleは指定されてないので、こちらで加えます。

また、Unityでは、Monoのバージョンの関係で F# 3.0しか使えないので、F# 4.0の文法を使っている部分は修正が必要です。

Unity用の修正版

Library1.fs
namespace DigitRecognition //追加
open System.IO
open System

module DigitRecognitionEntry = //追加

    type Entry = {Label: string; Values: int list } 

    let distance (values1: int list, values2: int list) = 
  **省略 原著参照**


    let loadValues (filename: string ) = 
  **省略 原著参照**

    let kNN (entries : Entry list, newEntry : string * int[] , k: int) = 
  **省略 原著参照**

    let loaded = loadValues @"*パス*\train.csv"
    let newEntry = ("X,",[|0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;15;48;143;186;244;143;31;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;83;209;253;252;252;252;252;192;15;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;5;166;241;252;253;252;170;162;252;252;113;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;5;61;234;252;252;243;121;44;2;21;245;252;122;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;80;252;252;243;163;50;0;0;0;5;101;88;8;0;0;0;0;0;0;0;0;0;0;0;0;0;0;105;234;252;210;88;0;0;0;0;74;199;240;43;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;185;252;210;21;0;4;12;41;231;249;252;252;55;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;242;252;218;154;154;184;252;253;252;252;248;184;22;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;209;252;252;252;252;252;252;253;252;252;196;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;17;57;142;95;142;61;81;253;252;209;20;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;11;177;255;230;86;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;12;124;252;245;57;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;135;252;252;86;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;79;248;252;233;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;231;252;202;12;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;20;175;248;252;136;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;109;252;252;159;6;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;33;218;252;252;192;141;14;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;132;252;252;252;205;74;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;132;252;252;146;13;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0|]) //原著では途切れていて読めないので、修正した
  **省略 原著参照**
    let guess = fst (List.nth labels 0) //原著はF# 4.0文法だったので修正

Unity C#側はこういう感じで。F#側で指定したnamespaceとmodule名を使用します。

ReadFSharp.cs

using UnityEngine;
using DigitRecognition;

public class ReadFSharp : MonoBehaviour {

    void Start () {
        Debug.Log(DigitRecognitionEntry.guess);
    }

}

実行すると「9」と出るはずです。簡単ですね。

11
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10