2017-07-01 18 views
-1

私はロジスティック回帰を使ってデータを訓練していました。この過程で は、私は次のようにコード化されたシグモイド関数を計算する必要があります。 機械学習で高精度のdouble値を使用するにはどうすればよいですか?

private double sigmoid(double x) { 
    return 1.0/(1 + Math.pow(Math.E, -1 * x)); 
} 

だから私 xが36よりも大きい場合、それは常に 1.0を返す、と私は log(1 - sigmoid(x))Infinityを取得します。

私は、機械学習ではJavaが良い言語ではないと思うので、このプロジェクトに応募するだけです。

私はまた、このquestionを介してJavaの精度原則を知っていますが、私はまだこの問題を解決するためにとにかく知りたいです。

+1

以上あるシグモイド関数を書くの他の方法がありますが、高精度の値は 'BigDecimal'を使用することを検討してください。また、この質問はあなたに役立つ可能性があります:https://stackoverflow.com/questions/13784056/calculating-sigmoid-value-of-a-bigdecimal-in-java –

+3

「私はJavaが良い言語ではないことを知っています」 - 無知な言葉。 – duffymo

+0

これは浮動小数点固有です(言語固有ではありません)。 1つのトリックは、可能な場合に、異なるスケール、たとえば対数の1つまたはそれを使用することです。おそらくないでしょう。 –

答えて

1

それは精度の問題であるが、爆発勾配に対処し、数値安定性を確保するための通常の方法は、関数の入力をクリップすることである。

final double CLIP = 30d; 
input = Math.min(CLIP, Math.max(-CLIP, input))); 
return 1.0/(1.0 + Math.exp(-input)) 

ます。また、[0、1に出力をクリッピングすることができ]:

double output = 1.0/(1.0 + Math.exp(-input)) 
return Math.min(0d, Math.max(1d, output))); 
+0

私は正しく理解しているかどうかわからないが、シグモイド関数は常に0と1の間の値を返すので、何も変更することはできない。あなたの意味は 'Math.min(CLIP、Math.max(-CLIP、input))'のようなものですか? – fmyblack

+0

trueの場合、シグモイド出力は0と1の間で切り取ることができます。また、入力をより高い10進数で切り取ることもできます。 –

0

これが私のために完璧に動作が

は20、40、49

をテスト
import java.math.BigDecimal; 
import java.math.MathContext; 

/** 
* 
* @author tawfik 
*/ 
public class Mathic { 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     BigDecimal sigmoid = sigmoid(37); 
     System.out.println(sigmoid); 
    } 
    static private BigDecimal sigmoid(double x) { 
    return new BigDecimal(1.0).divide(new BigDecimal(1).add(new BigDecimal(Math.pow(Math.E, -1 * x))),MathContext.DECIMAL128); 
} 
} 
0

numerically stable

private double sigmoid(double x) { 
    if (x > 0) { 
     return 1.0/(1 + Math.exp(-x)); 
    } 
    else { 
     z = Math.exp(x); 
     return z/(1 + z); 
    } 
} 
関連する問題