首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >sklearn.datasets.make_classification无法生成平衡类

sklearn.datasets.make_classification无法生成平衡类
EN

Stack Overflow用户
提问于 2018-09-10 09:17:19
回答 1查看 1.4K关注 0票数 1

我正在尝试使用sklearn库中的make_classification来生成分类任务的数据,并且我希望每个类都有精确的4个样本。

如果类数小于19,则行为正常。

代码语言:javascript
复制
from sklearn.datasets import make_blobs, make_classification
import numpy as np
data = make_classification(n_samples=76, n_features=5, n_informative=5, n_redundant=0, n_repeated=0, 
                           n_classes=19, n_clusters_per_class=1, weights=None, flip_y=0, class_sep=1.0, 
                           shuffle=False, random_state=101)
print(data[1])
[ 0  0  0  0  1  1  1  1  2  2  2  2  3  3  3  3  4  4  4  4  5  5  5  5
  6  6  6  6  7  7  7  7  8  8  8  8  9  9  9  9 10 10 10 10 11 11 11 11
 12 12 12 12 13 13 13 13 14 14 14 14 15 15 15 15 16 16 16 16 17 17 17 17
 18 18 18 18]

但是,如果类数等于或超过20个,则第一类将有5个样本,最后一个类将只有3个样本,这是不平衡的。

代码语言:javascript
复制
data = make_classification(n_samples=80, n_features=5, n_informative=5, n_redundant=0, n_repeated=0, 
                           n_classes=20, n_clusters_per_class=1, weights=None, flip_y=0, class_sep=1.0, 
                           shuffle=False, random_state=101)
print(data[1])
[ 0  0  0  0  0  1  1  1  1  2  2  2  2  3  3  3  3  4  4  4  4  5  5  5
  5  6  6  6  6  7  7  7  7  8  8  8  8  9  9  9  9 10 10 10 10 11 11 11
 11 12 12 12 12 13 13 13 13 14 14 14 14 15 15 15 15 16 16 16 16 17 17 17
 17 18 18 18 18 19 19 19]

在检查文档时,我发现weight参数控制着classes的比例。

weights:浮标列表或无列表(default=None) 分配给每个类的样本比例。如果没有,那么类是平衡的。注意,如果len(权重) == n_classes - 1,那么将自动推断最后一个类的权重。如果权重之和超过1,则可以返回超过n_samples的样本。

因此,我尝试使用以下代码显式地输入比例。

代码语言:javascript
复制
data = make_classification(n_samples=80, n_features=5, n_informative=5, n_redundant=0, n_repeated=0, 
                           n_classes=20, n_clusters_per_class=1, weights=list(np.ones(20)), flip_y=0, class_sep=1.0, 
                           shuffle=False, random_state=101)
print(data[1])
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0]

然而,生成的类是完全错误的。

我不知道为什么这个函数是这样的。当n_classes大于或等于20时,如何确保平衡类?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-10 09:43:19

虽然它没有明确提到,而且令人困惑,但参数weights需要样本的“比例”。它不会自动将数字转换成比例。

因此,如果总样本数= 80,并且要将40个样本分配到第1类,则该比例将变为0.5

但是,你提供的比例如下:

代码语言:javascript
复制
[1.0, 1.0, 1.0, 1.0,.................., 1.0, 1.0, 1.0, 1.0]

这是错误的根源。该方法对于第一类(在您的情况下为0)采用1.0,并忽略所有其他类。

这样做:

代码语言:javascript
复制
n_classes = 20
weights=list(np.ones(20)/n_classes)  <== Making proportions correct

data = make_classification(n_samples=80, n_features=5, n_informative=5, n_redundant=0, n_repeated=0, 
                           n_classes=n_classes, n_clusters_per_class=1, weights=weights, flip_y=0, class_sep=1.0, 
                           shuffle=False, random_state=101)

正确返回:

代码语言:javascript
复制
array([ 0,  0,  0,  0,  1,  1,  1,  1,  2,  2,  2,  2,  3,  3,  3,  3,  4,
        4,  4,  4,  5,  5,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,
        8,  8,  9,  9,  9,  9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12,
       12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16,
       17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19])

最后一行:

如果权重之和超过1,则可以返回超过n_samples的样本。

似乎增加了混乱。

当您将1.0作为所有类的比例传递时,它应该返回80*20 =1600个样本,每个类都返回80个样本。

但它并没有这么做。它在内部正确地生成样本,但随后只返回前80个样本(由n_samples param定义)。这就是为什么在生成的数据中只返回一个类(0)的原因。您应该在github:https://github.com/scikit-learn/scikit-learn/issues的页面上发布这个问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52254567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档