DeedleとAccord.NETを使ってサポートベクトルマシン(Support Vector Machine, SVM)を実行する
意外とサクっと出来るんじゃないかと思ったが、そうもいかなかった。とりあえずの元データはirisでこれは適当にcsv形式で保存しておいた。とりあえずCross Validation&可視化はなしで予測値をはじき出すまでで結構苦労したのでまとめる。使っているのはAccord.NETという.NETベースの機械学習ライブラリとDeedleというデータ操作ライブラリ。
また、SVMをF#でどうしたらよいのかは大体ここを見ている。
System.Environment.CurrentDirectory <- __SOURCE_DIRECTORY__ //ライブラリへの参照と名前空間をオープン #r @"..\packages\Accord.2.14.0\lib\net40\Accord.dll" #r @"..\packages\Accord.Math.2.14.0\lib\net40\Accord.Math.dll" #r @"..\packages\Accord.Statistics.2.14.0\lib\net40\Accord.Statistics.dll" #r @"..\packages\Accord.MachineLearning.2.14.0\lib\net40\Accord.MachineLearning.dll" #r @"..\packages\Deedle.1.0.6\lib\net40\Deedle.dll" #r @"..\packages\FSharp.Data.2.0.14\lib\net40\FSharp.Data.dll" #r @"..\packages\FSharp.Charting.0.90.9\lib\net40\FSharp.Charting.dll" open System open System.IO open Accord.MachineLearning open Accord.MachineLearning.VectorMachines open Accord.MachineLearning.VectorMachines.Learning open Accord.Statistics.Kernels open FSharp.Data open FSharp.Charting open Deedle //同フォルダにあるirisファイルのロード let iris = Frame.ReadCsv("iris.csv", hasHeaders=true) //クラスラベル("setosa", "versicolor", "virginica")の数値化 let labels_string = iris.GetColumn<string>("Species").Values let label_map = labels_string |> Seq.distinct |> Seq.mapi (fun i label -> (label, i)) |> Map.ofSeq let labels = labels_string |> Seq.map(fun label -> label_map.[label]) |> Seq.toArray //特徴量となるデータを2次元配列へ let obs2D = iris |> Frame.sliceCols ["Sepal.Length"; "Sepal.Width"; "Petal.Length"; "Petal.Width"] |> Frame.toArray2D //特徴/クラス数のカウント let features = obs2D |> Array2D.length2 let classes = labels_string |> Seq.distinct |> Seq.length //二次元配列を"配列の配列"へ let obs = Array.init (Array2D.length1 obs2D) (fun i -> obs2D.[i, *]) //SVM実行 let algorithm = fun (svm: KernelSupportVectorMachine) (classInputs: float[][]) (classOutputs: int[]) (i: int) (j: int) -> let strategy = SequentialMinimalOptimization(svm, classInputs, classOutputs) strategy :> ISupportVectorMachineLearning let kernel = Linear() let svm = new MulticlassSupportVectorMachine(features, kernel, classes) let learner = MulticlassSupportVectorLearning(svm, obs, labels) let config = SupportVectorMachineLearningConfigurationFunction(algorithm) learner.Algorithm <- config let error = learner.Run() |> printfn "Error: %f" let predict = obs |> Array.map (fun o -> svm.Compute(o))
参考
- Accord.NET Machine Learning Framework
- Deedle: Exploratory data library for .NET
- First steps with Accord.NET SVM in F#
Accord.NETのサイトをよくみるとScatterPlorなんてものが提供されているので、それを使ってみるか…