如何使用pandas/numpy/python math库计算平均绝对误差(MAE)和平均有符号误差(MSE)?

6
我有一个类似下面的数据集。在这个数据集中,有不同颜色的温度计,并给出了“True”或参考温度,以及它们根据某些测量方法“Method 1”和“Method 2”的测量差异。
我遇到了计算两个重要参数的困难,它们是均值绝对误差(MAE)和均值有符号误差(MSE)。我想使用每种方法的非NaN值并打印结果。
我已经可以返回一个两列索引和总和的系列,但问题在于在这种情况下我需要除以求和的方法值数量,这取决于一行中有多少NaN值。而且我不想因为整行有NaN值就跳过整行。
编号 日期 温度计颜色 真实温度 方法 1 方法 2
0 2021 年 1 月 1 日 红色 0.2 0.2 0.5
1 2021 年 1 月 1 日 红色 0.6 0.6 0.3
2 2021 年 1 月 1 日 红色 0.4 0.6 0.23
3 2021 年 1 月 1 日 绿色 0.2 0.4 NaN
4 2021 年 1 月 1 日 绿色 1 1 0.23
5 2021 年 1 月 1 日 黄色 0.4 0.4 0.32
6 2021 年 1 月 1 日 黄色 0.1 NaN 0.4
7 2021 年 1 月 1 日 黄色 1.3 0.5 0.54
8 2021 年 1 月 1 日 黄色 1.5 0.5 0.43
9 2021 年 1 月 1 日 import numpy as np import pandas as pd import matplotlib.pyplot as plt plt.style.use('default' data = pd.read_csv('data.txt', index_col=0) data data["M1_ABS_Error"]= abs(data["True_Temperature"]-data["Method_1"]) data["M2_ABS_Error"]= abs(data["True_Temperature"]-data["Method_2"]) MAE_Series=data[['Name', 'M1_ABS_Error', 'M2_ABS_Error' ]] MAE_Series.sum(axis=1, skipna=True)
目前输出的结果是这样的,没有指定它属于哪个颜色的温度计,我希望以一种易于与其所属关联的方式打印输出。 此外,正如我所提到的,这还没有考虑如何按给定行中值/方法的数量进行除法以考虑 NaN。
0       4.94
1       3.03
2      11.88
3       3.28
4       8.14
5       7.80
6       2.76
7       2.71

我希望您能帮忙解答这个问题。谢谢!

2个回答

4

编辑

我想我现在明白了,如果这是您想要的,请让我知道。

MAE:

df['MAE'] = df[['M1_ABS_Error','M2_ABS_Error']].mean(axis = 1)
df

产生

    date      Thermometer      True_Temperature    Method_1    Method_2    M1_ABS_Error    M2_ABS_Error    MAE
--  --------  -------------  ------------------  ----------  ----------  --------------  --------------  -----
 0  1/1/2021  red                           0.2         0.2        0.5              0              0.3   0.15
 1  1/1/2021  red                           0.6         0.6        0.3              0              0.3   0.15
 2  1/1/2021  red                           0.4         0.6        0.23             0.2            0.17  0.185
 3  1/1/2021  green                         0.2         0.4      nan                0.2          nan     0.2
 4  1/1/2021  green                         1           1          0.23             0              0.77  0.385
 5  1/1/2021  yellow                        0.4         0.4        0.32             0              0.08  0.04
 6  1/1/2021  yellow                        0.1       nan          0.4            nan              0.3   0.3
 7  1/1/2021  yellow                        1.3         0.5        0.54             0.8            0.76  0.78
 8  1/1/2021  yellow                        1.5         0.5        0.43             1              1.07  1.035
 9  1/1/2021  yellow                        1.5         0.5        0.43             1              1.07  1.035
10  1/1/2021  blue                          0.4         0.3      nan                0.1          nan     0.1
11  1/1/2021  blue                          0.8         0.2        0.11             0.6            0.69  0.645

"并且对于 MSE (带符号误差)"
df["MSE"]= df[['Method_1','Method_2']].mean(axis = 1)- df['True_Temperature']

产生,制造
    date      Thermometer      True_Temperature    Method_1    Method_2    M1_ABS_Error    M2_ABS_Error    MAE     MSE
--  --------  -------------  ------------------  ----------  ----------  --------------  --------------  -----  ------
 0  1/1/2021  red                           0.2         0.2        0.5              0              0.3   0.15    0.15
 1  1/1/2021  red                           0.6         0.6        0.3              0              0.3   0.15   -0.15
 2  1/1/2021  red                           0.4         0.6        0.23             0.2            0.17  0.185   0.015
 3  1/1/2021  green                         0.2         0.4      nan                0.2          nan     0.2     0.2
 4  1/1/2021  green                         1           1          0.23             0              0.77  0.385  -0.385
 5  1/1/2021  yellow                        0.4         0.4        0.32             0              0.08  0.04   -0.04
 6  1/1/2021  yellow                        0.1       nan          0.4            nan              0.3   0.3     0.3
 7  1/1/2021  yellow                        1.3         0.5        0.54             0.8            0.76  0.78   -0.78
 8  1/1/2021  yellow                        1.5         0.5        0.43             1              1.07  1.035  -1.035
 9  1/1/2021  yellow                        1.5         0.5        0.43             1              1.07  1.035  -1.035
10  1/1/2021  blue                          0.4         0.3      nan                0.1          nan     0.1    -0.1
11  1/1/2021  blue                          0.8         0.2        0.11             0.6            0.69  0.645  -0.645

原始回答

不太清楚您想要什么,但是有些猜测,您是想要这个吗?如果您按颜色进行groupby,并在每个组中应用mean到`ABS列,则可以得到以下结果。

data.groupby('Thermometer', sort = False)[['M1_ABS_Error','M2_ABS_Error']].mean()

你得到这个。

        M1_ABS_Error    M2_ABS_Error
Thermometer     
red     0.066667    0.256667
green   0.100000    0.770000
yellow  0.700000    0.656000
blue    0.350000    0.690000

例如,在这里,左上角的第一个数字“0.066667是那些红色温度计的M1_ABS_Error列的平均值。类似于其他情况,每个颜色/列中的NaN将被跳过。
要获取MSE(通常表示均方误差,因此我认为这是您想要的),您可以执行以下操作。
import numpy as np
data["M1_Sqr_Error"]= (data["True_Temperature"]-data["Method_1"])**2
data["M2_Sqr_Error"]= (data["True_Temperature"]-data["Method_2"])**2
data.groupby('Thermometer', sort = False)[['M1_Error','M2_Error']].apply(lambda v: np.sqrt(np.mean(v)))

获取


        M1_Error    M2_Error
Thermometer     
red     0.115470    0.263881
green   0.141421    0.770000
yellow  0.812404    0.769909
blue    0.430116    0.690000

谢谢你的回答!我正在寻找的是平均绝对误差(MAE),它是所有绝对误差的平均值。基本上,您需要:
  1. 找到所有的绝对误差,xi - x。
  2. 把它们全部加起来。
  3. 除以错误数。例如,如果您有10个测量值,则除以10。
理想情况下,我希望能够按索引为每行获得一个MAE值。不仅仅是“全部红色”,而是每个单独的颜色。我遇到的问题是如何分割每行的绝对误差总和,因为某些行中的'Method'列中有NaN。因此,在这种情况下,有些行可能需要除以2,而其他行可能需要除以1。
- Joseph Romo
至于MSE,我指的是平均有符号误差或平均有符号差。https://wiki2.org/en/Mean_signed_deviation - Joseph Romo
非常感谢!这正是我想要的。非常详尽和易于理解的解释。@piterbarg - Joseph Romo

0

我宁愿使用来自库(例如scikit-learn)的现成、经过测试和正确定义的函数。注意:我在这里提供的答案是针对MAE(平均绝对误差)和MSE(均方误差)而言,而不是很少使用的平均符号误差。

import pandas as pd
from sklearn.metrics import mean_absolute_error, mean_squared_error

data = {"predicted": [11.3, 22.2, 51.4], "true": [10.1, 25.2, 60.3]}
df = pd.DataFrame(data)

mae = mean_absolute_error(data["predicted"], data["true"])
mse = mean_squared_error(data["predicted"], data["true"], squared=True)

print(f"mae:{round(mae,2)} mse:{round(mse,2)}")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接