search
LoginSignup
7

More than 5 years have passed since last update.

posted at

UnityとF#で機械学習② 行列分解 (QR分解と特異値分解)

はじめに

"F# for Machine Learning Essentials" (Sudipta Mukherjee 著 以下「原著」) の第2章 "Linear Regression"(線形回帰)では、Math.NET for Numericsという.Net用の数値計算ライブラリを用いた線形回帰の方法を説明しています。色々盛りだくさんの内容なので、ここでは行列分解の代表的な方法のQR Decomposition (QR分解)とSingular Value Decomposition (SVD: 特異値分解)に関するところだけ取り上げます。これらを用いることで線形回帰の計算がラクになります(理由は参考資料を参照)。

参考資料

原著のコード こちらにある。

大人になってからの再学習

Wikipedia

Unityでの実行

今回使うMath.NET for NumericsはF#、C#どちらにも対応しており、Unityで実行させる場合も両方に対応させるよう準備する必要があります。原著のコードの部分でQRDとSVDの部分だけをまず試してみます。

まず、Visual StudioでQRDecompositionLibraryというF#ライブラリを作り、以下のコードを入力します。

Library1.fs
namespace QRDecompositionLibrary

open MathNet.Numerics.LinearAlgebra
open System.IO

module LinearRegress = 
    let myMat = matrix  [[1.0;2.0;3.0]
                         [4.0;5.0;2.0]
                         [7.0;0.8;9.0]]
    let qr = myMat.QR() // QR分解
    let svdR = myMat.Svd(true) // 以下 特異値分解の計算
    let s= svdR.S
    let v' = svdR.VT
    let u = svdR.U
    let w = svdR.W
    let myMatSVD = u*w*v'

原著のコードと異なり, namespaceとmoduleが指定されていて、#load...が無いのに注意してください。この時点では、コードのあちこちに赤線(エラー)が出ているはずです。

次に、Referencesにいつも通りUnityEngine.dllを加えるだけで無く、Math.NET用のdllも加えます。そのために、Solution ExplorerでQRDecompositionLibrary(ソリューションではなく、プロジェクトの方)を右クリックし、Manage NuGet Packagesを選択します。

ManageNuget.png

すると、以下のようにNuGet Package Managerが起動します。

NuGetPackageManager.png

右上の検索窓でmathnet.numericsと入力して検索します。MathNet.Numericsが見つかったら、選択してInstallボタンを押してインストールします。いくつかダイアログが出ますが、デフォルトのままでお願いします。さらに、同じ検索で下の方にMathNet.Numerics.FSharpというのも引っかかるので、それもインストールします。うまくいくと、MathNet.Numerics, MathNet.Numerics.FSharpがReferenceに追加されます。

MathNetDLLs.png

これらの作業が終了したら、Library1.fsの中の赤線が無くなってるはずです。ここで、いったんビルドします。

次に、Unity C#で以下のスクリプトを作成します。スクリプトはゲームオブジェクトにアタッチしてください。

SeeFSharp.cs
using UnityEngine;
using System.Collections;
using QRDecompositionLibrary;

public class SeeFSharp : MonoBehaviour
{
    void Start()
    {
        Debug.Log(LinearRegress.myMatSVD);
    }
}

Playすると以下の出力がコンソールに表示されます

image

行列の各要素はLinearRegress.myMatSVD[1, 2]などの形でアクセスできます。

ここで、UnityのAssetsフォルダ以下にMathNet.Numerics.dllがあることが重要です。Unity側でコンパイルエラーが出るときは、必ず確認してください。

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
What you can do with signing up
7