我使用 Logistic回归来训练我的数据。 在这个过程中,我需要计算一个 sigmoid函数,编码如下:
private double sigmoid(double x) {
return 1.0 / (1 + Math.pow(Math.E, -1 * x));
}
因此,如果我的x
大于36,则会始终返回1.0
,我会在Infinity
中获得log(1 - sigmoid(x))
。
我认为java不是机器学习的好语言,我只需要在这个项目中申请。
我也通过这个question了解Java的精确原则,但我仍然想知道是否有解决这个问题的方法。
答案 0 :(得分: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)));
答案 1 :(得分: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);
}
}
答案 2 :(得分:0)
还有其他编写sigmoid函数的方法更多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);
}
}