お報せ

童帝雑談所自動抽出でAAではないレスを拾う場合がある件に関する説明

Google chrome使用時に順番がズレるケースがある問題について












スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
[ --/--/-- --:-- ] スポンサー広告 | TB(-) | CM(-)

当サイトで行っているAA自動判別フィルタの仕組みと、AAではないレスが抽出されてしまうケースに関する説明

この文書は、私の作成した「したらば形式ログから、やる夫スレとしてそれっぽくレスを抜き出すライブラリ」の挙動、およびライブラリを使用して公開している童帝雑談所の自動抽出における抽出基準やノイズが混ざる理由に関する質問へのFAQとして書かれた文書です。

自動抽出時の抽出ポリシー



当ライブラリの自動抽出ポリシーは単純です。

1. >>1は抽出する
2. トリップつきの書きこみは抽出する
3. 1.にマッチする書き込みと同IDの書き込みは抽出する
4. AAに見える書き込みは抽出する
5. 2や4を満たす書き込みと同IDの書き込みについては、他の条件次第で多少は抽出する
6. 抽出したレスでアンカーがついていたら多少は追う(アンカー元のレスの一部として抽出する)
7. どの条件も満たさない書き込みは無視する

これは原則ですので、実はもう少し細かい処理がありますが、基本的にはこんなかんじです。
厳密に説明しようとするとプログラミングや情報処理的な素養が無いと理解できない文章になってしまいますので、そのへんは割愛します。

また、「4. AAに見える書き込みは抽出する」ですが、これは>>1のIDが変わった状態(翌日とか別の端末とか)でトリをつけ忘れた場合に拾い損ねないようにするための条件です。
(あと、私が>>1がトリをつけないスレも追っているから作った機能でもあります)
もちろん判別は完璧ではありませんし、この条件を外すことは容易いのですが、「>>1がミスったら拾い損ねる」よりも「たまに余計なレスがまざる」方がマシなので、童帝スレのロボットにおいてはこの判別は有効にしています。

以下、このAA判別のロジックについて簡単に記します。


どうやってAAとそれ以外を判断しているか



以下の差を見て、日本語の文章なのかAAなのかを判別します。
判別の方法は色々考えられますが、当ライブラリでは、テキスト中に出現する文字とその割合の偏り方から「これは日本語っぽいぞ」「これはAAっぽいぞ」と判別しています。


日本語の文章の傾向


日本語の文章における具体例ですが、2014/03/20現在におけるhttp://yaruo.wikia.com/wiki/やる夫スレのテキストに対し、出現する文字ごとに出現数の集計を行いますと、こうなります。
graph02.png


「る」が一番多く94文字、対で「の」が68文字、「に」が51文字、…と出てきまして、全てをグラフにすると、高等数学でおなじみの y=log2(x) のグラフを上下反転させたような形のグラフになります。

もうちょっと硬い文章にも同じ解析をかけてみましょう。
安倍首相の東日本大震災三周年追悼式 内閣総理大臣式辞の場合は、こうなります。

graph03.png


口語の多い文章も見てみましょう。
AAではない「日本語の文章」の範疇として、比較的カオスになる適当なSSに対して同じようにグラフにしてみました。
graph04.png



ニュース、プログラム言語の関数マニュアル、企業の内部文章などいくつか傾向の異なる他の文章にも同じ解析をかけてみましたが、全て同じようなグラフになりました。
というわけで、素人考えですが、たいていの日本語の文章は同じようなグラフになると判断しました。


AAの傾向

試しにやる夫AA録2収録の2013/04/20現在の銀ちゃんの基本AAのmltに対して、上記の解析をかけてみます。
graph10.png

通常の日本語の文章に比べて、明らかにカーブが急なグラフになりました。
これは、再頻文字とそうではない文字との間の出現頻度格差が激しいということです。

銀ちゃんのmltでは本当にAAだけですので、これに台詞が乗った場合を考えてみます。
手っ取り早いサンプルとして、無触蹌踉童帝 ◆CDXOg0zb8Eのルドン高原 87スレ目から適当に抜き出したテキストを解析にかけてみましょう。すると、こうなります。

graph11.png



やはり、通常の日本語文章に比べてカーブが急で、最頻文字とそうではない文字との出現頻度落差が激しい結果になりました。
多少の台詞や描画が入った程度では覆らないほどの強い傾向があることがわかります。
追試は省きますが、ライブラリ作成時に試した殆どのサンプルにおいて、この傾向は変わりませんでした。


レス単位の場合

日本語の文章とAAの場合、構成文字ごとの出現頻度をグラフにすると明らかな違いがあることがわかりました。
今回解析したい処理単位は「レス」ですから、もっと粗いサンプルでの傾向も必要です。
詳細は省きますが、レス単位の短い文章でも、上記二者同様の傾向が広く認められました。

具体的な閾値については省略しますが、レス単位でこの傾向を判断して、「AAかそうではないか」を判別しています。


構造的な問題点

この判断ロジックには、若干の構造的な問題があります。
コンピュータはテキスト文字列を見て「これは文章だ」「これはAAだ」と直感的に判断できないため、このようなロジックを必要としています。
このロジックは文字の出現頻度グラフを根拠に判別しているため、まれに日本語の文字列だけど、偶然、AAの場合の文字出現頻度グラフと同じようなグラフになったようなケースが発生します。
このような場合、ロボットはそのレスをAAと誤認して、拾ってしまいます。
この誤認は、短い文章の場合に発生しやすいです。

良く似た解析誤認(というか根本的には全く同じ理由)ケースとして、、「日本語が少数記述されたWebサイトを見た時にWebブラウザが文字コードの自動判別に失敗して文字化けを起こす」ケースが挙げられます。

この問題は、現在採用しているアルゴリズムでは解決不可能です。


付録:違うロジックでのAA判別



以下、AA判別ライブラリを作成するにあたって検討した、別のアプローチでのロジックについて記します。
これらは、

  • ライブラリのライセンス的に使いにくい
  • 口語処理に向かない
  • 使っているサーバのパワーが足りない(266MHzとかのCPU+32MBのメモリな別用途サーバに相乗りしてるので)
  • 今回採用したプログラム言語で利用するには向かない
  • 私の仕事が忙しくて、試す時間が無い
  • 私のプログラムの腕が足りない ;-(

などの理由でオミットされたものです。このへんが解決したら、ライブラリのバージョンアップ時に試してみる可能性はあります。
(でも当分暇にはならない気配はする)


形態素解析を使う

テキストを形態素解析にかけると、文法や辞書にある単語か等を根拠に品詞分解して、自然言語の構成としてそれっぽく分解してくれます。
これにより、レス1つ1つが日本語としてどの程度成立していそうかが何となくわかります。
通常のレスは日本語としてそれなりに成立していて、AAのレスは品詞判別できない個所が多くてノイズの割合が高い、などの傾向の差が出ますので、その違いを見てAA判別可能です。

が、実際にやってみますと、多くのレスは口語やスラングが多く、短い文章も多い傾向があります。
これが、形態素解析には単語境界判別の問題がある、口語文は未知語が多い、口語文はルーズな文法が多い、などの形態素解析の弱点にクリーンヒットします。
結果、私のよく見るスレにおいては現在採用した手法よりも判別精度が甘くなってしまったので、取りやめました。
(スレによって書き込みに傾向があるので、スレによっては形態素解析のほうが良いかもしれません。たとえば読者による長文の考察が多い歴史系などでは形態素解析による判別の精度はかなり高くなると思います)

あと、私のサーバではパワーが足りなかったってのも大きいです。

この解析で試したエンジンは、以下の通りです。
KAKASI (kanji kana simple inverter)
ChaSen
Sen (Java版MeCab)


NGramを使う

NGramで複数のトークンを生成してみます。
その上で、それらのトークンが単語として成立している割合を比較すればAAと文章が判別できます。
たとえば「これは日本語です」を 2Gramで解析すると「これ」「れは」「は日」「日本」「本語」「語で」「です」「す」となります。
このうち「これ」「日本」「です」あたりは単語として辞書にありますので、8トークン中3つ、単語としてヒットしたことになります。
通常レスや合いの手はこの割合が高く、AAはこの割合が非常に低くなります。

この手法はそこそこ精度が高い判別ができたのですが、サーバの処理能力の都合と、口語表現用辞書の入手の都合で、とりやめました。


ベイジアンフィルタを使う

ベイジアンフィルタとは、単純ベイズ分類器を応用し、対象となるデータを解析・学習し分類する為のフィルタです。
身近なところではSPAMメールの判別などに使われます。
ベイジアンフィルタの実装そのものに形態素解析が必要なため形態素解析を使ったモデルの弱点のいくつかを引き継いでしまうのと、判別のためにサンプルを食わせるのが結構なマンパワーを要求するのと、何より私のプログラムの腕が足りなくて十分な精度のベイジアンフィルタを組めなかったという理由で挫折しました。
まぁ、サーバのマシンパワーも結構必要でしたので、仮に私の腕が足りてたとしても、サーバのパワー不足で挫折した気はします。


どの方法を使っても誤認してしまうレスの例



こんなかんじのは、どの方法を使ってもかなりの確率でAAと誤認してしまいます。

「こ…こwwwれwwwwはwwwwひwwwwwどwwwwいwwwwwwww」

文字出現頻度グラフ法(仮名) → 「w」の頻度が異様に高いため、AAのスクリーントーン用文字として「w」を使っている書き込みだ、と誤認してしまうようです。
形態素解析 → 文法がルーズすぎて、日本語の文法で分解できる個所が一切無いため、「全部ノイズだ」→「全部AAだね!」と誤認してしまいます。
NGram → 2Gramだろうが10Gramだろうが辞書に存在する単語扱いできる個所の抽出が一切不可能なため、日本語の単語出現頻度ゼロ→「全部AAだね!」と誤認してしまいます。
ベイジアンフィルタ → 同じ文字(w)ばかり出るのをスクリーントーンと誤認してAA判断してしまう可能性が高いです。

このうち、ベイジアンフィルタだけは、学習を重ねていけば「AAではない」と判断できる可能性があります。
まぁ、私のプログラムの腕的に、その制度のベイジアンフィルタと学習機構を組める自信は一切無いわけですが……。
関連記事
[ 2014/03/21 14:34 ] 雑事 | TB(-) | CM(-)
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。