【问题标题】:Smoothing Categorical Output平滑分类输出
【发布时间】:2020-09-18 16:57:39
【问题描述】:

我有一个从奶牛行为检测模型获得的输出列表。即使在奶牛产蛋的视频中,它通常也会识别为站立,反之亦然。在每个视频帧中,模型给出一个分类结果,我们将其附加到一个列表中。假设在 20 帧之后,我们有一系列输出如下 -

behavious_cow_1 = ["stand","stand","stand","stand","lying", "stand","stand", "eating", "stand","stand","stand","stand","lying""stand","stand","stand","stand","stand","stand","lying"]

在 20 个分类结果中,我们有 4 个错误分类; 3个谎言,1个吃东西。然而,这头牛一直坐在一个地方。如果列表只包含像 - 1,2,3...这样的数值,我会选择移动平均线来改变错误分类。是否有任何可以平滑分类输出的 Scipy、Pandas、Numpy 函数?我正在考虑使用前 3 个和后 3 个值来确定当前类别。

【问题讨论】:

    标签: python pandas numpy math scipy


    【解决方案1】:

    我使用了以下解决方案-

    import scipy.stats
    window_length = 7
    behave = ["stand","stand","stand","stand","lying","lying", "eating"]
    most_freq_val = lambda x: scipy.stats.mode(x)[0][0]
    smoothed = [most_freq_val(behave[i:i+window_length]) for i in range(0,len(behave)-window_length+1)]
    

    我尝试了 Hugolmn 发布的解决方案,但它在某个时候崩溃了。在滚动模式下,窗口宽度由用户提供(此处为 7)。在一定宽度下,如果多个值出现在相同的次数中,则代码不起作用。这更像是 - 你试图找到一个列表的统计模式(最常见的项目),但它得到了多个具有相同最高频率的项目。

    【讨论】:

      【解决方案2】:

      我自己很惊讶 mode() 之类的函数在 pandas 的滚动窗口中不起作用。但是,我仍然找到了解决您问题的好方法

      首先,创建一个具有分类数据类型的熊猫系列:

      df = pd.Series(sample, dtype='category')
      

      现在您可以看到 df.cat.categories 返回数据中的类别列表,而 df.cat.codes 返回与它们关联的代码。我们可以使用后者来应用宽度为 7 的滚动模式(前 3 个,值,后 3 个):

      df.cat.codes
      0     3
      1     3
      2     3
      3     3
      4     1
      5     3
      6     3
      7     0
      8     3
      9     3
      10    3
      11    3
      12    2
      13    3
      14    3
      15    3
      16    3
      17    3
      18    1
      dtype: int8
      
      df.cat.codes.rolling(7, center=True, min_periods=0).apply(lambda x: x.mode())
      0     3.0
      1     3.0
      2     3.0
      3     3.0
      4     3.0
      5     3.0
      6     3.0
      7     3.0
      8     3.0
      9     3.0
      10    3.0
      11    3.0
      12    3.0
      13    3.0
      14    3.0
      15    3.0
      16    3.0
      17    3.0
      18    3.0
      dtype: float64
      

      最后,您可以映射代码以获取字符串:

      (df.cat.codes
        .rolling(7, center=True, min_periods=0)
        .apply(lambda x: x.mode())
        .map(dict(enumerate(df.cat.categories)))
      )
      0     stand
      1     stand
      2     stand
      3     stand
      4     stand
      5     stand
      6     stand
      7     stand
      8     stand
      9     stand
      10    stand
      11    stand
      12    stand
      13    stand
      14    stand
      15    stand
      16    stand
      17    stand
      18    stand
      dtype: object
      

      你去吧!在对他们的代码应用滚动模式后,您恢复了您的字符串!

      【讨论】:

        猜你喜欢
        • 2022-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-13
        • 2018-07-29
        • 2021-09-30
        • 2017-10-31
        • 1970-01-01
        相关资源
        最近更新 更多