SlideShare ist ein Scribd-Unternehmen logo
1 von 10
Downloaden Sie, um offline zu lesen
Zipf 分布に従う乱数の生成方法

       まるやま



      2013/04/18




                    1 / 10
Zipf 分布に従う乱数を発生させたい



  そういう時もあるでしょ(あるんです)
  Zipf 分布とは → ja.wikipedia
  一番簡単な Zipf 分布を考える
                             1/k
                 f (k; N) = ∑N
                             i=1 1/i




                                       2 / 10
調和級数の部分和
                             Zipf 分布の分母は、調和級数の部分和(要するに、調和数)
                             調和級数とは → ja.wikipedia
                             だから、対数とオイラーの定数で近似できる
                             オイラーの定数とは → ja.wikipedia
                             ∑N 1
                               i=1 i ≒ log(N) + γ
                                         オイラーの定数:γ = 0.5772156649 · · ·


                             Partial Sums of Harmonic Series (Harmonic Number) and its approximate value
                   10

                   9.5

                    9

                   8.5

                    8

                   7.5




                                                                                                                              グラフでは見分けがつか
                    7

                   6.5
 Harmonic Number




                    6



                                                                                                                              ない程、近い
                   5.5                                                                          Harmonic Number
                    5                                                                           approximate value
                   4.5

                    4

                   3.5

                    3

                   2.5

                    2

                   1.5

                    1

                   0.5

                         0      1000    2000    3000    4000         5000         6000   7000        8000      9000   10000

                                                               x-th partial sum



                                                                                                                                            3 / 10
Zipf 分布の式を簡単に

                         Zipf 分布の式が結構簡単になる
                                                                       1
                                  f (k; N) =                     k(log(N)+γ)

                         グラフを描くのも楽チン


                                              Zipf Distribution (N=10000)                                                                           Zipf Distribution (N=10000, Enlargement)
                1                                                                                                         0.4


               0.9
                                                                                                                         0.35

               0.8

                                                                                                                          0.3
               0.7

                                                                                                                         0.25
               0.6
 PDF and CDF




                                                                                                           PDF and CDF
                                                                                          PDF                                                                                                                PDF
               0.5                                                                                                        0.2
                                                                                          CDF                                                                                                                CDF

               0.4
                                                                                                                         0.15

               0.3
                                                                                                                          0.1

               0.2

                                                                                                                         0.05
               0.1


                0                                                                                                          0

                     0   1000   2000   3000      4000     5000    6000      7000   8000     9000   10000                        1   2   3   4   5   6   7   8    9   10       11   12   13   14   15   16   17   18   19   20

                                                           k                                                                                                              k




                                                                                                                                                                                                                                4 / 10
一様乱数から Zipf 乱数へ



   確率分布な乱数を作る時は、累積分布関数(CDF)を使う
     前のスライドに載せていた確率密度関数(PDF)ではなくて
   ジップ分布の累積密度関数だって、実は簡単
                log(k)+γ
     F (k; N) = log(N)+γ
     何も言わずに前のスライドにはグラフを載せていたけど
   累積密度関数の逆関数で、確率分布な乱数を作れる
     G (x; N) = exp((log(N) + γ)x − γ)




                                         5 / 10
Lua で作ってみる

 zipfr.lua
 euGm = 0.5772156649
 max = 1000
 count = 1000000
 harm = math.log(max)+euGm
 math.randomseed(os.time())
 hist = {}
 for i = 1, max, 1 do hist[i] = 0 end
 for i = 1, count, 1 do
   x = math.ceil(math.exp((math.random()*harm)-euGm))
   hist[x] = hist[x]+1
 end
 for i = 1, max, 1 do print(i, hist[i]/count, 1/i/harm) end




                                                              6 / 10
作ってみたら…

                                                    Zipf Distribution (N=1000)
                 0.15

                 0.14

                 0.13

                 0.12

                 0.11

                  0.1

                 0.09
   probability




                 0.08
                                                                                                      count
                 0.07                                                                                logical

                 0.06

                 0.05

                 0.04

                 0.03

                 0.02

                 0.01

                   0

                        1   2   3   4   5   6   7    8   9    10       11   12   13   14   15   16   17    18   19   20

                                                                   k




 あれ?なんか違う?
                                                                                                                          7 / 10
定義域と値域


  一様乱数の入力 x = [0, 1) に対して、
  出力 y = G (x; N) は y = [0, N) であって欲しい
  しかし、G (0; N) = e −γ 、G (1; N) = N
      だから1番目の値が小さかった!
  値域の始まりを合わせるため、
  G (x; N) = exp((log(N) + γ)x − γ) − e −γ とする
      すると今度は値域の終わりが G (1; N) = N − e −γ とズレる
  さらに値域の終わりを合わせるため、
  G (x; N) = exp((log(N + e −γ ) + γ)x − γ) − e −γ とする
      これで G (0; N) = 0、G (1; N) = N になった!




                                                         8 / 10
Lua で再実装

 zipfrand.lua
 euGm = 0.5772156649
 max = 1000
 count = 1000000
 base = math.exp(-euGm)
 harm = math.log(max)+euGm
 cond = math.log(max+base)+euGm
 math.randomseed(os.time())
 hist = {}
 for i = 1, max, 1 do hist[i] = 0 end
 for i = 1, count, 1 do
   x = math.ceil(math.exp((math.random()*cond)-euGm)-base)
   if (x == 0) then x = 1 end
   hist[x] = hist[x]+1
 end
 for i = 1, max, 1 do print(i, hist[i]/count, 1/i/harm) end

                                                              9 / 10
結果…

                                                    Zipf Distribution (N=1000)
                 0.15

                 0.14

                 0.13

                 0.12

                 0.11

                  0.1

                 0.09
   probability




                 0.08
                                                                                                      count
                 0.07                                                                                logical

                 0.06

                 0.05

                 0.04

                 0.03

                 0.02

                 0.01

                   0

                        1   2   3   4   5   6   7    8   9    10       11   12   13   14   15   16   17    18   19   20

                                                                   k




 できた!
    !
                                                                                                                          10 / 10

Weitere ähnliche Inhalte

Was ist angesagt?

elasticsearch-hadoopをつかってごにょごにょしてみる
elasticsearch-hadoopをつかってごにょごにょしてみるelasticsearch-hadoopをつかってごにょごにょしてみる
elasticsearch-hadoopをつかってごにょごにょしてみる
Katsushi Yamashita
 

Was ist angesagt? (20)

MongoDBが遅いときの切り分け方法
MongoDBが遅いときの切り分け方法MongoDBが遅いときの切り分け方法
MongoDBが遅いときの切り分け方法
 
平面グラフと交通ネットワークのアルゴリズム
平面グラフと交通ネットワークのアルゴリズム平面グラフと交通ネットワークのアルゴリズム
平面グラフと交通ネットワークのアルゴリズム
 
トランザクションをSerializableにする4つの方法
トランザクションをSerializableにする4つの方法トランザクションをSerializableにする4つの方法
トランザクションをSerializableにする4つの方法
 
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
 
がっつりMongoDB事例紹介
がっつりMongoDB事例紹介がっつりMongoDB事例紹介
がっつりMongoDB事例紹介
 
Rolling hash
Rolling hashRolling hash
Rolling hash
 
Consistent hash
Consistent hashConsistent hash
Consistent hash
 
elasticsearch-hadoopをつかってごにょごにょしてみる
elasticsearch-hadoopをつかってごにょごにょしてみるelasticsearch-hadoopをつかってごにょごにょしてみる
elasticsearch-hadoopをつかってごにょごにょしてみる
 
DockerコンテナでGitを使う
DockerコンテナでGitを使うDockerコンテナでGitを使う
DockerコンテナでGitを使う
 
AWS Black Belt Techシリーズ Amazon EMR
AWS Black Belt Techシリーズ  Amazon EMRAWS Black Belt Techシリーズ  Amazon EMR
AWS Black Belt Techシリーズ Amazon EMR
 
2014 3 13(テンソル分解の基礎)
2014 3 13(テンソル分解の基礎)2014 3 13(テンソル分解の基礎)
2014 3 13(テンソル分解の基礎)
 
Rustに触れて私のPythonはどう変わったか
Rustに触れて私のPythonはどう変わったかRustに触れて私のPythonはどう変わったか
Rustに触れて私のPythonはどう変わったか
 
AWS BlackBelt AWS上でのDDoS対策
AWS BlackBelt AWS上でのDDoS対策AWS BlackBelt AWS上でのDDoS対策
AWS BlackBelt AWS上でのDDoS対策
 
推薦アルゴリズムの今までとこれから
推薦アルゴリズムの今までとこれから推薦アルゴリズムの今までとこれから
推薦アルゴリズムの今までとこれから
 
全自動Zabbix
全自動Zabbix全自動Zabbix
全自動Zabbix
 
Rolling Hashを殺す話
Rolling Hashを殺す話Rolling Hashを殺す話
Rolling Hashを殺す話
 
RedisのBitCountとHyperLogLogを使用した超高速Unique User数集計
RedisのBitCountとHyperLogLogを使用した超高速Unique User数集計RedisのBitCountとHyperLogLogを使用した超高速Unique User数集計
RedisのBitCountとHyperLogLogを使用した超高速Unique User数集計
 
PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門
 
MariaDBとMroongaで作る全言語対応超高速全文検索システム
MariaDBとMroongaで作る全言語対応超高速全文検索システムMariaDBとMroongaで作る全言語対応超高速全文検索システム
MariaDBとMroongaで作る全言語対応超高速全文検索システム
 
協調フィルタリング入門
協調フィルタリング入門協調フィルタリング入門
協調フィルタリング入門
 

Mehr von Maruyama Tetsutaro

Mehr von Maruyama Tetsutaro (15)

Online Matching and Ad Allocaton 8章&9章半分
Online Matching and Ad Allocaton 8章&9章半分Online Matching and Ad Allocaton 8章&9章半分
Online Matching and Ad Allocaton 8章&9章半分
 
shot note で手書き資料作成
shot note で手書き資料作成shot note で手書き資料作成
shot note で手書き資料作成
 
ユークリッド距離以外の距離で教師無しクラスタリング
ユークリッド距離以外の距離で教師無しクラスタリングユークリッド距離以外の距離で教師無しクラスタリング
ユークリッド距離以外の距離で教師無しクラスタリング
 
機械学習向けプログラミング言語の使い分け - RCO の場合
機械学習向けプログラミング言語の使い分け - RCO の場合機械学習向けプログラミング言語の使い分け - RCO の場合
機械学習向けプログラミング言語の使い分け - RCO の場合
 
keynoteでslideshare
keynoteでslidesharekeynoteでslideshare
keynoteでslideshare
 
Lambda and rundeck
Lambda and rundeckLambda and rundeck
Lambda and rundeck
 
Mining of massive datasets chapter3
Mining of massive datasets chapter3Mining of massive datasets chapter3
Mining of massive datasets chapter3
 
業務に活かすデータサイエンスとは?
業務に活かすデータサイエンスとは?業務に活かすデータサイエンスとは?
業務に活かすデータサイエンスとは?
 
日本の伝統色
日本の伝統色日本の伝統色
日本の伝統色
 
Gnuplotあれこれ
GnuplotあれこれGnuplotあれこれ
Gnuplotあれこれ
 
Ubuntuで最新パッケージを導入
Ubuntuで最新パッケージを導入Ubuntuで最新パッケージを導入
Ubuntuで最新パッケージを導入
 
Zshでデキるプロンプト
ZshでデキるプロンプトZshでデキるプロンプト
Zshでデキるプロンプト
 
配列数式
配列数式配列数式
配列数式
 
ランダム・シャッフル
ランダム・シャッフルランダム・シャッフル
ランダム・シャッフル
 
円錐曲線の極座標表示
円錐曲線の極座標表示円錐曲線の極座標表示
円錐曲線の極座標表示
 

Zipf分布に従う乱数の生成方法

  • 1. Zipf 分布に従う乱数の生成方法 まるやま 2013/04/18 1 / 10
  • 2. Zipf 分布に従う乱数を発生させたい そういう時もあるでしょ(あるんです) Zipf 分布とは → ja.wikipedia 一番簡単な Zipf 分布を考える 1/k f (k; N) = ∑N i=1 1/i 2 / 10
  • 3. 調和級数の部分和 Zipf 分布の分母は、調和級数の部分和(要するに、調和数) 調和級数とは → ja.wikipedia だから、対数とオイラーの定数で近似できる オイラーの定数とは → ja.wikipedia ∑N 1 i=1 i ≒ log(N) + γ オイラーの定数:γ = 0.5772156649 · · · Partial Sums of Harmonic Series (Harmonic Number) and its approximate value 10 9.5 9 8.5 8 7.5 グラフでは見分けがつか 7 6.5 Harmonic Number 6 ない程、近い 5.5 Harmonic Number 5 approximate value 4.5 4 3.5 3 2.5 2 1.5 1 0.5 0 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000 x-th partial sum 3 / 10
  • 4. Zipf 分布の式を簡単に Zipf 分布の式が結構簡単になる 1 f (k; N) = k(log(N)+γ) グラフを描くのも楽チン Zipf Distribution (N=10000) Zipf Distribution (N=10000, Enlargement) 1 0.4 0.9 0.35 0.8 0.3 0.7 0.25 0.6 PDF and CDF PDF and CDF PDF PDF 0.5 0.2 CDF CDF 0.4 0.15 0.3 0.1 0.2 0.05 0.1 0 0 0 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 k k 4 / 10
  • 5. 一様乱数から Zipf 乱数へ 確率分布な乱数を作る時は、累積分布関数(CDF)を使う 前のスライドに載せていた確率密度関数(PDF)ではなくて ジップ分布の累積密度関数だって、実は簡単 log(k)+γ F (k; N) = log(N)+γ 何も言わずに前のスライドにはグラフを載せていたけど 累積密度関数の逆関数で、確率分布な乱数を作れる G (x; N) = exp((log(N) + γ)x − γ) 5 / 10
  • 6. Lua で作ってみる zipfr.lua euGm = 0.5772156649 max = 1000 count = 1000000 harm = math.log(max)+euGm math.randomseed(os.time()) hist = {} for i = 1, max, 1 do hist[i] = 0 end for i = 1, count, 1 do x = math.ceil(math.exp((math.random()*harm)-euGm)) hist[x] = hist[x]+1 end for i = 1, max, 1 do print(i, hist[i]/count, 1/i/harm) end 6 / 10
  • 7. 作ってみたら… Zipf Distribution (N=1000) 0.15 0.14 0.13 0.12 0.11 0.1 0.09 probability 0.08 count 0.07 logical 0.06 0.05 0.04 0.03 0.02 0.01 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 k あれ?なんか違う? 7 / 10
  • 8. 定義域と値域 一様乱数の入力 x = [0, 1) に対して、 出力 y = G (x; N) は y = [0, N) であって欲しい しかし、G (0; N) = e −γ 、G (1; N) = N だから1番目の値が小さかった! 値域の始まりを合わせるため、 G (x; N) = exp((log(N) + γ)x − γ) − e −γ とする すると今度は値域の終わりが G (1; N) = N − e −γ とズレる さらに値域の終わりを合わせるため、 G (x; N) = exp((log(N + e −γ ) + γ)x − γ) − e −γ とする これで G (0; N) = 0、G (1; N) = N になった! 8 / 10
  • 9. Lua で再実装 zipfrand.lua euGm = 0.5772156649 max = 1000 count = 1000000 base = math.exp(-euGm) harm = math.log(max)+euGm cond = math.log(max+base)+euGm math.randomseed(os.time()) hist = {} for i = 1, max, 1 do hist[i] = 0 end for i = 1, count, 1 do x = math.ceil(math.exp((math.random()*cond)-euGm)-base) if (x == 0) then x = 1 end hist[x] = hist[x]+1 end for i = 1, max, 1 do print(i, hist[i]/count, 1/i/harm) end 9 / 10
  • 10. 結果… Zipf Distribution (N=1000) 0.15 0.14 0.13 0.12 0.11 0.1 0.09 probability 0.08 count 0.07 logical 0.06 0.05 0.04 0.03 0.02 0.01 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 k できた! ! 10 / 10