C#で独立成分分析(ICA)

こんにちは!

LiT!関西 Advent Calendar 2014 - Adventarの18日目を担当します、りほやんです。
ちなみに今日は20日です。全然間に合ってないです。すみません。

この機会に、はてぶをはじめました!

これから、いろいろ書いていこうと思います。

 

今回、何かいたらいいかわからなかったのですが、

最近したことを書こうと思います。

 

C#独立成分分析(ICA)をしよう!』

独立成分分析とは:多変量の信号を複数の加法的な成分に分離するための計算手法(ざっくり)
詳しくは
独立成分分析 - Wikipedia

 

今回の開発環境は、Visual Studio2013で

Accord.NET Machine Learning Frameworkで提供されてるメソッドを使います

Accord.NET.Frameworkは、機械学習、数学、統計、などのメソッドや技術を.NETに提供しています。

Accord.NET.FrameworkのインストールはNuget経由で行えます。

(ちなみに、NugetはVisual Studio拡張機能からインストールできます。

詳しくは

参考:.NET 用パッケージマネージャー NuGet のインストールと使い方 | プログラマーズ雑記帳

 

1、Accord.Netをインストール

まず、メニューバーの「プロジェクト」→「Nugetパッケージの管理」をクリック

f:id:rlho:20141220153107p:plain

 

ダイアログが出てきたら、『Accord.net』を検索して

Accord.NETの中の『Accord.Statistics』をインストールしましょう。

f:id:rlho:20141220152611p:plain

 

 2、独立成分分析(ICA)をかける

今回使う『Accord.Statistics』はICAの中でも『Fast-ICA法』を使ってるみたいです。

詳しくは
参考:IndependentComponentAnalysis Class

 

先ほどのリンクにあったサンプルを使って今回は試したいと思います。

ソースコードは以下

// Let's create a random dataset containing
// 5000 samples of two dimensional samples.
// 
double[,] source = Matrix.Random(5000, 2);

// Now, we will mix the samples the dimensions of the samples.
// A small amount of the second column will be applied to the
// first, and vice-versa. 
// 
double[,] mix =
{
    {  0.25, 0.25 },
    { -0.25, 0.75 },    
};

// mix the source data
double[,] input = source.Multiply(mix);

// Now, we can use ICA to identify any linear mixing between the variables, such
// as the matrix multiplication we did above. After it has identified it, we will
// be able to revert the process, retrieving our original samples again

// Create a new Independent Component Analysis
var ica = new IndependentComponentAnalysis(input);


// Compute it 
ica.Compute();

// Now, we can retrieve the mixing and demixing matrices that were 
// used to alter the data. Note that the analysis was able to detect
// this information automatically:

double[,] mixingMatrix = ica.MixingMatrix; // same as the 'mix' matrix
double[,] revertMatrix = ica.DemixingMatrix; // inverse of the 'mix' 


こちらを実行して,mixingMatrixをみてみるとだいたいmixに戻ってますね。
f:id:rlho:20141220164624p:plain
うまく分解できてそうです。



流れを説明すると・・・

流れを説明するとこんな感じ・・・かな?

1, ランダムなデータがはいった二次元配列sourceを作成
2, { 0.25, 0.25 },{ -0.25, 0.75 }というデータを持つmixを作成
3, 二つを掛け合わせて、混合したinputを作成
4, inputをICAにかける
5, mixingMatrixを確認してみるとmixと一緒!分解できてる!

めっちゃ雑でそのまんまですね・・・

分かれた2つのデータはresultに入ってます。
このソースではica.Resultの中ですね。
また、ICAは入力のチャンネル数分、分解されます。
今回は、入力が2つなので、結果も2つに分解されてますね。


もっとまともなデータでやったほうが面白かっただろうな…
時間がなかったということで許してください><
また気が向いたらいい感じのデータで信号分解してみます。

それでは!