15

測定されたプロパティのいくつかの数値を持つ 5 つの要素 (AE) のセットがあるとします (たとえば、「心拍数」など、要素ごとにいくつかの観測値)。

A = {100, 110, 120, 130}
B = {110, 100, 110, 120, 90}
C = { 90, 110, 120, 100}
D = {120, 100, 120, 110, 110, 120}
E = {110, 120, 120, 110, 120}

まず、平均レベルに有意差があるかどうかを検出する必要があります。そこで、Apache Commons Math が提供する Statistical パッケージを使用して一方向ANOVAを実行します。これまでのところ問題はありません。違いが見つかったかどうかを示すブール値を取得しています。

第二に、違いが見つかった場合、他の要素とは異なる要素 (または複数の要素) を知る必要があります。要素が他の要素と異なるかどうかを知るために、要素の各ペア (A と B、A と C .... D と E) を比較して、対応のない t 検定を使用する予定です。したがって、この時点で、他の要素との大きな違いを示す要素のリストの情報を取得しています。たとえば、次のようになります。

C is different than B
C is different than D

しかし、その情報を使用して、どの要素が他の要素と異なるかを効率的に判断するための汎用アルゴリズムが必要です (この例では C ですが、複数の可能性があります)。

統計的な問題はさておき、問題は (一般的な用語で) 次のようになります。他は?」

グラフ理論が適用できる問題のようです。有用であれば、実装にJava言語を使用しています。

編集:要素は人であり、測定値はタスクを完了するのに必要な時間です。ある種の不正検出システムで、誰がタスクを完了するのに時間がかかりすぎているか、または時間がかかりすぎているかを検出する必要があります。

4

4 に答える 4

4

Apache Commons Mathを使用して統計演算を行い、Troveを使用してプリミティブ型のコレクションを操作することで、最終的なコードに興味がある人がいる場合に備えて。

次数が最も高い要素を探します (アイデアは @Pace と @Aniko のコメントに基づいています。ありがとうございます)。

最終的なアルゴリズムは O(n^2) だと思います。提案は大歓迎です。観測値の正規性を仮定すると、1 つの定性的変数と 1 つの定性的変数を含む問題に対して機能するはずです。

import gnu.trove.iterator.TIntIntIterator;
import gnu.trove.map.TIntIntMap;
import gnu.trove.map.hash.TIntIntHashMap;
import gnu.trove.procedure.TIntIntProcedure;
import gnu.trove.set.TIntSet;
import gnu.trove.set.hash.TIntHashSet;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.math.MathException;
import org.apache.commons.math.stat.inference.OneWayAnova;
import org.apache.commons.math.stat.inference.OneWayAnovaImpl;
import org.apache.commons.math.stat.inference.TestUtils;


public class TestMath {
    private static final double SIGNIFICANCE_LEVEL = 0.001; // 99.9%

    public static void main(String[] args) throws MathException {
        double[][] observations = {
           {150.0, 200.0, 180.0, 230.0, 220.0, 250.0, 230.0, 300.0, 190.0 },
           {200.0, 240.0, 220.0, 250.0, 210.0, 190.0, 240.0, 250.0, 190.0 },
           {100.0, 130.0, 150.0, 180.0, 140.0, 200.0, 110.0, 120.0, 150.0 },
           {200.0, 230.0, 150.0, 230.0, 240.0, 200.0, 210.0, 220.0, 210.0 },
           {200.0, 230.0, 150.0, 180.0, 140.0, 200.0, 110.0, 120.0, 150.0 }
        };

        final List<double[]> classes = new ArrayList<double[]>();
        for (int i=0; i<observations.length; i++) {
            classes.add(observations[i]);
        }

        OneWayAnova anova = new OneWayAnovaImpl();
//      double fStatistic = anova.anovaFValue(classes); // F-value
//      double pValue = anova.anovaPValue(classes);     // P-value

        boolean rejectNullHypothesis = anova.anovaTest(classes, SIGNIFICANCE_LEVEL);
        System.out.println("reject null hipothesis " + (100 - SIGNIFICANCE_LEVEL * 100) + "% = " + rejectNullHypothesis);

        // differences are found, so make t-tests
        if (rejectNullHypothesis) {
            TIntSet aux = new TIntHashSet();
            TIntIntMap fraud = new TIntIntHashMap();

            // i vs j unpaired t-tests - O(n^2)
            for (int i=0; i<observations.length; i++) {
                for (int j=i+1; j<observations.length; j++) {
                    boolean different = TestUtils.tTest(observations[i], observations[j], SIGNIFICANCE_LEVEL);
                    if (different) {
                        if (!aux.add(i)) {
                            if (fraud.increment(i) == false) {
                                fraud.put(i, 1);
                            }
                        }
                        if (!aux.add(j)) {
                            if (fraud.increment(j) == false) {
                                fraud.put(j, 1);
                            }
                        }
                    }           
                }
            }

            // TIntIntMap is sorted by value
            final int max = fraud.get(0);
            // Keep only those with a highest degree
            fraud.retainEntries(new TIntIntProcedure() {
                @Override
                public boolean execute(int a, int b) {
                    return b != max;
                }
            });

            // If more than half of the elements are different
            // then they are not really different (?)
            if (fraud.size() > observations.length / 2) {
                fraud.clear();
            }

            // output
            TIntIntIterator it = fraud.iterator();
            while (it.hasNext()) {
                it.advance();
                System.out.println("Element " + it.key() + " has significant differences");             
            }
        }
    }
}
于 2010-02-24T23:01:39.110 に答える
0

あなたの編集は良い詳細を与えます。ありがとう、

これに基づいて、典型的な応答では、かなり正常に動作する時間の分布(通常、またはおそらくガンマ。時間のゼロにどれだけ近いかによって異なります)を推測します。この分布からのサンプルの拒否は、標準偏差を計算して平均からn stdevを超えるサンプルを確認するのと同じくらい簡単な場合もあれば、データが適切なヒープに落ち着くまで外れ値を除外するサブセットを取得するのと同じくらい複雑な場合もあります(平均'多く'の動きを停止します)。

これで、ある試行でサルをしている人が別の試行でサルをしていると仮定すると、しわが追加されます。ですから、あなたはたまたま速い(または遅い)人と「浮気」している人を区別しようとしています。各スコアの標準偏差ランクを計算するようなことを行うことができます(これの固有名を忘れています:値が平均より2標準偏差高い場合、スコアは「2」です)、それを統計として使用します。

次に、この新しい統計を前提として、テストする必要のあるいくつかの仮説があります。たとえば、私の疑いでは、この統計の標準偏差は、他の人よりも均一に速い人よりも詐欺師の方が高くなりますが、それを確認するためのデータが必要になります。

それで頑張ってください!

于 2010-02-24T14:57:38.553 に答える
0

対応のある t 検定 (または実装したい任意の対ごとの検定) を実行し、キーが Person であり、カウントが異なる回数であるハッシュのカウントをインクリメントする必要があります。

people オブジェクトを含む arrayList もあると思います。people オブジェクトは、ID と、異なる時間のカウントを格納できます。同等のものを実装すると、配列リストをカウントでソートできます。

于 2010-02-24T20:51:32.887 に答える
0

リスト内の項目が番号順にソートされている場合、2 つのリストを同時に移動することができ、相違点は挿入または削除として簡単に認識できます。例えば

List A    List B
  1         1       // Match, increment both pointers
  3         3       // Match, increment both pointers
  5         4       // '4' missing in list A. Increment B pointer only.

List A    List B
  1         1       // Match, increment both pointers
  3         3       // Match, increment both pointers
  4         5       // '4' missing in list B (or added to A). Incr. A pointer only.
于 2010-02-24T21:19:36.863 に答える