夜のブログ

講評です

集計自動化メモ:現状の制限

2006-06-07 20:27:49 | 超-1
で、現状わかっている問題についても書いておきます。
そもそも超-1はヒューマンパワーによってのみ成し得る仕事ですので
自動化といっても色々条件が付きます。
以下はそんな注意点です。

再講評はどうしよう



数は少ないですが、同一の投稿者名で複数のコメントが書かれている場合があります。
単純な2重投稿でなければ、スクリプトで判定できません。
これは最悪、繋げて出します。


自動採点



現在、好評や▲、不評や▼、-1、無得点や-0、プラスマイナス0が明記されている講評については
自動的に点数を計算しています。

これは飽くまで入力の手間をわずかでも省くためであり、最終的な判断は人間に委ねられる前提です。


その自動採点は、判断を諦めると0でもなく、無記入として出力します。

ですが、判断を諦められない場合もあります。

「限りなく好評に近いですが、+-0としておきます」

みたいな講評は「好評」と「+-0」にヒットし、どちらかわからないので判断を諦めますが

「限りなく好評に近いですが、好評までは至りません」

というような書き方だと「好評」のみにヒットし、+1であると判断してしまいます。
自動でやるならもう少しなんとかしたいかなぁーと思わずにいられない。

また人によっては△を「好評」の意味ではなく、「まあまあ」の意味で使っている人もいらっしゃいました。
そういう部分でもしっかり誤判定をやらかす恐れがあります。
(スクリプト上では、▲は好評だけど△は不明という扱いにしてありますが、
同様の理由により同じ事故は起き得るでしょう)

微妙なのは、この自動判定がまったく信用ならぬものなら安心できるのですが
ざっと見た感じ6-7割くらいは信用できるという点です。
潔くOFFってしまったほうがいい機能かも知れない。


うっかり無記名で投稿した場合



実はこれが一番厄介です。
うっかり名前を入力し忘れてコメントを投稿し、後から

「↓は私の講評です」

などと補足する場合。
補足の仕方は人によって異なり、自動では判別できないので、名前入力忘れの講評は名無し講評として処理されてしまいます。

この場合、少なくともXML上(消さなければCSV上にも)には、「↓は私の講評です」という謎のメッセージは残りますので
最終的に監査を行う人間(加藤さん?)が意図を汲んで修正する余地はあります。
余地はありますが、見過ごされる可能性もあるわけで、非常に不安と言えましょう。
こういう事故はそんなに多くないというのだけが救いかな。

集計自動化メモ

2006-06-07 19:36:47 | 超-1
超-1の集計をある程度楽にできないかということで始めて見ました。
思い立ったのは講評締め切り当日(2006/6/3)で講評の締め切りに合わせて開始しました。

とりあえずやり方や懸念事項などを明らかにしておくことで、
(もしあれば)次回開催以降の参考等になりましたら、ということで。


1. 講評データを集める



これはwww.chokowa.comからHTMLを取り出してきて、perlスクリプトにかけXMLに変換します。
取り回しやすいDBがあればそっちに突っ込んでしまっても良かったのですが
手ごろなDBがなかったのとXML-DBという手もあったのでこれで良かろうと。

HTMLの内容にもよりますが、幸いにも超-1のHTMLは扱いやすかったです。


2. 講評データXMLから講評者DBを作る



講評データを舐めて、使用されている名前を引っ張り出せばよいのですが
生憎一人の講評者がいつも同じ名前で投稿してくれるとは限りません。
半角だったり全角だったり、苗字と名前の間にスペースがあったりなかったりします。
なので、講評者DBのXMLは以下のような構造になっています。

<name id="一意な値">hydrogen</name>
<index>94</index>
<filter>(hydrogen|hydrogen)</filter>

これで一人分です。
filterは同一講評者だが名前が若干違うコメントを同定するための正規表現です。
indexというのはCSVなどに変換するときに、何番目の列に名前が現れるか、です。
この要素がなければCSVには変換できませんが自動では無理なので、中間集計のCSVを参考に手で埋めます。
CSVに登場しないがコメントを投稿している(作者さん、TB代行などの非講評)は
indexの要素を負の値としておき、名無し講評は全てindexは0で統一とします。

この講評者の抜き出し作業はXSLTで行います。
ここではxsltprocというXSLTプロセッサ(そのまんま)を使い、データの抜き出し、IDの発行を行います。
同じ(と思われる)人を抜き出して同定のための正規表現を書くのと、indexの割り当ては手で行います。


3. 講評データに講評者IDを振る



1と2の結果を合わせ、最終的なXMLを生成します。
2の講評者DBのfilter要素を使って、1の講評者を同定するためです。
具体的には、1の講評の全てに2のIDを振り分け、どの講評が誰のものか解るようにする作業です。

これは再びPerlスクリプトで行いました。
要素から取得した文字列を正規表現としてマッチングさせるのが楽だからです。
やるのは2のXMLからfilterを取り出してマッチングして、マッチしたら s/<name>/<name ref="$id">/ とするだけなので
Perlでも全然楽勝です。

(余談ですが、Perlでは5.8.0以降UTF-8が扱えるようです。
UTF-8にしておくと(文字境界が自明なためか)日本語正規表現が使えて大変ありがたいです。
またPerlでXMLをDOMとして扱うために、XML::DOMモジュールを入手しておきましょう。
perl -CPAN -e shell で install XML::DOM とすればOKですが、root権限が必要になりがちです。)


4. データの見た目を整える



3で最終的なXMLが手に入ったらあとは楽勝です。
どのような形でも拡張可能です。

で、CSVへの変換ですが、最初XSLTでやろうとして挫折しました。
SQLみたいな完全に集合論の世界なら楽なのですが、ある程度イベントドリブンである程度逐次処理、ある程度集合も書けるという感じで
なかなかCSVにするのがしんどい。

特に悲惨なのが <xsl:value-of select="id(@id)" /> で逆参照が出来ないところ。
これは二重ループにして、articleごとの処理中に、講評者テーブルごとにcommentの集合と付き合わせることが出来ましたが
ここで多重投稿の除去や名無し講評だけ合算とか、その他のワークアラウンドを含めると
物凄くきついことになってしまいます。

で、結局これもPerlで処理したほうがよいという結論に至り。


あとはせいぜい、XMLがでかくなりすぎたので各シーズンに分割するためのXSLとか。
その辺は一通り揃ったらUPします。