2014年02月02日

対象値視点の規模別対象値合計関数


 とりあえず、自分のためメモ。ノートに数式書いても汚くて読めない……。

[番外編]ニコニコデータセットに感謝。真の「規模別合計」問題をねじ伏せれた。

の続き。対象が対数正規分布で近似できる場合を考えた。

正規分布の確率密度関数と相補累積分布関数(対数正規分布ではない)




対象のロングテール分布を対数正規分布 f で近似する。fの相補累積分布関数F_cは



この式とロングテールの順位分布関数(対象が持つ値を降順に並べたときの分布)との関係は、
順位を r 対象値を x とすると



となっている。

導入した順位視点の規模別による対象値合計関数 S は rx である。順位 r が変数のとき、この関数は、規模が r 付近のxの合計値を示す。

一方、xを変数として書くと、



となる。これは対象値が規模 x 付近の順位 r の合計値を表す。これを対象値の合計としたい。

そのために F_c の両対数空間での曲線の傾きで補正する。
X = log x, F_l = log F_c として書き直すと、



これを微分する。



(Φ'_c は -φ。この比は Mills ratio と呼ばれるものの逆数らしい。)

順位合計 S から、対象値合計 S_1 を求めるには -F'_l をかけると良い(証明はしていないが、実データで計算する限り正しい模様)。




以上、非常にすっきりした形で書けていることがわかった。なお、 Φ 特有の性質は使っていないので、確率密度関数と相補累積分布関数の組、 p, P_c があって、 r = P_c(log x) の形で書けているなら、S_1 = x p(log x) の形で書けていると考えられる。

 

ちなみに「-F'_l をかけると良い(証明はしていないが、実データで計算する限り正しい模様)」の部分、手元でやった計算結果はこんな感じ。
magniaccumcomp.png
 完全に一致した。証明はしてないけど一致すると考えて問題ないはず。この結果を得るには、F'_l つまり傾きを計算する必要があるが、安定した結果を得るのは簡単ではない。今回一番良かったのは、とびとびのデータを3次スプライン曲線で補間して計算したもの。DPLN分布ではうまく近似できず、対数正規分布でもざっくりとは近似できたが、ここまでぴったりにはできなかった。3次スプライン曲線の方法も、とびとびの値の取り方や横軸の取り方に工夫が必要だった。

 他にも3次スプライン曲線の方法適応して調子がいいようなら、この統計値も安心して使えるようになるだろう。いろいろ試してみるのが楽しみ。

 実データの集計の方は、データ数が少ないと、集計区間を細かくするとすぐばたばたする。[番外編]ニコニコデータセットに感謝。真の「規模別合計」問題をねじ伏せれた。
では試しに4万件程度で試したが、そこのグラフ以上には細かくできなかった。

 しかし、800万以上データがあると見ての通りばたつかない。昔はせいぜい2000件程度のデータしか持ってなかったので、この辺りは全く手が出なかった。まさにニコニコデータセットのおかげ。



posted by 産業創出ネットワーク at 10:34 | 記事 | このブログの読者になる | 更新情報をチェックする

2014年01月31日

真の「規模別合計」をねじ伏せれた、のこぼれ話


 以前、

 ロングテールを調べるのに便利な「規模別合計」の数学的解説

で、「規模別合計」について解説したけど、今日少し進んだ。ニコ動のニコニコデータセット使ったので、ブロマガの方に書きました。

[番外編]ニコニコデータセットに感謝。真の「規模別合計」問題をねじ伏せれた。

 こぼれ話。最近ニコ動のブロマガの方で始めたロングテールの連載は、割と前からやりたいと思っていたこと。なので、一昨年ニコ動が動画の生データを公開したときも、もちろん、私は飛びついてダウンロードした。が、データ形式が JSON というエクセルでは直接扱えない形式の上、データファイルの数が1925もあって、サイズ合計は12GB。そもそもファイルごとに圧縮されているので、それを全部展開するところから始めないといけない。rubyあたりでいじるか〜、と思いつつもなかなか手が出ないでいた。

 昨年末、ゆく年くる未来で ruby と csv を使ってリンクを生成した余韻が残ったまま、地図関係で久々にエクセル使いまくって、そのまま久々にロングテールに飛び火して、ということで「いましかない」と勢いで12GBの JSON ニコニコデータセットをrubyにかませた。1年以上の懸案がついに動いてめちゃくちゃ快感。

 で、その膨大なデータのおかげで、ついに10年近く気になっていたけど確かめられなかった問題に切り込むことができた。

 こういう話って、ツールやデータが日進月歩なので、急がないならいくらでもペンディングした方が、どんどん楽になる。ある日、あ今ならできるかも!って瞬間が来るまで待つということ。

 もちろん、勝ちたい競争ならそんなこと言ってられないけど、むしろ誰かやってくれないかなでもいい話ならこやってのんびりいっぱい開店休業しておくと、結果として効率いいのではないだろうか。
posted by 産業創出ネットワーク at 20:19 | 記事 | このブログの読者になる | 更新情報をチェックする

2014年01月21日

geofuse の地名一覧はどこに。

 ブロマガの方で、47maps使っていろいろ地図を作って載せてるけど、自分の作ったデータでも geofuse を使えば表示できると言うところまでは分かった。 で、ちょっとやってみたのだけど、 スクリーンショット 2014-01-21 20.30.36.png こんな感じでところどころ歯抜けになる。多分地名が変わったかとか合併したとか町から市になったとかそういうのじゃないかと思うのだけど、geofuse 側でどういう地名で登録されているか不明で合わせようがない。 ソース見ても、ドキュメントないし。インストールしてデータベース覗けば分かるのだろうけど、そこまでしないでもわからないかなあ。 そもそも、どういうオプション?レイヤー?(都道府県とか市町村とか)があるのかすらよく分からない。 もちょっとだけ情報整理してくれれば使えるのにぃぃぃぃぃ。
posted by 産業創出ネットワーク at 21:42 | 記事 | このブログの読者になる | 更新情報をチェックする

2014年01月16日

Ruby でエクセルのCSVを読み込む方法

 年末にゆく年くる未来をやったとき、キーワードを並べるためにエクセルと Ruby を使った。エクセルに各キーワードを入力してCSVで出力してRubyで整形。

 簡単なことのように見えて、漢字コードの問題があって、なかなかうまくいかない。
 それは良く知られたことなので、ネットで調べるといろいろ出てくるのだけど、どれもうまくいかない。結局いろいろ総合して、下記のコードでうまくいった。


require "csv"
require "kconv"
filename = 'yukutoshi.csv'
CSV.parse(File.read(filename).toutf8.gsub(/\r/, "\n")) do |row|
# 処理
end


ポイントは、漢字コードの変換だけではだめで、改行コードも変えないと読み込めないんだけど、ネットの情報だとそこんとこごまかしてるのが多くて、それがうちだとなぜかうまくいかない。

ちゃんと \r から \n に変換してやったらうまくいった。

という自分用メモ。

この作業一年に一回しかやらないかもしれないので、また次回も同じところではまって、同じようにぐぐったら、最初にこれが出てきますように!
posted by 産業創出ネットワーク at 16:34 | 記事 | このブログの読者になる | 更新情報をチェックする

2014年01月14日

ロングテールを調べるのに便利な「規模別合計」の数学的解説


 ブロマガの方で、ロングテールの話題を扱う中で「規模別合計」という集計値を使っていますが、改めて数学的な説明をここで補足しておきます。

ちりを集めて集計してみる


 例としてべき乗則を考えます。

 

ここで、xは順位、f(x) は対象となる統計値です。たとえば、ニコニコ動画の再生数などです。kを100万とすると、
 1位は100万回再生、
 2位は50万回再生、
 3位は33万回再生、
 ...
 10位は10万回再生、
 ...
 100位は1万回再生、
 ...
 1万位は100回再生
となっているような分布です。

 このとき、10位ごとに区切って再生数を合計すると、
 1-10位の合計  300万回弱
 11-20位の合計 約67万回
 21-30位の合計  40万回弱
 ...
 101-110位の合計 10万回弱
と、当然上位10位の合計は他を圧倒します。

 しかし、もし、1位の再生数と、2位からは集計する幅をどんどん広くしたものを比べると肩を並べます。

 1位の再生数           100万回
 2-10位の再生数の合計     約190万回
 11-100位の再生数の合計    約230万回
 101-1000位の再生数の合計   約230万回
 10001-10000位の再生数の合計 約230万回

と肩を並べますし、さらに約230万回で一定になります。

「規模別合計」


 この様子は、近似的に連続関数上で集計してやるとわかります。通常の等幅の集計は、ある幅 Δx について、[ x, x + Δx ] という区間で行いますが、どんどん幅を広くするというのを一般的に書くと、ある比 Δx について、[ x, x (1 + Δx) ]という区間で集計することにします。すると、上記べき乗則では、




 
と定数になっており、実際の合計値も一定数に近づきます。

 この操作を「規模別合計」と呼んでいます。なぜかというと、今行った集計の区切りの順位での再生数を見ると、
 1位の再生数  100万回
 10位の再生数  10万回
 100位の再生数   1万回
 1000位の再生数 1000回
 10000位の再生数 100回
となっていて、つまり、たとえば 2 - 10位の合計というのは、再生数が10万回以上100万回未満、つまり、再生数が6ケタのものを合計しているからです。
 同様に11 - 100位の合計とは再生数が5ケタのものの合計になっていますし、再生数が3ケタしかなくても、それは、1001位から10000位と約9000個もあり、それらを合計すると1位の再生数を超えるのです。まさにちりも積もれば山となる、です。

 つまり、上記のように幅をどんどん広くしながら合計するという操作をべき乗則のようなロングテールの分布に行うと、再生数が何ケタかというような規模ごとに集計していることになるので、「規模別合計」と呼んでいるのです。

 この、小さいものが無数にあって、合算すると大きいものと同じくらいの大きさであることが、ある分布がロングテールであるかどうかの重要なポイントであり、それは「規模別合計」をチェックすることでできるのです。
 例えば市区町村の人口を調べると人口の多い上位の方はべき乗則のように振る舞いますが、たとえば1000人以下の自治体に住む人口の合計は全人口の0.01%、1000人から1万人の自治体に住む人は全人口の2%しかいなくて、尻切れとんぼなロングテールとはいえない分布をしています。

(註:詳しくは
ロングテールの、ほとんど知られていない、しかしもっとも重要な性質(その2)〜ロングじゃないテールの例〜
にあります)

「規模別合計」は簡単に計算できる


 さらにこの「規模別合計」の大変便利なところは、f(x)という分布に対して、 x f(x) という簡単な計算でその姿が分かることです。上記の例はわざわざエクセルで集計していますが、それなりの手間です。一方べき乗則 1/x について、 x f(x) は 1 と定数になることは一瞬で分かります。
 また実際に集計しようとするとデータがたくさんないとまともな集計になりません。しかし、 x f(x) で計算した場合はデータの点が10個程でも充分その姿を捉えることができます。

 なぜ x f(x) で「規模別合計」が分かるのか、以下に簡潔に示しておきます。ある等比係数Δxに対し「規模別合計」を次のように定義します。


 
 これをxについて微分してみます。





 ここで、Δxを0に近づけると



となり、これはと同じです。従って両者は定数分を除いて等しくなります。

 以上ロングテールの様子を調べるのに便利な「規模別合計」について数学的な解説でした。きっと同じ議論はよそでもされているとは思うのですが、「規模別合計」に対応する学術用語が分からず、いまだに見つけられていません。「それはなんとかのことだよ」とか分かる人いましたら是非教えてください。
posted by 産業創出ネットワーク at 12:00 | 記事 | このブログの読者になる | 更新情報をチェックする