【问题标题】:Python Dataframe: Calculating Confidence or Prediction Intervals Using Groupby on One ColumnPython Dataframe:在一列上使用 Groupby 计算置信区间或预测区间
【发布时间】:2018-06-03 17:35:25
【问题描述】:

我有一个如下表:

Type    Actual  Predicted
A       4       3
A       10      18
A       13      11
B       3       10
B       4       2
B       8       33
C       20      17
C       40      33
C       87      80
C       32      30

我想计算每种类型的 R^2 和 RMSE。执行此操作的代码如下:

import numpy as np
import pandas as pd
from sklearn.metrics import r2_score, mean_squared_error

def r2_rmse( g ):
    r2 = r2_score( g['Actual'], g['Predicted'] )
    rmse = np.sqrt( mean_squared_error( g['Actual'], g['Predicted'] ) )
    return pd.Series( dict(  r2 = r2, rmse = rmse ) )

your_df.groupby( 'Type' ).apply( r2_rmse ).reset_index()

样本输出表(值是假设的):

Type    R^2     RMSE    
A       0.66    4   
B       1.00    6   
C       0.03    1

上面的代码工作并给了我想要的输出。但现在我想在类型级别的表中添加置信/预测区间。我确实在互联网上搜索了如何在没有运气的情况下做到这一点。

概念问题:如果我想要以 95% 的置信度捕获实际值的值范围,我是在实际列还是预测列上运行置信区间?

下面是我想要的样表:

Type    Conf_Int_90%  Conf_Int_80%
    A    (21, 100)       (5, 55)
    B    (10, 46)        (3, 14)
    C    (1, 19)         (12, 19)

我感觉置信区间代码是这样的:

st.t.interval(0.95, len(a)-1, loc=np.mean(a), scale=st.sem(a)) BUT ... 

我将哪些特定代码合并到现有代码中(如上所示),以便获得我想要的表格输出?

【问题讨论】:

    标签: python pandas numpy scikit-learn intervals


    【解决方案1】:

    尝试跟随,据我了解,置信区间应在预测列中操作。希望对你有帮助:)

    import numpy as np
    import pandas as pd
    import scipy.stats as st
    from sklearn.metrics import r2_score, mean_squared_error
    
    def r2_rmse_interval(g):
        r2 = r2_score( g['Actual'], g['Predicted'] )
        rmse = np.sqrt( mean_squared_error( g['Actual'], g['Predicted'] ))
        st_interval = st.t.interval(0.95, len(g) -1, loc=np.mean(g.Predicted), scale=st.sem(g.Predicted))
        return pd.Series( dict(  r2 = r2, rmse = rmse, st_interval = st_interval) )
    
    
    df = pd.DataFrame({'Type': ['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C', 'C'],
                   'Actual': [4, 10, 13, 3, 4, 8, 20, 40, 87, 32],
                   'Predicted': [3, 18, 11, 10, 2, 33, 17, 33, 80, 30]}, 
                    columns=['Type', 'Actual', 'Predicted'])
    
    df.groupby( 'Type' ).apply( r2_rmse_interval ).reset_index()
    

    【讨论】:

    • 不幸的是,我的所有值都以 st_interval 的 (nan, nan) 形式出现
    • 嗨,我可以知道您是如何尝试上述代码的吗?我已经测试过了,它可以返回你想要的结果。
    • 我明白了!我这边出错了……非常感谢您
    • 我可以在实际领域运行 CI 吗?原因是我的预测值给了我,并且同一类型的每个“预测”值都是相同的值
    • 嗨,据我了解,CI 适用于预测值。但如果你想返回实际值,只需将代码更改为: st_interval = st.t.interval(0.95, len(g) -1, loc=np.mean(g.Actual), scale=st.sem(g .实际))
    【解决方案2】:

    使用standard formula for 95% CI

    sample mean +/- 1.96 * std.err

    您可以使用apply 一次性完成所有操作:

    def stats(g):
        r2 = r2_score(g.Actual, g.Predicted)
        rmse = np.sqrt(mean_squared_error(g.Actual, g.Predicted))
        ci95_hi = g.Predicted.mean() + g.Predicted.sem() * 1.96
        ci95_lo = g.Predicted.mean() - g.Predicted.sem() * 1.96
        return r2, rmse,(ci95_lo, ci95_hi)
    
    df.groupby("Type").apply(stats)
    

    【讨论】:

    • 代码运行了!但是我的 ci95_hi 值都等于我的 ci95_lo 值……这怎么可能?
    • 不确定,当我使用您的示例数据运行此代码时,它们会有所不同。例如,A 的 CI 是 (2.17, 19.16)。您确定您使用的是+-
    • 啊,想通了……我对相同类型的预测值是相同的值;我实际上并没有进行预测......这些值是作为预测提供给我的
    • 非常感谢您的代码,非常感谢
    • 鉴于上述情况,我可以在 Actual 字段上运行 CI 吗?
    猜你喜欢
    • 2021-01-24
    • 1970-01-01
    • 1970-01-01
    • 2021-07-26
    • 2018-12-21
    • 2013-07-07
    • 2022-01-22
    • 2021-05-15
    • 2018-02-05
    相关资源
    最近更新 更多