このエントリではRDFチェックツール「rdflint」に実装した、
外れ値検証機能の仕様と、その仕様の検討経緯について紹介します。

「rdflint」とは、
Linked Open Dataと呼ばれる、インターネット上を通じて、
機械での処理に適したデータを公開・共有するための技術に、
RDF(Resource Description Framework)という
データを記述する枠組みがあるのですが。
この枠組みに基づいて記載されたデータを機械的にチェックするためのツールです。

rdflint | GitHub
https://github.com/imas/rdflint

rdflintの外れ値検証機能の仕様

rdflintの外れ値検証機能は、利用ガイドにも記載しましたが。
階層的クラスタリングで
1つしかデータを含まないクラスタが出来ないかをどうかで判断しています。

rdflintの実装では、階層的クラスタリングと言っても、
変数毎に判断しているため、次元は1つしかありません。

2つのクラスタに振り分けるとすると、
値を順に並べて、最初か最後の値の間隔が最も大きい場合に、
1つしかデータを含まないクラスタが出来ます。
また、3つのクラスタに振り分けるケースでは、
値を順に並べて、間隔の大きさ1,2位が連続する時に、
1つしかデータを含まないクラスタが出来ます。

上記の2クラスタ、3クラスタのケースで、
1つしかデータを含まないクラスタのデータを外れ値と判断しています。
実際には、他の間隔で最も大きなものの3倍以上間隔が離れている場合
という閾値を設けています。

検証ルール | rdflint: RDF Linter
https://imas.github.io/rdflint/rules.html

外れ値検証機能の検討経緯

rdflintの外れ値検証機能は、上記の通りの仕様で実装されていますが、
個人的なノートと言う意味で、検討経緯をまとめておきます。

外れ値を見つける方法はいろいろありますが、
例えば、以下のサイトで紹介されているような方法があります。

32-1. 外れ値 | 統計学の時間 | 統計WEB
https://bellcurve.jp/statistics/course/12929.html

紹介されている手法

  • 箱ひげ図を描く
  • 外れ値検定を行う
  • クラスター分析を行う

これらの方法を実装しようと考えた時に、
一番に思いつくのは、外れ値検定の「スミルノフ=グラブス検定」を使うことです。

スミルノフ=グラブス検定は正規分布を仮定するので、
正規分布ではない変数を除外する必要があります。
そのため、この手法を採用しようとすると、
まず始めに正規分布かどうかを判断(正規性検定)する必要があります。

正規性検定については、以下の講義資料がわかりやすいです。

データ解析 第八回「検定」
http://ibis.t.u-tokyo.ac.jp/suzuki/lecture/2015/dataanalysis/L8.pdf

上記を踏まえて、以下のような実装をすることを考えました。

  1. シャピロ・ウィルク検定で正規分布かを判定、正規分布で無い場合はチェック対象外
  2. スミルノフ・グラブス検定で有意水準を決定
  3. 有意水準から外れる値を外れ値として検知

rdflintはJavaで実装されているので、Javaの実装を探したところ、
シャピロ・ウィルク検定については、以下の実装がありました。

elcronos/shapiro-wilk | GitHub
https://github.com/elcronos/shapiro-wilk

スミルノフ・グラブス検定の実装は見つけられなかったですが、
Apache Commons Mathにt分布があるので、割と簡単に実装が出来そうです。

Class TDistribution | commons-math3
https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/index.html

と、言うところまで検討したのですが。

よく考えると、rdflintでは検出したい外れ値には、
正規分布以外のデータが結構あるように思いました。
ID番号のようなデータは一様分布ですが、
桁がズレるなどの記載ミスもありがちな気がします。
データ大きくなると計算に時間がかかると言う問題もあるので、
計算が簡単なクラスタリング手法(値の間隔を見て判断)で実装しています。

ひとまずはこの方法で様子見でよいかな、と考えていますが。
将来的に正規分布を仮定した検定を実装するかもしれない自分のために、
このエントリを書いておきました。