lightgbm 回歸損失函數


 

sum_weights 可以通過參數設置。 如果不設置,那么值就是樣本的個數。   指定每個樣本的權重。   

我突然想到基金預測,可以設置樣本的權重。  真實漲幅越高,權重越小。   反之,權重越高。    因為如果預測偏低,那么loss 損失越大。

 

 

"rmse":  

sum_loss = 和 (score - label)*(score - label) 
loss = std::sqrt(sum_loss / sum_weights);
 
 

"l2": 誤差的平方:

sum_loss = 和 (score - label)*(score - label) 
loss = sum_loss / sum_weights
 

"l1": 誤差的絕對值:

sum_loss = 和 fabs(score - label)
loss = sum_loss / sum_weights
 

"quantile": 分位數損失

  inline static double LossOnPoint(label_t label, double score, const Config& config) {
    double delta = label - score;
    if (delta < 0) {
      return (config.alpha - 1.0f) * delta;
    } else {
      return config.alpha * delta;
    }
  }
 
從c++ 代碼可以看到, 如果alpha為0.5,   那么就是誤差的絕對值* 0.5.    如果為0.2。 那么就是負誤差越小,損失越大。  從圖中可以看出,alpha值越大,正誤差損失斜率越低。 為0.5時正負斜率相等
 
sum_loss = 和 LossOnPoint(label, score)
loss = sum_loss / sum_weights 

 

 

 

 

"huber":

  inline static double LossOnPoint(label_t label, double score, const Config& config) {
    const double diff = score - label;
    if (std::abs(diff) <= config.alpha) {
      return 0.5f * diff * diff;
    } else {
      return config.alpha * (std::abs(diff) - 0.5f * config.alpha);
    }
  }

預測的分數離標簽值越近,越趨近0.    從圖中可以看出,  就是平方損失函數的壓縮版。 huber損失值相對平方損失壓小了。  alpha越小, Huber損失值壓的越狠。

 

 

 

"fair":公允價值變動損失

  inline static double LossOnPoint(label_t label, double score, const Config& config) {
    const double x = std::fabs(score - label);
    const double c = config.fair_c;
    return c * x - c * c * std::log(1.0f + x / c);
  }

 

 從圖中可以看出, fair_c 越小, 損失越小。  fair_c 越大損失越大

 

"poisson": 柏松回歸

  inline static double LossOnPoint(label_t label, double score, const Config&) {
    const double eps = 1e-10f;
    if (score < eps) {
      score = eps;
    }
    return score - label * std::log(score);
  }

  

 

 如果出現負誤差, 那么損失值非常大。

 

mape:

  inline static double LossOnPoint(label_t label, double score, const Config&) {
    return std::fabs((label - score)) / std::max(1.0f, std::fabs(label));
  }

 

 

gamma: 分布

  inline static double LossOnPoint(label_t label, double score, const Config&) {
    const double psi = 1.0;
    const double theta = -1.0 / score;
    const double a = psi;
    const double b = -Common::SafeLog(-theta);
    const double c = 1. / psi * Common::SafeLog(label / psi) - Common::SafeLog(label) - 0;  // 0 = std::lgamma(1.0 / psi) = std::lgamma(1.0);
    return -((label * theta - b) / a + c);
  }

 限制條件: label 必須大於0

 

 

 從圖中可以看到, 標簽值越大, 預測值離標簽值越近,損失值越小。   在預測值在標簽值附近的時候,損失值差別不大

 

 "gamma_deviance":

  inline static double LossOnPoint(label_t label, double score, const Config&) {
    const double epsilon = 1.0e-9;
    const double tmp = label / (score + epsilon);
    return tmp - Common::SafeLog(tmp) - 1;
  }

  

從圖中可以看出, 當標簽為1的時候,損失值是線性的, 標簽值大於0的時候。  標簽為2的時候,是分段線性的。  負誤差的斜率和正誤差的斜率要陡。

 

"tweedie" 類分布

  inline static double LossOnPoint(label_t label, double score, const Config& config) {
    const double rho = config.tweedie_variance_power;
    const double eps = 1e-10f;
    if (score < eps) {
      score = eps;
    }
    const double a = label * std::exp((1 - rho) * std::log(score)) / (1 - rho);
    const double b = std::exp((2 - rho) * std::log(score)) / (2 - rho);
    return -a + b;
  }
tweedie_variance_power = 0.2  時, 函數圖形如下:  

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM