9

机器学习完全指南:如何用 Python 生成合成数据集?

 3 years ago
source link: https://www.36kr.com/p/1078333653233538
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

神译局是36氪旗下编译团队,关注科技、商业、职场、生活等领域,重点介绍国外的新技术、新观点、新风向。

编者按:机器学习在越来越多的领域中凸显出其不可替代的重要性,人们开始从各领域渗透机器学习的典型案例,希望其大规模投入使用,而数据集对机器学习的效果起了决定性作用。这篇文章,原标题是 How to Make Synthetic Datasets with Python: A Complete Guide for Machine Learning ,作者Dario Radečić在文中主要介绍了如何用Python生成合成数据集,希望对你有所帮助。

3Q3uUja.jpg!mobile

图片来源:Pexels.com @Christina Morillo

我们总是很难找到好的数据集。有时候,你可能只想提出一个观点。在这些情况下,繁琐的加载和准备工作则会显得有点多。

在这篇文章中,我将跟大家分享如何用Python和Scikit-Learn(一个非常好的机器学习库)生成合成数据集。此外,你还将了解如何处理噪声,类别平衡和类分离等内容。

懒人目录

  • 生成你的第一个合成数据集

  • 添加噪声

  • 调整类别平衡

  • 调整类分离

生成你的第一个合成数据集

对于概念和想法展示而言,现实世界中的数据集总是盈千累万。

假设你想要直观地解释SMOTE算法(一种处理类别平衡的技术)。首先,你必须找到一个类别不平衡的数据集,并且把它映射到二维或三维空间上,以便于可视化工作。

当然,还有更好的解决方案。

Scikit-Learn库附带了一个方便的make_classification()函数。虽然这个函数不是唯一一个生成合成数据集的函数,但你在如今必然会频繁地使用它。

这个函数接受各种参数,可以让你控制数据集的具体信息,下文中会进一步介绍。

首先,你需要导入所需的库。你可以参考以下代码段:

import numpy as np  import pandas as pd from sklearn.datasets import make_classification  import matplotlib.pyplot as plt from matplotlib import rcParams rcParams['axes.spines.top'] = False rcParams['axes.spines.right'] = False

你将开始生成自己的第一个数据集。

这个数据集有1000个样本,这些样本被分为0和1两类,为了确保样本类别平衡,每一类的占比都是50%。

每个类别的所有样本都以一个单独的簇为中心。为了提高可视化效果,该数据集只有两个特征:

X, y = make_classification(     n_samples=1000,     n_features=2,     n_redundant=0,     n_clusters_per_class=1,     random_state=42 )  df = pd.concat([pd.DataFrame(X), pd.Series(y)], axis=1) df.columns = ['x1', 'x2', 'y'] # 5 random rows df.sample(5)

调用sample()函数可以列出五个随机的数据点:

eiE32iy.png!mobile

图片来源:Dario Radečić

这五个随机数据点还无法提供数据集背后的完整信息。该数据集是二维的,所以你可以声明一个用于数据可视化的函数。比如,你可以声明这样一个函数:

def plot(df: pd.DataFrame, x1: str, x2: str, y: str, title: str = '', save: bool = False, figname='figure.png'):     plt.figure(figsize=(14, 7))     plt.scatter(x=df[df[y] == 0][x1], y=df[df[y] == 0][x2], label='y = 0')     plt.scatter(x=df[df[y] == 1][x1], y=df[df[y] == 1][x2], label='y = 1')     plt.title(title, fontsize=20)     plt.legend()     if save:         plt.savefig(figname, dpi=300, bbox_inches='tight', pad_inches=0)     plt.show()   plot(df=df, x1='x1', x2='x2', y='y', title='Dataset with 2 classes')

这是该数据集可视化之后的效果:

yiABfu6.png!mobile

图2:合成数据集的可视化效果。图片来源:Dario Radečić

整个过程十分迅速!你现在拥有一个简单的能够自行处理的合成数据集。接下来,你将学习如何添加一些噪声。

添加噪声

你可以使用make_classification()函数的flip_y参数来添加噪声。

这个参数代表y(每一个样本中的类成员的整数标签)噪声值的比重。更大的值可以将噪声引入到标签中,并且使得分类任务更加困难。

值得注意的是,在某些情况下,默认设置flip_y > 0可能会导致y中缺少n_classes(类别数量)。

下面是使用该参数处理我们的数据集,为其添加噪声的演示:

X, y = make_classification(     n_samples=1000,     n_features=2,     n_redundant=0,     n_clusters_per_class=1,     flip_y=0.15,     random_state=42 )  df = pd.concat([pd.DataFrame(X), pd.Series(y)], axis=1) df.columns = ['x1', 'x2', 'y']  plot(df=df, x1='x1', x2='x2', y='y', title='Dataset with 2 classes - Added noise')

下图是对应的可视化效果。

RfmErui.png!mobile

图3:在合成数据中添加噪声的可视化效果。图片来源:Dario Radečić

你能看见蓝色簇中有更多的橘色点,反之亦如此,至少和图2比较时,这个发现是成立的。

以上就是添加噪声的方式与过程。接下来我们将讲解类别平衡。

调整类别平衡

在现实世界的数据集中,我们总能看到类别不平衡的情况。一些数据集甚至存在极大的类别不平衡问题。例如,1000笔银行交易中,可能有一笔交易是诈骗交易,这就意味着其平衡比例为1:1000。

你可以使用weights参数来控制类别平衡。它是一个有N-1个值的列表,其中N是特征数。我们之前设置的特征数为2,所以列表中只有一个值。

现在让我们来看看如果将值指定为0.95,会出现什么结果:

X, y = make_classification(     n_samples=1000,     n_features=2,     n_redundant=0,     n_clusters_per_class=1,     weights=[0.95],     random_state=42 )  df = pd.concat([pd.DataFrame(X), pd.Series(y)], axis=1) df.columns = ['x1', 'x2', 'y']  plot(df=df, x1='x1', x2='x2', y='y', title='Dataset with 2 classes - Class imbalance (y = 1)')

下图就是数据集可视化效果:

UbYvmeA.png!mobile

图4:在正类上类别不平衡的合成数据集可视化效果。图片来源:Dario Radečić

如图所示,数据集中只有5%的部分属于类1,你也可以将这一个分类比例轻松地转换。比如说,如果你将数据集中类0的占比改为5%:

X, y = make_classification(
n_samples=1000,
n_features=2,
n_redundant=0,
n_clusters_per_class=1,
weights=[0.05],
random_state=42
)
df = pd.concat([pd.DataFrame(X), pd.Series(y)], axis=1)
df.columns = ['x1', 'x2', 'y']
plot(df=df, x1='x1', x2='x2', y='y', title='Dataset with 2 classes - Class imbalance (y = 0)')

下图就是对应的可视化效果:

6RfIZr2.png!mobile

图5:在负类上类别不平衡的合成数据集可视化效果。图片来源:Dario Radečić

这就是关于类别平衡的全部信息。最后,我们再看看调整类分离。

调整类分离

默认状态下,类0和类1中总会有一些重叠的数据点。对此,你可以使用class_sep参数来控制类分离的情况。Class_sep的默认值是1.

如果你将该值设为5,我们看看会出现什么结果:

X, y = make_classification(     n_samples=1000,     n_features=2,     n_redundant=0,     n_clusters_per_class=1,     class_sep=5,     random_state=42 )  df = pd.concat([pd.DataFrame(X), pd.Series(y)], axis=1) df.columns = ['x1', 'x2', 'y']  plot(df=df, x1='x1', x2='x2', y='y', title='Dataset with 2 classes - Make classification easier')

下图就是数据集的可视化效果:

mQBbeyB.png!mobile

图6:明显的类分离合成数据集可视化效果。图片来源:Dario Radečić

如图所示,类分离的情况非常明显。将class_sep的值设置得越高,类分离效果就越好,反之亦然。

写在最后

在这篇文章中,我跟大家分享了如何用Python和Scikit-Learn生成基本的合成分类数据集。

你可以在想要证明一个观点,或是实现一些数据科学概念的时候来使用它们。然而,在这种情况下,不建议使用真实的数据集,因为它们往往需要缜密的准备工作。

译者:俊一


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK