yoshoku/rumale

Is there a way to show the classification report as in sklearn?

mcksshg opened this issue ยท 6 comments

Thank you for your awesome project.

In scikit-learn, `classification_report' function shows the classification metrics per-class basis.
I cannot find alternative method in Rumale. Is there a simple way to obtain similar report?

I wrote the following code to compare with the results obtained by using sklearn. I am not sure whether it is always correct...

def classification_report(label, predict)
  classes = label.to_a.uniq.sort
  label_prediction = label.to_a.zip(predict.to_a)
  # Evaluator
  precision_evaluator = Rumale::EvaluationMeasure::Precision.new(average: 'micro')
  recall_evaluator = Rumale::EvaluationMeasure::Recall.new(average: 'micro')
  # Evaluate precision and recall
  class_score = classes.map do |class_label|
    # precision
    pr_score = precision_evaluator.score(
        *label_prediction.select {|l,p| p==class_label}.transpose
      )
    # recall
    re_score = recall_evaluator.score(
        *label_prediction.select {|l,p| l==class_label}.transpose
      )
    # f_score
    f_score = re_score+pr_score != 0 ? 2*pr_score*re_score / (re_score + pr_score) : nil
    # num
    num = label_prediction.count {|label,predict| label==class_label}
    #
    [class_label, {precision: pr_score, recall: re_score, fscore: f_score, number: num}]
  end
  Hash[*class_score.flatten]
end

@mcksshg Thank you for your comment. As you pointed out, Rumale does not have a method equivalent to sklearn's classification_report method. Your code appears to work correctly. I also consider the code that works like classification_report.

Thank you for your quick response and consideration. I has been trying to port basic sample codes written in Python to Ruby. I think that this function is not essential but at least useful for beginner.

Thank you for your proposal. I will implement classification_report method in the next version ๐Ÿ‘Œ

@mcksshg I have released version 1.8.1 including classification_report method. Please confirm that.

https://yoshoku.github.io/rumale/doc/Rumale/EvaluationMeasure.html#classification_report-class_method

irb(main):001:0> require 'rumale'
=> true
irb(main):002:0> y_true = Numo::Int32[0, 1, 1, 2, 2, 2, 0]
irb(main):003:0> y_pred = Numo::Int32[1, 1, 1, 0, 0, 2, 0]
irb(main):004:0> puts Rumale::EvaluationMeasure.classification_report(y_true, y_pred)
              precision    recall  f1-score   support

           0       0.33      0.50      0.40         2
           1       0.67      1.00      0.80         2
           2       1.00      0.33      0.50         3

    accuracy                           0.57         7
   macro avg       0.67      0.61      0.57         7
weighted avg       0.71      0.57      0.56         7
=> nil
irb(main):005:0> pp Rumale::EvaluationMeasure.classification_report(y_true, y_pred, output_hash: true)
{"0"=>
  {:precision=>0.3333333333333333, :recall=>0.5, :fscore=>0.4, :support=>2},
 "1"=>
  {:precision=>0.6666666666666666, :recall=>1.0, :fscore=>0.8, :support=>2},
 "2"=>
  {:precision=>1.0, :recall=>0.3333333333333333, :fscore=>0.5, :support=>3},
 :accuracy=>0.5714285714285714,
 :macro_avg=>
  {:precision=>0.6666666666666666,
   :recall=>0.611111111111111,
   :fscore=>0.5666666666666668,
   :support=>7},
 :weighted_avg=>
  {:precision=>0.7142857142857142,
   :recall=>0.5714285714285714,
   :fscore=>0.5571428571428572,
   :support=>7}}

I have tried new method classification_report. It works fine! Thank you.