Monthly Archives: 6月 2014

ドキュメントとソースコードの対応2(word2vecの利用)

先週に引き続きドキュメントとソースコードの対応付けについて実験してみた。

手順は下記の通り。前回からの改良(?)としてword2vecで日本語→英語の変換を行ってみた。

  1. 英語と日本語のマニュアルからword2vecで使用できる形式で単語を抜き出す。
    • 形態素解析のライブラリにはMecabを利用。
    • 2.のword2vecの処理で使うためのデータ。
  2. PostgreSQLのソース内にあるhtml、c、hファイルを対象にファイル内に存在する単語を抜き出す。
    1. 単語が日本語であった場合はword2vec的に類似度の高い単語TOP10から距離に応じて英単語をランダムに選ぶ。
      • ライブラリにはgensim(http://radimrehurek.com/gensim/index.html)を利用。
  3. 2.で抜き出したデータに対し、TF-IDF用の辞書(単語と出現頻度)を作る。
  4. 2.で抜き出したデータと3.を使って、それぞれのファイルに含まれる単語に対してTF-IDFで重み付けを行う。
  5. データ内(PostgreSQLのソース内)にあるhtmlファイルに対してコサイン距離の近いc、hファイルを一覧化する。

結果は↓の通り。前回に比べてコサイン類似度の値自体は上がっているものの適切なソースファイルを引けているかというとやや疑問。とはいえ何もやらないよりはマシかも(?)

詳細な結果とソースは以下のURLをご参照。

--../data/postgresql-9.3.4/doc/src/sgml/html/app-createuser.html--
[   (   '../data/postgresql-9.3.4/src/bin/scripts/createuser.c',
        0.5312760078128166),
    (   '../data/postgresql-9.3.4/src/backend/commands/user.c',
        0.49654701095797743),
    (   '../data/postgresql-9.3.4/src/bin/pg_dump/pg_dumpall.c',
        0.4521924409520057),
    (   '../data/postgresql-9.3.4/src/include/commands/user.h',
        0.4458741678013434),
    (   '../data/postgresql-9.3.4/src/include/catalog/pg_authid.h',
        0.4366612559172716)]

--../data/postgresql-9.3.4/html-ja/app-createuser.html--
[   (   '../data/postgresql-9.3.4/src/bin/scripts/createuser.c',
        0.27458665377082037),
    (   '../data/postgresql-9.3.4/src/bin/psql/tab-complete.c',
        0.2411847340696424),
    (   '../data/postgresql-9.3.4/src/backend/commands/user.c',
        0.20269999574142247),
    ('../data/postgresql-9.3.4/src/include/utils/acl.h', 0.16197452745649446),
    (   '../data/postgresql-9.3.4/src/bin/pg_dump/pg_backup.h',
        0.16130232695577076)]
--../data/postgresql-9.3.4/doc/src/sgml/html/indexes-intro.html--
[   (   '../data/postgresql-9.3.4/src/backend/commands/indexcmds.c',
        0.5887593627491802),
    ('../data/postgresql-9.3.4/src/include/utils/rel.h', 0.5847988052787634),
    (   '../data/postgresql-9.3.4/src/backend/optimizer/path/indxpath.c',
        0.5736868945937168),
    (   '../data/postgresql-9.3.4/src/backend/catalog/index.c',
        0.5695396670614502),
    (   '../data/postgresql-9.3.4/src/backend/optimizer/util/plancat.c',
        0.5669650556082131)]

--../data/postgresql-9.3.4/html-ja/indexes-intro.html--
[   (   '../data/postgresql-9.3.4/src/backend/access/rmgrdesc/spgdesc.c',
        0.6065874266691939),
    (   '../data/postgresql-9.3.4/src/backend/access/transam/rmgr.c',
        0.6055142588080052),
    (   '../data/postgresql-9.3.4/contrib/pg_xlogdump/rmgrdesc.c',
        0.6055142588080052),
    (   '../data/postgresql-9.3.4/src/backend/access/spgist/spgquadtreeproc.c',
        0.6054292723362433),
    (   '../data/postgresql-9.3.4/src/include/access/rmgrlist.h',
        0.6054292723362433)]

ドキュメントとソースコードの対応

ソフトウェア開発においてドキュメントとソースコードの対応を取り続けることは想像以上に難しい。開発当初は綺麗に対応していたドキュメントとソースが年を追うごとに乖離していき、それぞれ別物として成長していくことはよくある光景である。そのような中、ドキュメントに対応するソースが何であるか一覧化できるそりゅ~しょんが強く求められている・・・ような気がする。

ざっくり言うとドキュメントとソースコードの紐付けが自動でできるかどうか気になったのでやってみた。(ここにはひさしぶりの投稿)

条件は下記の通り。

  • Postgresql9.3.4のマニュアルに対応するソースを表示する。
  • マニュアル、ソースそれぞれについて出てくる単語を抽出し、TF-IDFで重み付けを行い、コサイン類似度の大きなものを関連しているとみなす。

結果、英語版のマニュアルとソースの対応はそこそこの精度で取れるが、日本語版のマニュアルに対する対応はイマイチだった。ソース中に日本語が入っているとは思えない(=キーとなる情報が少ない)ので納得のいく結果ではある。

下記はcreateuserとindex-introの例。[]内には–・・・.html(マニュアル)–に対して類似度が大きなソース上位5つが入っている。()内の”の中がソースコードの名称でその後の数字がコサイン類似度。なお、htmlディレクトリ以下にあるのが英語版で、html-ja以下にあるのが日本語版となっている。

--../data/postgresql-9.3.4/doc/src/sgml/html/app-createuser.html--
[   (   '../data/postgresql-9.3.4/src/bin/scripts/createuser.c',
        0.5315036131957114),
    (   '../data/postgresql-9.3.4/src/backend/commands/user.c',
        0.49634873213501424),
    (   '../data/postgresql-9.3.4/src/bin/pg_dump/pg_dumpall.c',
        0.45199746892518794),
    (   '../data/postgresql-9.3.4/src/include/commands/user.h',
        0.4456889634461926),
    (   '../data/postgresql-9.3.4/src/include/catalog/pg_authid.h',
        0.436479878362433)]

--../data/postgresql-9.3.4/html-ja/app-createuser.html--
[   (   '../data/postgresql-9.3.4/src/bin/scripts/createuser.c',
        0.24660267524744783),
    (   '../data/postgresql-9.3.4/src/bin/psql/tab-complete.c',
        0.21638658446826328),
    (   '../data/postgresql-9.3.4/src/backend/commands/user.c',
        0.18185439320172517),
    (   '../data/postgresql-9.3.4/src/backend/catalog/objectaddress.c',
        0.17654887868713476),
    (   '../data/postgresql-9.3.4/src/backend/parser/gram.c',
        0.15892817112702087)]
--../data/postgresql-9.3.4/doc/src/sgml/html/indexes-intro.html--
[   (   '../data/postgresql-9.3.4/src/backend/commands/indexcmds.c',
        0.5887593627491802),
    ('../data/postgresql-9.3.4/src/include/utils/rel.h', 0.5847988052787634),
    (   '../data/postgresql-9.3.4/src/backend/optimizer/path/indxpath.c',
        0.5736868945937168),
    (   '../data/postgresql-9.3.4/src/backend/catalog/index.c',
        0.5695396670614502),
    (   '../data/postgresql-9.3.4/src/backend/optimizer/util/plancat.c',
        0.5669650556082131)]

--../data/postgresql-9.3.4/html-ja/indexes-intro.html--
[   (   '../data/postgresql-9.3.4/src/backend/lib/stringinfo.c',
        0.09184457364491616),
    (   '../data/postgresql-9.3.4/src/interfaces/ecpg/test/expected/sql-insupd.c',
        0.0886416204237675),
    (   '../data/postgresql-9.3.4/src/test/examples/testlibpq3.c',
        0.08837346944289427),
    (   '../data/postgresql-9.3.4/src/backend/access/heap/visibilitymap.c',
        0.08815864541352804),
    (   '../data/postgresql-9.3.4/src/interfaces/ecpg/test/expected/sql-indicators.c',
        0.08800994862677734)]

詳細な結果はhttp://staka.jp/doc-src/result.txtの通り。なんとなくだが、英語版マニュアルとソースコードはそれなりに紐付いているように見える。日本語のコメントが豊富にあるソースとであれば日本語版もうまく行くような気がしないでもない。

ソースコードはhttps://github.com/s-taka/doc-srcにおいておいた。基本的にPythonで書いていて、日本語マニュアルの形態素解析はMeCabで行っている。最近流行のword2vecの利用は今後の課題。

補記

前回同様、前段の補記。ドキュメントとソースが乖離していくのがよくある光景なのは事実だが、ドキュメントとソースが(ざっくりと)紐付いてうれしい人がどれだけいるかは謎。ドキュメント→ソース→コミットログ→作成者とたどっていけるのはある程度便利かもしれないが。本当は、ドキュメントとソースの乖離が分かるとうれしい人は多そうだけど、自然言語処理のアプローチでそれを見つけるのは至難の技だろーなーと思う。