3

私は sklearn のデシジョン ツリーを使用して、長い if-elif-else チェーンとしてのビジネス ルールの乱雑で管理不可能な実装を置き換えています。すべてのラベルに対して数千のテスト ケースを使用してツリーを検証しますが、トレーニング データとして使用しているルールを含むテーブルにエラーがあり、一部のテストがランダムに失敗することがあります。

結果のテスト ケースを超えて、ツリーを検証する方法が必要です。すべての葉ノードのジニが 0.0 である場合、異なるランダム シードで生成されたツリー間で分類にランダムな変動がないと仮定するのは正しいですか? アプリケーションでそれを強制する必要がある場合、トレーニング データを更新するときにそれを確認するのは合理的ですか?

私のケースは典型的な分類問題ではないことに注意してください。なぜなら、私はすでに決定木をコードに実装しており、アルゴリズムを使用して、現実世界のデータ サンプルではなく、慎重に調整されたデータから同等のツリーを生成したいからです。私の場合、ビジネス ルールを使用してデータ セットを維持する方が、コードを維持するよりも簡単です。

そのため、私のデータ セットでは、機能が可能な値の範囲をすべてカバーし、そのための明確なラベルを 1 つ付けることが理想的です。たとえば、実際のトレーニング セットは次のようになります。

features = [[1], [1.1], [2], [2.3]]
labels = ['sativa', 'sativa', 'indica', 'indica']

そして、アルゴリズムは次のような tree1 でランダムに発生する可能性があります。

if feature < 1.75:
    return 'sativa'
else:
    return 'indica'

そして次のようなtree2:

if feature < 1.55:
    return 'sativa'
else:
    return 'indica'

ただし、私のトレーニング セットには、ランダム性が発生するギャップはありません。次のようになります。

features = [[1], [1.9], [2], [2.3]]
labels = ['sativa', 'sativa', 'indica', 'indica']

したがって、最初のランダムな状態に関係なく、ツリーは常に次のようになります (明らかに、0.1 未満の差は無視されます)。

if feature < 1.95:
    return 'sativa'
else:
    return 'indica'

私の問題は、トレーニング セットにエラーがあり、ランダムな変動が発生する可能性のある値のギャップがあるかどうか、または同じ機能セットが異なるラベルに割り当てられているかどうかを検証する必要があることです。ランダムな状態を修正してもその問題は解決しません。同じデータが常に同じツリーを生成することを保証するだけです。

では、ツリーを生成する前にこれらの問題についてデータを検証するか、ランダムな変動を除外するのに十分な回数の包括的なテストを実行する以外に、ツリーでこれが発生するかどうかを判断する方法はありますか?

4

1 に答える 1

1

ラベル付けのルールがあり、機能の可能な範囲を知っているので、目的を達成できます。

例でこれを視覚化しましょう

ジニ指数

ジニ指数とは?これは、作成したばかりのツリーにトレーニング セットを適合させようとし、それらのアイテムがどの程度間違ってラベル付けされるかを示します。したがって、Tree1 と Tree2 では、gini = 0 になります。これは、トレーニング セットのすべての例が適切にラベル付けされるためです。

Tree1 と Tree2 は同じトレーニング セットを持ち、gini = 0.0 です。しかし、x=[1.7] にラベル付けしようとすると、異なる結果が得られます。

解決

特徴のセットをそれぞれのラベル付けにバインドするルールの知識があるため、次の場合、トレーニング セットが与えられた場合、可能な特徴に対して正しい結果を出力するツリーが常に生成されることを保証できます。

  • 連続値である機能は、範囲内にあります。[2,30]
  • 精度のしきい値を設定できます。上記の例では、少なくとも 0.1 ステップで変化します
  • 可能なすべての組み合わせの例を生成できます
  • あなたの木はジニ= 0.0を持っています

(基本的に、gini = 0.0 であるため、トレーニング セットに含まれていた入力を指定すると、正しくラベル付けされることを伝えています。ここで大きな飛躍的な結論はありません)。

したがって、次の場合:

   feature1 one of numpy.linspace(1,2,11) = [1., 1.1, 1.2, 1.3, ..., 2]
   feature2 one of True or False

と:

    Your examples have all the possible linear combinations 
    You have sum(all gini nodes) = 0
    The future examples are inside the condition boundaries of the training set

次に、次のことを確信できます。

    You covered all possible examples
    All possible examples are labeled correctly

このようにして、ランダムに初期化されたランダム ツリーは同じ出力を持ちます。それらは、トレーニング セットの範囲外にある例、またはしきい値規則に従わない値を持つ値を持つ例でのみ異なる可能性があります。

すでにそれを行っていると思いますが、テスト カバレッジ ツールを使用してトレーニング セットを作成し、考えられるすべての例が確実に作成されるようにすることをお勧めします。

連続値で可能なすべての値を使用する必要性について

[1.0, 1.1, 1.2, ... 1.9, 2.0] のような連続値のすべての可能な値が必要であると述べたとき、私は特に注意を払っていました。フィーチャが 1 つのノードのみで使用されている場合は、境界値 (例では 1.9 と 2.0) のみを使用できます。ただし、if-else がより複雑な場合は、予測できない複雑なシナリオが発生する可能性があります。機能 f1 を評価するノードの後に​​、左の生成ノードに (if f2 > 5) のような条件を、右のノードに (if f2 < 3) を、またはそのようなものにすることができます。そして、間違った結果を得る可能性があります。

組み合わせが大きくなりすぎる場合は、特徴を 2 値化することをお勧めします。次のような連続機能がある場合:

    if f1 > 3: f1 = 'many'
    if 3 <= f1 < 0 = 'little'

DictVectorizer オブジェクトを使用して、(1 0) と (0 1) に変換します。

次元の数を増やしていますが、ディシジョン ツリーは 2 つの機能に対して 1 つのノードしか作成しません。最初の値が true かどうかのみをチェックする場合、2 番目の値は相互に排他的であるため冗長です。

これは、データの境界がない場合の解決策でもあります。範囲のない ax 機能がある場合は、(x < 0, 0<= x < 5, 5 <= x) のように二値化し、連続値を (1 0 0)、(0 1 0) または(0 0 1)、考えられるすべての組み合わせを評価できます。

このようにして、組み合わせのセットのサイズを根本的に減らすことができます。

それだけです。乾杯!

于 2013-09-17T23:35:52.907 に答える