Scikit-Learn快速生成分类数据集

假如你学习了新的分类算法并想进一步探索研究、尝试不同的超参数评估模型性能,但问题是你找不到好的数据集用于实验。幸运的是Scikit-Learn 提供的 make_classification() 方法可以创建不同类型的数据集,它可以生成不同类型的数据集:二分类、多分类、平衡或不平衡数据集、难以分类的数据集等。本文通过示例详细说明,并结合随机森林分类算法进行验证。

make_classification函数

首先我们介绍该函数参数,以及常用参数及默认值:

  • n_samples: 生成多少条样本数据,缺省100条.
  • n_features: 有几个数值类型特征,缺省为20.
  • n_informative: 有用特征的个数,仅这些特征承载对分类信号.,缺省为2.
  • n_classes: 分类标签的数量,缺省为2.

该函数返回包含函数Numpy 数组的tuple,分别为特征X,以及标签y。其他参数用到时再作说明。

生成二分类数据集

下面生成二分类数据集,即标签仅有两个可能的值:0 、1.

因此需要设置n_classes参数为2。我们需要生成1000条样本,包括5个特征,其中三个为有用特征,另外两个为冗余特征。

python 复制代码
from sklearn.datasets import make_classification

X, y = make_classification(
    n_samples=1000, # 1000 observations 
    n_features=5, # 5 total features
    n_informative=3, # 3 'useful' features
    n_classes=2, # binary target/label 
    random_state=999 # if you want the same results as mine
)

下面需转换 make_classification 函数返回值为 padas 数据框。padas 数据框比Numpy数组更易分析。

python 复制代码
import pandas as pd

# Create DataFrame with features as columns
dataset = pd.DataFrame(X)
# give custom names to the features
dataset.columns = ['X1', 'X2', 'X3', 'X4', 'X5']
# Now add the label as a column
dataset['y'] = y

dataset.info()

输出结果:

复制代码
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 6 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   X1      1000 non-null   float64
 1   X2      1000 non-null   float64
 2   X3      1000 non-null   float64
 3   X4      1000 non-null   float64
 4   X5      1000 non-null   float64
 5   y       1000 non-null   int64  
dtypes: float64(5), int64(1)
memory usage: 47.0 KB

和我们期望一致,该数据集包括1000个样本,包括5个特征,以及对应的响应目标标签。我们设置**n_informative** 为3,因此,仅 (X1 , X2 , X3 )是重要的,另外两个 X4X5, 是多余的。

现状我们检查标签y的基数和总数:

python 复制代码
dataset['y'].value_counts()

1    502
0    498
Name: y, dtype: int64

标签仅包括两个可能的值,因此属于二分类数据集。而且两者数量大致相当,因此标签分类相对平衡。下面查看前5条样本值:

python 复制代码
dataset.head()
X1 X2 X3 X4 X5 y
0 2.501284 -0.159155 0.672438 3.469991 0.949268 0
1 2.203247 -0.331271 0.794319 3.259963 0.832451 0
2 -1.524573 -0.870737 1.004304 -1.028624 -0.717383 1
3 1.801498 3.106336 1.490633 -0.297404 -0.607484 0
4 -0.125146 0.987915 0.880293 -0.937299 -0.626822 0

分类示例

生成数据集看上去不错,下面利用缺省超参数创建随机森林分类器。我们使用交叉验证衡量模型性能:

python 复制代码
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_validate

# initialize classifier
classifier = RandomForestClassifier() 

# Run cross validation with 10 folds
scores = cross_validate(
    classifier, X, y, cv=10, 
    # measure score for a list of classification metrics
    scoring=['accuracy', 'precision', 'recall', 'f1']
)

scores = pd.DataFrame(scores)
scores.mean().round(4)

输出结果如下, 模型的 Accuracy, Precision, Recall, 和 F1 Score接近88%. 没有调整任何超参数情况下,表现尚可。

text 复制代码
fit_time          0.1201
score_time        0.0072
test_accuracy     0.8820
test_precision    0.8829
test_recall       0.8844
test_f1           0.8827
dtype: float64

不易分类数据集

下面尝试创建要给不容易分类的数据集。我们可以使用下面**make_classification()**函数参数控制数据集的难度级别:

  • flip_y: 通过反转少量标签增加噪声数据 . 举例,改变少量标签值0的值为1,返回改变1为0. 该值越大噪声越多,缺省值为 0.01.
  • class_sep: 类别之间的距离,默认值为1.0,表示原始特征空间中的类别之间的平均距离. 值越小分类越难.

下面代码使用flip_y较高的值与class_sep较低的值创建有挑战性的数据集:

python 复制代码
X, y = make_classification(
    # same as the previous section
    n_samples=1000, n_features=5, n_informative=3, n_classes=2, 
    # flip_y - high value to add more noise
    flip_y=0.1, 
    # class_sep - low value to reduce space between classes
    class_sep=0.5
)

# Check label class distribution
pd.DataFrame(y).value_counts()
复制代码
1    508
0    492
dtype: int64

0 和 1 标签对应的样本量几乎相当。因此分类相对平衡。

分类较难数据集

我们再次构建随机森林模型,并使用默认超参数。这次使用较难的数据集:

python 复制代码
classifier = RandomForestClassifier() 

scores = cross_validate(
    classifier, X, y, cv=10, 
    scoring=['accuracy', 'precision', 'recall', 'f1']
)

scores = pd.DataFrame(scores)
scores.mean()
复制代码
fit_time          0.138662
score_time        0.007333
test_accuracy     0.756000
test_precision    0.764619
test_recall       0.760196
test_f1           0.759281
dtype: float64

模型的Accuracy , Precision , Recall , 和F1 Score 参数值大约在75~76%.相对前面88%有了明显下降。

flip_y 和**class_sep** 参数值起作用了,它们创建的数据集确实较难分类。

不平衡数据集

前面我们创建的数据集,每个分类对应样本大致相等。但有时我们需要不平衡数据集,即其中一个标签分类样本数据比较稀少。

我们可以使用参数weights去控制每个分类的比例。下面代码利用make_classification 函数给样本0值标签分配比例97%, 剩下了的分类值1占3%:

python 复制代码
X, y = make_classification(
    # the usual parameters
    n_samples=1000, n_features=5, n_informative=3, n_classes=2, 
    # Set label 0 for  97% and 1 for rest 3% of observations
    weights=[0.97], 
)

pd.DataFrame(y).value_counts()
复制代码
0    964
1     36
dtype: int64

从结果看,**make_classification()**函数分配了3%比例给标签值为1的样本,确实生成了不平衡数据集。

分类不平衡数据集

与前节一样,仍使用缺省超参数的随机森林模型训练不平衡数据集:

python 复制代码
classifier = RandomForestClassifier() 

scores = cross_validate(
    classifier, X, y, cv=10, 
    scoring=['accuracy', 'precision', 'recall', 'f1']
)

scores = pd.DataFrame(scores)
scores.mean()
复制代码
fit_time          0.101848
score_time        0.006896
test_accuracy     0.964000
test_precision    0.250000
test_recall       0.083333
test_f1           0.123333
dtype: float64

我们看到有趣的现象,我们的模型准确率很高(96%),但精确率和召回率很低(25% 和 8%)。这是典型的准确率悖论,当处理不平衡数据经常会发生。

多分类数据集

到目前为止,我们生成的标签仅有两种可能。如果你需要多分类数据做实验,则标签需要超过2个值。n_classes参数可以实现:

python 复制代码
X, y = make_classification(
    # same parameters as usual 
    n_samples=1000, n_features=5, n_informative=3,
    # create target label with 3 classes
    n_classes=3, 
)

pd.DataFrame(y).value_counts()
复制代码
1    334
2    333
0    333
dtype: int64

从结果看,三个分类样本大致相当,数据集分类较平衡。

多分类不平衡数据集

我们也可以很容易创建不平衡多分类数据集,只需要使用参数 n_classes 和 weights :

python 复制代码
X, y = make_classification(
    # same parameters as usual 
    n_samples=1000, n_features=5, n_informative=3,
    # create target label with 3 classes
    n_classes=3, 
    # assign 4% of rows to class 0, 48% to class 1
    # and the rest to class 2
    weights=[0.04, 0.48]
)

pd.DataFrame(y).value_counts()

0 值分类占 4%, 1 值占 48%, 剩下的给值 2 标签。查看结果:

复制代码
2    479
1    477
0     44
dtype: int64

1000个样本中 0 值标签仅有44个,和预期一致。

总结

现在你学会了使用scikit-learn的make_classification函数生成不同类型数据集了吧。包括二分类或多分类、不平衡数据集、挑战性难分类的数据集等。更多参数可以查看官方文档,本文参考:How to Generate Datasets Using make_classification | Proclus Academy

相关推荐
肥猪猪爸1 小时前
BP神经网络对时序数据进行分类
人工智能·深度学习·神经网络·算法·机器学习·分类·时序数据
Keep learning!1 小时前
深度学习入门代码详细注释-ResNet18分类蚂蚁蜜蜂
人工智能·深度学习·分类
Dxy12393102163 小时前
Python PDFplumber详解:从入门到精通的PDF处理指南
开发语言·python·pdf
在努力的韩小豪4 小时前
如何从0开始构建自己的第一个AI应用?(Prompt工程、Agent自定义、Tuning)
人工智能·python·llm·prompt·agent·ai应用·mcp
Otaku love travel5 小时前
实施运维文档
运维·windows·python
测试老哥6 小时前
软件测试之单元测试
自动化测试·软件测试·python·测试工具·职场和发展·单元测试·测试用例
presenttttt6 小时前
用Python和OpenCV从零搭建一个完整的双目视觉系统(六 最终篇)
开发语言·python·opencv·计算机视觉
测试19987 小时前
软件测试之压力测试总结
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·压力测试
李昊哲小课8 小时前
销售数据可视化分析项目
python·信息可视化·数据分析·matplotlib·数据可视化·seaborn
烛阴8 小时前
带参数的Python装饰器原来这么简单,5分钟彻底掌握!
前端·python