【问题标题】:The consistency ratio of the upward, downward, and equal directions of y_true and y_predy_true和y_pred的向上、向下、相等方向的一致性比
【发布时间】:2022-11-11 09:08:40
【问题描述】:

假设我们有一个数据框df

          date  y_true  y_pred1  y_pred2
0    2017-1-31    6.42    -2.35    15.57
1    2017-2-28   -2.35    15.57     6.64
2    2017-3-31   15.57     6.64     7.61
3    2017-4-30    6.64     7.61    10.28
4    2017-5-31    7.61     7.61     6.34
5    2017-6-30   10.28     6.34     4.88
6    2017-7-31    6.34     4.88     7.91
7    2017-8-31    6.34     7.91     6.26
8    2017-9-30    7.91     6.26    11.51
9   2017-10-31    6.26    11.51    10.73
10  2017-11-30   11.51    10.73    10.65
11  2017-12-31   10.73    10.65    32.05

我想计算比例向上、向下和相等的一致性连续两个月的两列数据,并将其作为时间序列预测结果的评价指标。本月与上月比率的方向:向上表示当前月份的值减去上个月的值是正数,类似地,equal 分别表示负数和 0。

我使用以下函数和代码计算了样本数据的结果,请注意,我们在计算最终比率时不包括黄色行,因为这些行的y_true_dirnull0

def cal_arrays_direction(value):
    if value > 0:
        return 1
    elif value < 0:
        return -1
    elif value == 0:
        return 0
    else:
        return np.NaN
    
df['y_true_diff'] = df['y_true'].diff(1).map(cal_arrays_direction)
df['y_pred1_diff'] = df['y_pred1'].diff(1).map(cal_arrays_direction)
df['y_pred2_diff'] = df['y_pred2'].diff(1).map(cal_arrays_direction)

df['y_true_y_pred1'] = np.where((df['y_true_diff'] == df['y_pred1_diff']), 1, 0)
df['y_true_y_pred2'] = np.where((df['y_true_diff'] == df['y_pred2_diff']), 1, 0)

dir_acc_y_true_pred1 = df['y_true_y_pred1'].value_counts()[1] / (df['y_true_diff'].value_counts()[-1] 
+ df['y_true_diff'].value_counts()[1])
print(dir_acc_y_true_pred1)

dir_acc_y_true_pred2 = df['y_true_y_pred2'].value_counts()[1] / (df['y_true_diff'].value_counts()[-1] 
 + df['y_true_diff'].value_counts()[1])
print(dir_acc_y_true_pred2)

出去:

0.2
0.4

但是我想知道如何将其转换为函数(类似于sklearn 中的MSERMSE 等)以使其更易于使用,谢谢!

def direction_consistency_acc(y_true, y_pred):
     ...
     return dir_acc_ratio

更新1:

Traceback (most recent call last):
  File "C:\Users\LSTM\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\indexes\base.py", line 3803, in get_loc
    return self._engine.get_loc(casted_key)
  File "pandas\_libs\index.pyx", line 138, in pandas._libs.index.IndexEngine.get_loc
  File "pandas\_libs\index.pyx", line 165, in pandas._libs.index.IndexEngine.get_loc
  File "pandas\_libs\hashtable_class_helper.pxi", line 1577, in pandas._libs.hashtable.Float64HashTable.get_item
  File "pandas\_libs\hashtable_class_helper.pxi", line 1587, in pandas._libs.hashtable.Float64HashTable.get_item
KeyError: 1.0

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "..\code\stacked model_2022-11-08.py", line 353, in <module>
    run_model(df)
  File "..\code\stacked model_2022-11-08.py", line 258, in run_model
    out1 = direction_consistency_acc(preds['y_true'], preds[['y_pred1','y_pred2',
  File "..\code\stacked model_2022-11-08.py", line 245, in direction_consistency_acc
    dir_acc_y_true_pred = preds[f'y_true_{col}'].eq(1).sum() / (s[-1] + s[1])
  File "C:\Users\LSTM\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\series.py", line 981, in __getitem__
    return self._get_value(key)
  File "C:\Users\LSTM\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\series.py", line 1089, in _get_value
    loc = self.index.get_loc(label)
  File "C:\Users\LSTM\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\indexes\base.py", line 3805, in get_loc
    raise KeyError(key) from err
KeyError: 1

Process finished with exit code 1

更新 2:

我在运行direction_consistency_acc(df['y_true'], df[['y_pred1','y_pred2']])print(df['y_true_diff'].value_counts())

...
2021-05-31
-1.0    4
 1.0    2
Name: y_true_diff, dtype: int64
2021-06-30
-1.0    5
 1.0    1
Name: y_true_diff, dtype: int64
2021-07-31
Traceback (most recent call last):
  File "C:\Users\LSTM\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\indexes\base.py", line 3803, in get_loc
-1.0    6
Name: y_true_diff, dtype: int64
    return self._engine.get_loc(casted_key)
  File "pandas\_libs\index.pyx", line 138, in pandas._libs.index.IndexEngine.get_loc
  File "pandas\_libs\index.pyx", line 165, in pandas._libs.index.IndexEngine.get_loc
  File "pandas\_libs\hashtable_class_helper.pxi", line 1577, in pandas._libs.hashtable.Float64HashTable.get_item
  File "pandas\_libs\hashtable_class_helper.pxi", line 1587, in pandas._libs.hashtable.Float64HashTable.get_item
KeyError: 1.0

The above exception was the direct cause of the following exception:

    Traceback (most recent call last):
      File "..\code\stacked model_2022-11-08.py", line 353, in <module>
        run_model(df)
      File "..\code\stacked model_2022-11-08.py", line 258, in run_model
        out1 = direction_consistency_acc(preds['y_true'], preds[['y_pred1','y_pred2',
      File "..\code\stacked model_2022-11-08.py", line 245, in direction_consistency_acc
        dir_acc_y_true_pred = preds[f'y_true_{col}'].eq(1).sum() / (s[-1] + s[1])
      File "C:\Users\LSTM\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\series.py", line 981, in __getitem__
        return self._get_value(key)
      File "C:\Users\LSTM\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\series.py", line 1089, in _get_value
        loc = self.index.get_loc(label)
      File "C:\Users\LSTM\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\indexes\base.py", line 3805, in get_loc
        raise KeyError(key) from err
    KeyError: 1

【问题讨论】:

    标签: python-3.x pandas dataframe numpy


    【解决方案1】:

    您可以创建自定义函数,而不是自定义函数使用 numpy.sign 而不是 .value_counts()[1] 比较 1 和计数 Trues 通过 sum

    #y_true - Series, y_pred - DataFrame
    def direction_consistency_acc(y_true, y_pred):
        df['y_true_diff'] = np.sign(y_true.diff(1))
        s = df['y_true_diff'].value_counts()    
    
        out = []    
        for col in y_pred.columns:
            df[f'y_{col}_diff'] = np.sign(df[col].diff(1))
            df[f'y_true_{col}'] = np.where((df['y_true_diff'] == df[f'y_{col}_diff']), 1, 0)
            dir_acc_y_true_pred = df[f'y_true_{col}'].eq(1).sum() / (s[-1] + s[1])
            out.append(dir_acc_y_true_pred)
            
        return out
            
    out = direction_consistency_acc(df['y_true'], df[['y_pred1','y_pred2']])
    print(out)
    [0.2, 0.4]
    

    没有新列的替代方案:

    #y_true - Series, y_pred - DataFrame
    def direction_consistency_acc(y_true, y_pred):
        y_true_diff = np.sign(y_true.diff(1))
        s = y_true_diff.value_counts()    
    
        out = []    
        for col in y_pred.columns:
            y_true = y_true_diff == np.sign(df[col].diff(1))
            dir_acc_y_true_pred = y_true.eq(1).sum() / (s[-1] + s[1])
            out.append(dir_acc_y_true_pred)
            
        return out
            
    out = direction_consistency_acc(df['y_true'], df[['y_pred1','y_pred2']])
    print(out)
    [0.2, 0.4]
    

    【讨论】:

    • 感谢分享这两个很棒的解决方案,比我的更高效、更简洁。
    • 你好@jezrael,我用新数据进行了测试,它引发了一个错误:KeyError: 1(我在这个问题的末尾更新了完整的错误),关于这个问题有什么想法吗? :)
    • @ahbon - 可能的列名是浮点数 1.0 并且预期是 1 吗?
    • 我查了一下,没有列名是11.0
    • @ahbon - 什么是 s 失败的解决方案?似乎索引中没有1 值(因为y_true_diff 中没有1),所以引发错误。
    【解决方案2】:

    我对这个问题的更新答案:

    def cal_arrays_direction(value):
        if value > 0:
            return 1
        elif value < 0:
            return -1
        elif value == 0:
            return 0
        else:
            return np.NaN
    
    
    def direction_consistency_acc(y_true, y_pred):
        df['y_true_diff'] = y_true.diff(1).map(cal_arrays_direction)
        df['y_pred_diff'] = y_pred.diff(1).map(cal_arrays_direction)
        df['y_true_pred_consis'] = np.where((df['y_true_diff'] == df['y_pred_diff']), 1, 0)
        dir_acc_ratio = df['y_true_pred_consis'].value_counts()[1] / (df['y_true_diff'].value_counts()[-1] 
        + df['y_true_diff'].value_counts()[1])
        return dir_acc_ratio
    
    direction_consistency_acc(df['y_true'], df['y_pred1'])
    

    出去:

    0.2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-16
      • 1970-01-01
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-20
      • 1970-01-01
      相关资源
      最近更新 更多