【问题标题】:Normalize a given random value to the range of 0 - 1 in java在java中将给定的随机值标准化为0-1的范围
【发布时间】:2018-02-01 03:08:53
【问题描述】:

假设我得到的值是以毫秒为单位的当前时间的差异 - 以毫秒为单位的某个日期时间。

double value = Calendar.getInstance().getTimeInMillis() - getMilliseconds(reportingDt);

所以这将是一个相当大的价值。现在我想将其标准化为 0 - 1 的范围。

请有人建议如何在 java 中实现这一点,以便我的值在 0 和 1 之间缩放。

reportingDt 越近,最终值越接近 1,reportingDt 越旧,最终值越接近 0。

更新

好吧,我对其进行规范化的方法如下。这更像是一个原型,但它对我有用。

private double getDocumentScore(String reportingDt) {

        Date offset = null;
        try {
            offset = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss.SSS").parse("24-08-2017 13:53:30.802");
        } catch (ParseException e) {
            e.printStackTrace();
        } 

        long currentTime = Calendar.getInstance().getTimeInMillis(); 
        if(offset != null) {
            // If offset is set then instead of current datetime consider offset
            currentTime = offset.getTime();
        }
        System.out.println(reportingDt);
        long value = currentTime - getMilliseconds(reportingDt);

        long minutes = TimeUnit.MILLISECONDS.toMinutes(value);
        double score = 2 * (1 / Math.log(minutes));
        System.out.println(score);
        return score;
    }

    private long getMilliseconds(String dateTime) {
        SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss.SSS");
        Date date = null;
        try {
            date = formatter.parse(dateTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date.getTime();
    }

样本输入日期和输出归一化分值为

11-07-2017 14:34:05.416
0.18089822028334113
11-07-2017 14:34:06.023
0.18089822028334113
11-07-2017 14:34:06.595
0.18089822028334113
11-07-2017 14:34:07.139
0.18089822028334113
11-07-2017 14:34:08.873
0.18089822028334113
11-07-2017 14:34:11.171
0.18089822028334113
11-07-2017 14:34:12.954
0.18089822028334113
11-07-2017 14:34:12.962
0.18089822028334113
11-07-2017 14:34:34.516
0.18089847869291217
11-07-2017 14:34:35.720
0.18089847869291217
11-07-2017 14:34:38.566
0.18089847869291217
11-07-2017 14:34:39.205
0.18089847869291217
11-07-2017 14:34:40.357
0.18089847869291217

下面是我考虑标准化值的各种评分函数的图表。最后我使用了绿线一 (2* (1/log(x)))

【问题讨论】:

  • 该双精度值的范围是多少?您可能需要首先考虑这一点,因为如果没有定义的范围,您就无法标准化。
  • @OHGODSPIDERS 我可以得到所有的值,把它放在一个列表中,然后找到最小值和最大值,从而有一个范围。
  • 你可以用其他方式来做,最近的reportingDt接近0,更早的接近1。你可以通过将最终值除以Calendar.getInstance().getTimeInMillis()来做到这一点
  • @a_a 不,否则不会让我得到我正在寻找的正确的东西。它必须更接近 1,而更接近 0。
  • 再次重申:如果您对 double value 不了解 任何事情 - 那么您就无法对其进行规范化。假设第一次调用的值为 5000。它应该更接近 0 还是接近 1?如果第一个值是 50000 怎么办?如果不知道要规范化的值的范围,就无法规范化!

标签: java java-8 range scaling normalize


【解决方案1】:

您说您可以将所有值放在一个列表中并计算最小值和最大值。然后可以像这样对每个值进行归一化:

/**
 * Calculates a value between 0 and 1, given the precondition that value
 * is between min and max. 0 means value = max, and 1 means value = min.
 */
double normalize(double value, double min, double max) {
    return 1 - ((value - min) / (max - min));
}

【讨论】:

    【解决方案2】:

    抱歉,这无法解决。为什么?因为时间在流逝,对于相同的 DateTime 值,您会得到不同的值,这取决于您是今天、明天还是一年后执行代码...

    您必须有一个要观察的固定时间范围。如果你说你想从 1970 年 1 月 1 日到 2070 年 1 月 1 日,你可以简单地将你的时间跨度值除以这个最大时间跨度值。从中减去 1 并将结果设置为绝对值。但是这个结果只有在本世纪 60 年代才会接近 1。这不是您真正想要的。

    那么,另一方面,浮点数在逗号后面有很多数字,而不是在逗号前面有很多数字的长值有什么用?

    【讨论】:

      【解决方案3】:

      这样做-

      double currenttime=Calendar.getInstance().getTimeInMillis();    
      double value= currenttime- getMilliseconds(reportingDt);
      double normalized=(1- value/currenttime;
      System.out.println(normalized);
      

      【讨论】:

      • 这等于getMilliseconds(reportingDt)/currenttime。它将从负数(对于早于 1970 年的报告 Dt)到 1(对于报告 Dt = 现在)不等。
      猜你喜欢
      • 2019-08-12
      • 2020-12-23
      • 1970-01-01
      • 2016-08-19
      • 2017-06-27
      • 1970-01-01
      • 2016-10-31
      • 2018-06-15
      • 1970-01-01
      相关资源
      最近更新 更多