2017-05-29 9 views
0

ロジスティック回帰(閾値なし)やベータ回帰などの割合を予測する標準的な方法があります。すでにこれについての議論がありました:sklearn枠組みの中で仕事の周りに存在する場合目標変数が割合である場合のsklearnの使用方法

http://scikit-learn-general.narkive.com/4dSCktaM/using-logistic-regression-on-a-continuous-target-variable

http://scikit-learn-general.narkive.com/lLVQGzyl/beta-regression

私が言うことができません。

答えて

3

は回避策が存在するが、それは本質的にsklearn枠組みの中でではありません。

あなたは比例ターゲット変数(値の範囲0-1)をお持ちの場合は、scikit学習を持つ2つの基本的な困難に遭遇:(ロジスティック回帰など)

  • クラシファイアのみ対象変数としてクラスラベルとの契約。回避策として、確率を0/1に単純にスレッシュホールドし、クラスラベルとして解釈することができますが、多くの情報を失うことになります。
  • 回帰モデル(線形回帰など)は、ターゲット変数を制限しません。比例データでそれらを訓練できますが、目に見えないデータの出力が0/1の範囲に制限されるという保証はありません。しかし、この状況では、強力な回避策(下記)があります。

ロジスティック回帰を数学的に定式化する方法はいくつかあります。それらの1つはgeneralized linear modelであり、これは基本的にロジスティック回帰をロジット変換された確率に対する正規の線形回帰として定義している。確率は未知であり、回帰係数と共に推定される必要があるため、通常、このアプローチは洗練された数学的最適化を必要とする。

しかし、あなたの場合、確率は既知です。つまり、y = p/(1 - p)で簡単に変換できます。現在は、-ooからooまでの全範囲をカバーし、LinearRegressionモデル[*]のターゲット変数としての役割を果たすことができます。もちろん、モデル出力を再度変換して確率p = 1/(exp(-y) + 1)とする必要があります。

import numpy as np 
from sklearn.linear_model import LinearRegression 


class LogitRegression(LinearRegression): 

    def fit(self, x, p): 
     p = np.asarray(p) 
     y = np.log(p/(1 - p)) 
     return super().fit(x, y) 

    def predict(self, x): 
     y = super().predict(x) 
     return 1/(np.exp(-y) + 1) 


if __name__ == '__main__': 
    # generate example data 
    np.random.seed(42) 
    n = 100 
    x = np.random.randn(n).reshape(-1, 1) 
    noise = 0.1 * np.random.randn(n).reshape(-1, 1) 
    p = np.tanh(x + noise)/2 + 0.5 

    model = LogitRegression() 
    model.fit(x, p) 

    print(model.predict([[-10], [0.0], [1]])) 
    # [[ 2.06115362e-09] 
    # [ 5.00000000e-01] 
    # [ 8.80797078e-01]] 
  • 数多くの他の選択肢もあります。いくつかの非線形回帰モデルは、0-1の範囲で自然に働くことができます。例えば、Random Forest Regressorsは、訓練された目標変数の範囲を決して超えません。単に確率を入れれば、確率は上がります。適切な出力活性化関数(tanh、私は推測する)を持つニューラルネットワークも確率ではうまくいくが、それらを使用したい場合はsklearnよりも特殊化されたライブラリがある。この方法は、より強力にありませんが、それはもはや、ロジスティック回帰とまったく同じであることができ任意のlinear回帰モデルでは、実際のプラグインで

[*]あなたができました。

+0

0または1の確率を含むトレーニング/テストデータについて、何をすべきか説明してください。これらの場合、yは-infで0で除算されます。 –

+0

@ JakeDrew最も簡単な解決策は、* 0 *を* e *と* 1 *を* 1-e *に置き換えることです。* e *は非常に小さい数です。 ( 'p = p * e + 0.5 * e'で確率をサニタイズすることもできます)。私は 'e = 1e-16'がうまくいくと思います。 – kazemakase

+0

速い応答に感謝します!あなたが以前に提案したとおりに私は実験をしていました。私は、0と1の値に.009と.991を使用する範囲p =(0,1)に対して、10倍のMAE = 0.059または5.9%を生成することを見出した。同じデータでp = 9e-16を使用すると、MAEは最大0.2266または22.6%になります。 eの精度は平均絶対誤差に大きな影響を与えているようです。 y = np.log(p /(1-p))かつp = 0.991のとき、y = 6.9である。 p = 9e-16のとき、y = 36.7。おそらく、私は自分自身のデータセットに余裕がありますか? –

関連する問題