如何在SQL中计算classification_report(精确度、召回率、F1分数和支持)?

huangapple go评论158阅读模式
英文:

How to count classification_report ( precision recall f1-score support) in sql

问题

我可以帮你编写SQL查询来生成类似classification_report的结果。以下是一个可能的查询示例:

SELECT
    'False' AS class,
    SUM(CASE WHEN real_value = 'true' AND predict_value = 'false' THEN 1 ELSE 0 END) / SUM(CASE WHEN real_value = 'false' THEN 1 ELSE 0 END) AS precision,
    SUM(CASE WHEN real_value = 'true' AND predict_value = 'false' THEN 1 ELSE 0 END) / SUM(CASE WHEN predict_value = 'true' THEN 1 ELSE 0 END) AS recall,
    2 * (SUM(CASE WHEN real_value = 'true' AND predict_value = 'false' THEN 1 ELSE 0 END) / SUM(CASE WHEN real_value = 'false' THEN 1 ELSE 0 END) * SUM(CASE WHEN real_value = 'true' AND predict_value = 'false' THEN 1 ELSE 0 END) / SUM(CASE WHEN predict_value = 'true' THEN 1 ELSE 0 END)) / (SUM(CASE WHEN real_value = 'true' AND predict_value = 'false' THEN 1 ELSE 0 END) / SUM(CASE WHEN real_value = 'false' THEN 1 ELSE 0 END) + SUM(CASE WHEN real_value = 'true' AND predict_value = 'false' THEN 1 ELSE 0 END) / SUM(CASE WHEN predict_value = 'true' THEN 1 ELSE 0 END)) AS f1_score,
    SUM(CASE WHEN real_value = 'false' THEN 1 ELSE 0 END) AS support
FROM your_table_name
UNION ALL
SELECT
    'True' AS class,
    SUM(CASE WHEN real_value = 'true' AND predict_value = 'true' THEN 1 ELSE 0 END) / SUM(CASE WHEN real_value = 'true' THEN 1 ELSE 0 END) AS precision,
    SUM(CASE WHEN real_value = 'true' AND predict_value = 'true' THEN 1 ELSE 0 END) / SUM(CASE WHEN predict_value = 'true' THEN 1 ELSE 0 END) AS recall,
    2 * (SUM(CASE WHEN real_value = 'true' AND predict_value = 'true' THEN 1 ELSE 0 END) / SUM(CASE WHEN real_value = 'true' THEN 1 ELSE 0 END) * SUM(CASE WHEN real_value = 'true' AND predict_value = 'true' THEN 1 ELSE 0 END) / SUM(CASE WHEN predict_value = 'true' THEN 1 ELSE 0 END)) / (SUM(CASE WHEN real_value = 'true' AND predict_value = 'true' THEN 1 ELSE 0 END) / SUM(CASE WHEN real_value = 'true' THEN 1 ELSE 0 END) + SUM(CASE WHEN real_value = 'true' AND predict_value = 'true' THEN 1 ELSE 0 END) / SUM(CASE WHEN predict_value = 'true' THEN 1 ELSE 0 END)) AS f1_score,
    SUM(CASE WHEN real_value = 'true' THEN 1 ELSE 0 END) AS support
FROM your_table_name;

请将代码中的"your_table_name"替换为您的表格名称。这个查询将生成与classification_report类似的结果,包括精确度、召回率、F1分数和支持度,分别针对"False"和"True"两个类别。

英文:

I have table with classification result of binary classification.

something like

id, predict_value, real_value
1,  true, true
2,  true, false
...

I want to get with sql classification_report, something like

   class   precision    recall  f1-score   support

   False       0.97      1.00      0.98     57241
    True       0.68      0.22      0.33      2323
accuracy       NULL      NULL      0.97     59564

Can you help me with sql query ?

答案1

得分: 2

以下可能会证明有用。

WITH classes AS (SELECT my_data.predict_value AS class
                   FROM my_data
                 UNION
                 SELECT my_data.real_value AS class
                   FROM my_data),
     t AS (SELECT c.class,
                  COUNT(*) FILTER (WHERE c.class = d.predict_value)                                              AS 支持,
                  (COUNT(*) FILTER (WHERE c.class = d.predict_value AND d.predict_value = d.real_value))::float  AS tp,
                  (COUNT(*) FILTER (WHERE c.class = d.predict_value AND d.predict_value <> d.real_value))::float AS fp,
                  (COUNT(*) FILTER (WHERE c.class <> d.predict_value AND c.class <> d.real_value))::float        AS tn,
                  (COUNT(*) FILTER (WHERE c.class <> d.predict_value AND c.class = d.real_value))::float         AS fn
             FROM classes c
               CROSS JOIN my_data d
             GROUP BY c.class),
     pr AS (SELECT t.class::text                                               AS 类别,
                   CASE t.支持 WHEN 0 THEN NULL ELSE t.tp / t.支持 END   AS 精确度,
                   CASE t.支持 WHEN 0 THEN NULL ELSE tp / (t.tp + t.fn) END AS 召回率,
                   t.支持
              FROM t
            UNION ALL
            SELECT '准确度'                          AS 类别,
                   SUM(t.tp) / SUM(t.支持)          AS 精确度,
                   SUM(t.tp) / (SUM(t.tp) + SUM(t.fn)) AS 召回率,
                   SUM(t.支持)                      AS 支持
              FROM t)
SELECT pr.类别,
       pr.精确度,
       pr.召回率,
       2 * pr.精确度 * pr.召回率 / (pr.精确度 + pr.召回率) AS "f1-score",
       pr.支持
  FROM pr
  ORDER BY pr.类别;
英文:

The following might prove useful.

WITH classes AS (SELECT my_data.predict_value AS class
                   FROM my_data
                 UNION
                 SELECT my_data.real_value AS class
                   FROM my_data),
     t AS (SELECT c.class,
                  COUNT(*) FILTER (WHERE c.class = d.predict_value)                                              AS SUPPORT,
                  (COUNT(*) FILTER (WHERE c.class = d.predict_value AND d.predict_value = d.real_value))::float  AS tp,
                  (COUNT(*) FILTER (WHERE c.class = d.predict_value AND d.predict_value &lt;&gt; d.real_value))::float AS fp,
                  (COUNT(*) FILTER (WHERE c.class &lt;&gt; d.predict_value AND c.class &lt;&gt; d.real_value))::float        AS tn,
                  (COUNT(*) FILTER (WHERE c.class &lt;&gt; d.predict_value AND c.class = d.real_value))::float         AS fn
             FROM classes c
               CROSS JOIN my_data d
             GROUP BY c.class),
     pr AS (SELECT t.class::text                                               AS class,
                   CASE t.support WHEN 0 THEN NULL ELSE t.tp / t.support END   AS precision,
                   CASE t.support WHEN 0 THEN NULL ELSE tp / (t.tp + t.fn) END AS recall,
                   t.support
              FROM t
            UNION ALL
            SELECT &#39;Accuracy&#39;                          AS class,
                   SUM(t.tp) / SUM(t.support)          AS precision,
                   SUM(t.tp) / (SUM(t.tp) + SUM(t.fn)) AS recall,
                   SUM(t.support)                      AS support
              FROM t)
SELECT pr.class,
       pr.precision,
       pr.recall,
       2 * pr.precision * pr.recall / (pr.precision + pr.recall) AS &quot;f1-score&quot;,
       pr.support
  FROM pr
  ORDER BY pr.class;

This query works for any positive number of classes, not just binary classification.

答案2

得分: 1

I have next ugly sql as solution

with _tmp as (select 'accuracy' as class,
                     null       as precision,
                     null       as recall,
                     count(*)   as support
              from my_data
              UNION
              select 'True'                                                          as class,
                     (count(*) filter ( where predict_value = True and real_value = True ))::float
                         /
                     (count(*) filter ( where predict_value = True))::numeric(12, 6) as precision,
                     (count(*) filter ( where predict_value = True and real_value = True ))::float
                         /
                     (
                                     count(*) filter ( where predict_value = FALSE and real_value = True)
                             +
                                     count(*) filter ( where predict_value = True and real_value = True )
                         )::float                                                    as recall,
                     null                                                            as f1_score,
                     count(*) filter ( where predict_value = True)                   as support
              from my_data
              Union
              select 'False'                                                          as class,
                     (count(*) filter ( where predict_value = FALSE and real_value = FALSE ))::float
                         /
                     (count(*) filter ( where predict_value = FALSE))::numeric(12, 6) as precision,
                     (count(*) filter ( where predict_value = FALSE and real_value = FALSE ))::float
                         /
                     (
                                     count(*) filter ( where predict_value = True and real_value = FALSE)
                             +
                                     count(*) filter ( where predict_value = FALSE and real_value = FALSE )
                         )::float                                                     as recall,
                     null                                                             as f1_score,
                     count(*) filter ( where fixed_predict = FALSE)                   as support
              from my_data)
select "class",
       precision::numeric(12, 3),
       recall::numeric(12, 3),
       (2 * precision * recall / (precision + recall))::numeric(12, 3) as f1_score,
       support
from _tmp
order by support
英文:

I have next ugly sql as soltion

with _tmp as (select &#39;accuracy&#39; as class,
                     null       as pricission,
                     null       as recall,
                     count(*)   as support
              from my_data
              UNION
              select &#39;True&#39;                                                          as class,
                     (count(*) filter ( where predict_value = True and real_value = True ))::float
                         /
                     (count(*) filter ( where predict_value = True))::numeric(12, 6) as pricission,
                     (count(*) filter ( where predict_value = True and real_value = True ))::float
                         /
                     (
                                     count(*) filter ( where predict_value = FALSE and real_value = True)
                             +
                                     count(*) filter ( where predict_value = True and real_value = True )
                         )::float                                                    as recall,
                     null                                                            as f1_score,
                     count(*) filter ( where predict_value = True)                   as support
              from my_data
              Union
              select &#39;False&#39;                                                          as class,
                     (count(*) filter ( where predict_value = FALSE and real_value = FALSE ))::float
                         /
                     (count(*) filter ( where predict_value = FALSE))::numeric(12, 6) as pricission,
                     (count(*) filter ( where predict_value = FALSE and real_value = FALSE ))::float
                         /
                     (
                                     count(*) filter ( where predict_value = True and real_value = FALSE)
                             +
                                     count(*) filter ( where predict_value = FALSE and real_value = FALSE )
                         )::float                                                     as recall,
                     null                                                             as f1_score,
                     count(*) filter ( where fixed_predict = FALSE)                   as support
              from my_data)
select &quot;class&quot;,
       pricission::numeric(12, 3),
       recall::numeric(12, 3),
       (2 * pricission * recall / (pricission + recall))::numeric(12, 3) as f1_score,
       support
from _tmp
order by support

huangapple
  • 本文由 发表于 2023年5月14日 05:14:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76244904.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定