LoginSignup
9
8

More than 5 years have passed since last update.

word2vecのC#実装

Last updated at Posted at 2016-07-07

単語の意味をベクトルで表現する手法を提供するword2vecですが、これをC#で実装したものがgitHubに上がっています。

元々のC言語のソースと見比べてみましたが、もうほとんど同じですね。そのままソース持ってきて、C#の文法に沿って微修正したような印象を受けました。

ただし、ちょっと不具合と思われる箇所が...

不具合に1か所気づいたのでメモしておきます。

Word2Vec.cs中のコンストラクタの部分です。ここにシグモイド関数の計算結果をテーブルに保持させるロジックがあります。

Word2Vec.cs
 for (var i = 0; i < ExpTableSize; i++)
 {
     _expTable[i] = (float)Math.Exp((i / ExpTableSize * 2 - 1) * MaxExp); // Precompute the exp() table
     _expTable[i] = _expTable[i] / (_expTable[i] + 1); // Precompute f(x) = x / (x + 1)
 }

恐らくシグモイド関数の計算時間を節約するために、あらかじめ計算結果をテーブル化させておいているんでしょうね。

問題は、このロジック中の変数 i なのですが、VisualStudioのデバッガで確認したところ、int型として扱われています。なので、Exp()関数の引数中の計算式「i / ExpTableSize * 2」は、常に0になってしまいます。ですので、_expTable[]にはシグモイド関数の計算結果は入りません。一定の値(0.00247262325)が全配列要素に入るだけです。

なので、以下のように修正する必要があると思います。

Word2Vec.cs
 for (var i = 0; i < ExpTableSize; i++)
 {
     _expTable[i] = (float)Math.Exp(((float)i / ExpTableSize * 2 - 1) * MaxExp); // Precompute the exp() table
     _expTable[i] = _expTable[i] / (_expTable[i] + 1); // Precompute f(x) = x / (x + 1)
 }

変更前:Math.Exp((i / ExpTableSize * 2 - 1) * MaxExp);
変更後:Math.Exp(((float)i / ExpTableSize * 2 - 1) * MaxExp);

9
8
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
9
8