あのSQLとの格闘はなんだったのか…。
ともかくRubyのHashとArrayでいけた。MEDLINE全件はちょっときつそうだけど。
nil
ランキングスコアがnil値になる問題があった。
g86:~ flashingwind$ grep -n nil medline1000rank.csv 54:19653919 nil 85:19680543 nil 146:19372376 nil 221:19451134 nil 392:19698190 nil 632:19221393 nil 881:19300490 nil g86:~ flashingwind$ grep 19653919 medline1000.csv 19653919,18761138,18439631,12764080,11522573,18387568,18088583,17851092,17208179,17224400,16953876,16594732,16603917,16402259,15716474,14585444,15157755,15147931,14622587 g86:~ flashingwind$ grep 19680543 medline1000.csv 19680543,15846361,15769737,15707503,15684387,15649380,15576043,15547249,9613202,8812426,7664742,1967820,2814477,8108407,6370993,15466086,15139850,14742425,12808457,12826641,12670948,12529507,11972329,11904358,11226216,11163147,15784737,19300474,19192037,18620006,19021753,18729827,18678873,18613946,18614015,18312863,18391175,18194548,17724061,17575325,17651921,17570365,17182725,17237235,17189185,17099226,17098935,17005538,16838076,16950771,16762838,16582907,16530192,16564017,16435202,16284200,16199517,16212937,16124867,16026597
どうも、出リンクしかないノード(第1カラムにしか出現しない)がうまく処理できない?
→make_matrixの段階で対応。
メモリ
オンメモリハッシュでとりあえず10万件まではいけた。ボトルネックはメモリに展開する部分。とくにファイル読み込みより、メモリ書き込みに時間がかかっているのではないかという印象。
10万件のときの時間ではメモリ使用量428MBであった。
- 仮にn^2に比例すると仮定すると
- 428MB/(100000^2) = 0.0448790528 byte
- nに比例すると仮定すると
- 428MB/(100000) = 4.38272 kbyte
で、これから、すげえおおざっぱな計算をすると、
1980年からのデータ(823,313件)で
823313^2 * (0.0448790528byte) = 28.3317733 GB
823313 * 4.38272 KB = 3.44119105 GB
のあいだくらいかなーと…。
あ、前者だけtokyocabinetいれちゃったかもしれない。
…正解: 2.63GB。
意外とメモリ効率がいいのかな。
sqlite> SELECT count(rowid) FROM papers where pmid in(select pmid from pmids);
4470100
sqlite> SELECT count(rowid) FROM pmids;
198734
bash-3.2$ wc -l medline_from1980-intersected.csv
4470100 medline_from1980-intersected.csv
nil問題、つづき
下記の両方のアプローチが考えられる
- 引用側と被引用側、両方に出てくる論文だけをあつかう
- 被引用側にだけ出現する論文は何も引用していない、として処理する
後者は見かけ上データがふえることがある。実際に、最新100件のデータについて、被引用文献をぶらさがりノードとして追加したところ、合計4061件になった。
これより、無事
> s<-t(cbind(
c(12640146, 0.00024572884064249),
c(15379887, 0.000246961532145432),
…
c(12325024, 0.000245832708484026),
c(12458211, 0.000245305924108703)
))
> sum(s[,2])
[1] 1
であるスコアが得られた。
cf.
textファイルを行列として読み込む
> x <- matrix(scan("data.txt"),ncol=8,byrow=T)
data.txtを列数8の行列x として読み込む
ところが、これを最新1000件にするとかだとまたnilが…。
とりあえず、なんともスパゲッティな感じになるので、pmidが整数であるから、連番のidを割り振る方式から、rankなどをarrayではなくhashに変更し、キーとして直接pmidを使う方式に書き換えた。
タイムアップ。この状態に関しては、動作の安定性は不明。