gpt4 book ai didi

python - 将 pandas 数据框中的多类训练示例(行)过度采样和欠采样到指定值

转载 作者:行者123 更新时间:2023-12-05 05:58:40 26 4
gpt4 key购买 nike

我想让多类 Pandas 数据框在训练时更加平衡。我的训练集的简化版本如下所示:

不平衡的数据帧:0、1 和 2 类的计数分别为 7、3 和 1

   animal  class
0 dog1 0
1 dog2 0
2 dog3 0
3 dog4 0
4 dog5 0
5 dog6 0
6 dog7 0
7 cat1 1
8 cat2 1
9 cat3 1
10 fish1 2

我用代码做了这个:

import pandas as pd    
data = {'animal': ['dog1', 'dog2', 'dog3', 'dog4','dog5', 'dog6', 'dog7', 'cat1','cat2', 'cat3', 'fish1'], 'class': [0,0,0,0,0,0,0,1,1,1,2]}
df = pd.DataFrame(data)

现在我想随机对多数类进行欠采样,并随机对少数类进行过采样以达到每个类的指定值,以获得更平衡的数据框。

问题是,我可以在网上找到的所有 pandas 教程或 stackoverflow 上有关该主题的其他问题都涉及随机对少数类进行过采样以达到多数类的水平(例如:Duplicating training examples to handle class imbalance in a pandas data frame)或随机欠采样多数类到少数类的水平。

由于我面临极度不平衡,我无法使多数类(class)的人数等于少数类(class)的人数。因此,我能找到的这些代码片段通常对我不起作用。理想情况下,我将能够指定每个类的样本的确切数量,然后通过过采样或欠采样生成这些样本(取决于我为该类指定的数量和该类包含的样本数)。

例如,

如果我指定:

  • counts_0 = 5(原来是 7,所以意味着随机采样有 2 个样本),
  • counts_1 = 4(原来是 3,所以意味着用 1 个样本随机过度采样),
  • counts_2 = 3(1 表示随机过度采样 2 个样本)

我想成为这样的人:

更平衡的数据框:0、1 和 2 类的计数分别为 5、4 和 3

   animal  class
0 dog2 0
1 dog3 0
2 dog5 0
3 dog6 0
4 dog7 0
5 cat1 1
6 cat2 1
7 cat3 1
8 cat2 1
9 fish1 2
10 fish1 2
11 fish1 2

解决这个问题的最佳方法是什么?

最佳答案

groupby.sample不允许 n 大于组大小,如果 replace 不是 True 但替换为 True 意味着这种替换甚至会发生在本可以被下采样的组中。

让我们尝试使用 groupby.apply + sample并有条件地为每个组启用 replace。创建一个将每个类映射到样本数量的字典,并使用条件逻辑来确定是否有替换:

sample_amounts = {0: 5, 1: 4, 2: 3}

s = (
df.groupby('class').apply(lambda g: g.sample(
# lookup number of samples to take
n=sample_amounts[g.name],
# enable replacement if len is less than number of samples expected
replace=len(g) < sample_amounts[g.name]
))
)

:

         animal  class
class
0 5 dog6 0
3 dog4 0
6 dog7 0
4 dog5 0
2 dog3 0
1 9 cat3 1
8 cat2 1
7 cat1 1
8 cat2 1
2 10 fish1 2
10 fish1 2
10 fish1 2

droplevel可用于保留初始索引(如果重要):

sample_amounts = {0: 5, 1: 4, 2: 3}

s = (
df.groupby('class').apply(lambda g: g.sample(
n=sample_amounts[g.name],
replace=len(g) < sample_amounts[g.name]
))
.droplevel(0)
)

:

   animal  class
6 dog7 0
3 dog4 0
2 dog3 0
4 dog5 0
1 dog2 0
7 cat1 1
8 cat2 1
8 cat2 1
8 cat2 1
10 fish1 2
10 fish1 2
10 fish1 2

reset_index如果索引不重要,可以使用:

sample_amounts = {0: 5, 1: 4, 2: 3}

s = (
df.groupby('class').apply(lambda g: g.sample(
n=sample_amounts[g.name],
replace=len(g) < sample_amounts[g.name]
))
.reset_index(drop=True)
)

:

   animal  class
0 dog1 0
1 dog2 0
2 dog4 0
3 dog5 0
4 dog3 0
5 cat3 1
6 cat2 1
7 cat1 1
8 cat3 1
9 fish1 2
10 fish1 2
11 fish1 2

关于python - 将 pandas 数据框中的多类训练示例(行)过度采样和欠采样到指定值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68413104/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com