プログラマーになりたい。

プログラミングや写真や本や読書会のことや、日常のこと。

SQLの日になってしまった

無線LANDHCPがとれない。有線でやった。

重複が取り除けない

DELETE FROM papers p1 WHERE id > (
SELECT MIN(id) FROM papers p2
WHERE p1.pmid == p2.pmid AND p1.cited_pmid == p2.cited_pmid
);
これが実行できない。DELETEでは何かのSELECTで使える文法が使えないらしい。


sqlite> .output noduplicate.sql
sqlite> .mode insert papers
sqlite> SELECT * FROM papers p1 WHERE id == ( SELECT MIN(id) FROM papers p2 WHERE p1.pmid == p2.pmid AND p1.cited_pmid == p2.cited_pmid) ORDERD BY pmid, cited_pmid;
無理。終わらなかった。db作り直す方がまし。


とりあえず、
sqlite> ALTER TABLE papers ADD COLUMN score REAL;
とかした。

RSQLiteをやってみた

> install.packages("RSQLite")
> library(RSQLite)

> drv <- dbDriver("SQLite")
> con <- dbConnect(drv, dbname="medline.db")
> m<-dbGetQuery(con,'select pmid,cited_pmid from papers where id<100')

> rownames(m)<-paste(m[,1],m[,2])
とすれば、とりあえずハッシュのように使える?
きたねえけど。


m<-dbGetQuery(con,'select pmid,cited_pmid from papers group by pmid,cited_pmid')
ちょっと心配したけど、1分はかからなかった。


> rownames(m)<-paste(m[,1],m[,2])
これが無理かもしれない…。いや、1分は、かからなかった!
(だんだん、計算待ちの感覚が鈍ってきてる…。)


> length(rownames(m))
[1] 8685382

へー。エッジ、ぜんぶで8685382個あるらしいぜ…。


で、どーーーーすっかなー
隣接行列のハッシュ表現?
やっぱ、行列使えないんじゃRのうまみがなあ…。

次数n?

とりあえずpagerankのアレに必要なパラメータとして、n。いつものアレ*1に「degrees of P」って書いてあったけど、ノード数という解釈でいいのよね。(グラフの次数では、ちょっと違和感がある。)


でもまあ、出次数とか、どんなもんか、興味はあるよねということで:
sqlite> SELECT id,pmid,count(*) FROM (SELECT * FROM papers GROUP BY pmid,cited_pmid) GROUP BY pmid HAVING count(*)>100 order by count(*) desc limit 10;


8561703|19133145|2227
7332682|19265398|1477
2179197|17237348|1388
3797461|17949854|1138
2056602|67839|1032
6079499|18616971|960
4052533|17706608|881
4090239|18081553|796
7249377|19269307|745
7070178|19173715|711

うわ、2227!?まじで。
http://www.ncbi.nlm.nih.gov/pubmed/19133145 *2
まじだ…。なんだこれは…。後で中身みないと…。
というか、この引用数の分布と、その時系列変化もみておかないと。

ノード数を知りたい

sqlite> SELECT count(id) FROM papers WHERE id IN(SELECT id FROM papers GROUP BY pmid,cited_pmid);
8685382

あ、ちがうこれエッジ数になっちゃう。
こう?
sqlite> SELECT count(id) FROM papers WHERE id IN(SELECT id FROM papers GROUP BY pmid);
396732
sqlite> SELECT count(id) FROM papers WHERE id IN(SELECT id FROM papers GROUP BY cited_pmid);
3078391


あーでも、HITSであれば上の数字でノード数としてもいいけど、pagerank的な正方行列だと規格化するときにつかえないよなあ…。


sqlite> SELECT count(id) FROM papers WHERE id IN(SELECT id FROM papers GROUP BY cited_pmid) AND id IN(SELECT id FROM papers GROUP BY pmid);
142472
あーれー…うーん…?ちがう。なんだこれ。
あ、和集合だ。…UNIONっていうのか。ぼーう。
sqlite> SELECT count(pmid) FROM (SELECT DISTINCT cited_pmid as pmid FROM papers UNION SELECT DISTINCT pmid as pmid FROM papers);
3276389
これか!328万ノード!


ちなみに、もし隣接行列にしたら、非ゼロ要素は
8685382 / (3276389^2)= 8.09092184 × 10-7 = 0.0000809092184%
でしかないと。スパース…。もちろん、零ベクトルが多いのか、薄く広いのかとかは、これだけじゃわからんけど。
そして、まじめにdouble(たしか8byteだよね)2次元配列にしたら
(3276389^2) * 8 byte = 78.1054032 テラバイト
これは……どうあっても、ありえないですね…。


でも、引用先としても引用元としても登録されているものだけ、という手もなくはないかもしれない。
396732 + 3078391 - 3276389 = 198734
それでも19万件。もちろん、グラフとしてみてスカスカだったり、年代別の内訳が偏るとかする可能性もあるから、あくまでもひとつの案として(せっかくなので減らしたくない貧乏性)。

*1:Google PageRankの数理 ―最強検索エンジンのランキング手法を求めて―の人のやつ

*2:リンクきれてた。サンクス、id:wakuteka!どうもリングの貼り方が間違ってたようだ cf. http://hmonai.blog33.fc2.com/blog-entry-45.html

Creative Commons License ©2007-2021 IIDA Munenori.