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?

メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろう
Kota Mizushima
 

Was ist angesagt? (20)

マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!
 
データサイエンティストのつくり方
データサイエンティストのつくり方データサイエンティストのつくり方
データサイエンティストのつくり方
 
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
 
因果推論の基礎
因果推論の基礎因果推論の基礎
因果推論の基礎
 
『逆転オセロニア』における バンディットアルゴリズムおよび強化学習を用いた 対戦環境のバランス設計支援
『逆転オセロニア』における バンディットアルゴリズムおよび強化学習を用いた 対戦環境のバランス設計支援『逆転オセロニア』における バンディットアルゴリズムおよび強化学習を用いた 対戦環境のバランス設計支援
『逆転オセロニア』における バンディットアルゴリズムおよび強化学習を用いた 対戦環境のバランス設計支援
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろう
 
数学カフェ 確率・統計・機械学習回 「速習 確率・統計」
数学カフェ 確率・統計・機械学習回 「速習 確率・統計」数学カフェ 確率・統計・機械学習回 「速習 確率・統計」
数学カフェ 確率・統計・機械学習回 「速習 確率・統計」
 
【メタサーベイ】Transformerから基盤モデルまでの流れ / From Transformer to Foundation Models
【メタサーベイ】Transformerから基盤モデルまでの流れ / From Transformer to Foundation Models【メタサーベイ】Transformerから基盤モデルまでの流れ / From Transformer to Foundation Models
【メタサーベイ】Transformerから基盤モデルまでの流れ / From Transformer to Foundation Models
 
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
 
[DL輪読会]Attention Is All You Need
[DL輪読会]Attention Is All You Need[DL輪読会]Attention Is All You Need
[DL輪読会]Attention Is All You Need
 
ナレッジグラフ入門
ナレッジグラフ入門ナレッジグラフ入門
ナレッジグラフ入門
 
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計
 
Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編
 
Prometheus at Preferred Networks
Prometheus at Preferred NetworksPrometheus at Preferred Networks
Prometheus at Preferred Networks
 
Ormとの付き合い方
Ormとの付き合い方Ormとの付き合い方
Ormとの付き合い方
 
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
 
エンジニアも知っておきたいAI倫理のはなし
エンジニアも知っておきたいAI倫理のはなしエンジニアも知っておきたいAI倫理のはなし
エンジニアも知っておきたいAI倫理のはなし
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
 
TLS 1.3 と 0-RTT のこわ〜い話
TLS 1.3 と 0-RTT のこわ〜い話TLS 1.3 と 0-RTT のこわ〜い話
TLS 1.3 と 0-RTT のこわ〜い話
 
DLLab 異常検知ナイト 資料 20180214
DLLab 異常検知ナイト 資料 20180214DLLab 異常検知ナイト 資料 20180214
DLLab 異常検知ナイト 資料 20180214
 

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