课程

什么是合成数据?
合成数据是由计算机生成、与真实世界数据相似的数据。合成数据的主要目的是提升系统的隐私性和完整性。例如,为保护用户的个人可识别信息(PII)或个人健康信息(PHI),公司必须实施数据保护策略。使用合成数据可以帮助公司测试新应用并保护用户隐私。
在机器学习中,我们使用合成数据来提升模型性能。在数据稀缺或类别不平衡的情况下也适用。合成数据在机器学习中的典型用例包括自动驾驶、安全、机器人、反欺诈和医疗健康。

图片来源:Nvidia
根据 Gartner 的数据,到 2024 年,用于开发机器学习和分析型应用的数据中将有 60% 为合成生成。那么,为什么合成数据呈上升趋势?
收集和清洗真实世界数据成本高昂,且在某些场景下十分稀缺。比如银行欺诈、乳腺癌、自动驾驶场景与恶意软件攻击等数据在现实中很难获取。即使获得数据,也需要投入时间和资源进行清洗与处理,才能用于机器学习任务。
在本教程的第一部分,我们将了解为何需要合成数据、其应用以及如何生成。在最后一部分,我们将探索 Python Faker 库,并用它来创建合成数据,以便进行测试并维护用户隐私。
为什么需要生成合成数据?

作者供图
我们需要合成数据来实现用户隐私、应用测试、提升模型性能、呈现罕见案例,并降低运营成本。
- 隐私:用于保护用户数据。您可以用合成数据替换姓名、邮箱和地址。这有助于避免网络攻击和黑箱攻击(模型推断训练数据细节)。
- 测试:在真实数据上进行应用测试成本高。使用合成数据测试数据库、UI 和 AI 应用更经济、更安全。
- 模型性能:生成的合成数据可以提升模型表现。例如:在图像分类中,我们通过剪切、平移、旋转图像来扩充数据集规模并提高准确率。
- 罕见案例:我们无法等待罕见事件发生再去收集真实数据。例如:信用欺诈检测、车祸与癌症相关数据。
- 成本:数据收集需要时间与资源。获取真实数据、清洗、标注并为测试或训练做准备,都成本不菲。
合成数据的应用有哪些?
本节将介绍公司如何利用合成数据构建高性价比、隐私友好且性能优异的应用。
- 数据共享:合成数据使企业能够在内部及与第三方共享敏感数据。它还支持将私有数据迁移至云端并保留用于分析。
- 金融服务:生成合成数据以模拟罕见事件,如欺诈交易、异常检测和经济衰退。亦可用于借助分析工具理解客户行为。
- 质量保障:用于维护和测试应用或数据系统的质量。通过在更罕见的异常上测试系统来提升性能。
- 医疗健康:在保持患者隐私的同时,实现医疗记录的内外部共享。还可用于临床试验与罕见疾病检测。通过学习 Python 或 R 的数据隐私与匿名化课程,了解如何处理敏感信息。
- 汽车与机器人:为机器人、无人机与自动驾驶汽车获取真实世界数据困难且缓慢。公司利用合成仿真数据对系统进行测试和训练,在不牺牲性能的前提下降低构建成本。
- 机器学习:我们可用合成数据扩充训练集规模、解决类别不平衡问题,并测试模型以确保性能与准确性。它也用于降低现有图像和文本数据中的偏差。这有助于我们测试系统并维护用户隐私。例如,DeepFake 可用于测试人脸识别系统。
如何生成合成数据
我们可以使用虚假数据生成器、统计工具、神经网络以及生成式对抗网络来生成合成数据。
生成虚拟数据库:使用 Faker 库测试数据库和系统。它可以生成包含地址等关键信息的虚拟用户档案。您也可以用它生成随机文本与段落。在测试阶段,它帮助公司保护用户隐私,并节省获取真实数据集的成本。
理解数据分布:使用高斯、指数、卡方、t、对数正态与均匀等统计工具,基于分布生成全新的数据集。要生成基于分布的合成数据,您需要具备相关领域知识。
变分自编码器(VAE):一种无监督学习方法,使用编码器和解码器来压缩原始数据集,并生成对原始数据集的表示。它旨在优化输入与输出数据集之间的相关性。
生成式对抗网络(GAN):当前生成数据最流行的方法。您可以用它生成合成图像、音频、表格数据和仿真数据。它通过生成器与判别器的深度学习架构,将随机样本与真实数据进行对比来生成合成数据。阅读我们的 走近生成式对抗网络 教程,使用 Keras 创建您自己的合成数据。
什么是 Python Faker?
Python Faker 是一个开源的 Python 包,用于创建用于应用测试、数据库引导和维护用户匿名性的虚拟数据集。

作者供图
您可以使用以下命令安装 Faker:
pip install faker
Faker 提供命令行支持、Pytest fixtures、本地化(支持不同地区)、可复现性以及动态提供者(可按需自定义)。
您也可以使用 Faker 的基础功能快速创建数据集,并根据需要进行定制。下表列出了多种 Faker 函数及其用途。
|
Faker Function |
Purpose |
|
name() |
生成虚拟全名 |
|
credit_card_full() |
生成带有效期和 CVV 的信用卡号 |
|
email() |
生成虚拟电子邮箱地址 |
|
url() |
生成虚拟 URL |
|
phone_number() |
生成带国家区号的虚拟电话号码 |
|
address() |
生成虚拟完整地址 |
|
license_plate() |
生成虚拟车牌号 |
|
currency() |
生成货币代码与全称的元组 |
|
color_name() |
生成随机颜色名称 |
|
local_latlng() |
生成纬度、经度、区域、国家和州/省信息 |
|
domain_name() |
基于虚拟人名生成虚拟网站域名 |
|
text() |
生成虚拟短文本 |
|
company() |
生成虚拟公司名称 |
要了解更多高级功能,请查看 Faker 文档。
审阅这些函数很重要,因为我们将用它们来创建各类示例与数据框。
使用 Python Faker 生成合成数据
本节我们将使用 Python Faker 生成合成数据。包含 5 个使用 Faker 完成不同任务的示例。主要目标是构建以隐私为中心的系统测试方法。在最后一部分,我们将使用 Faker 的本地化提供者生成虚拟数据来补充原始数据。
您可以在此 DataLab 工作簿中找到本教程的全部代码;您可以轻松创建一份副本,在浏览器中运行所有代码,无需在您的电脑上安装任何东西。
首先,我们将使用 `Faker()` 初始化一个虚拟数据生成器。默认使用 “en_US” 本地化。
from faker import Faker
fake = Faker()
示例 1
“fake” 对象可以通过属性名来生成数据。例如,`fake.name()` 用于生成随机的某个人的全名。
print(fake.name())
>>> Jessica Robinson
类似地,我们可以生成虚拟邮箱地址、国家名称、文本、地理位置和 URL,如下所示。
print(fake.email())
print(fake.country())
print(fake.name())
print(fake.text())
print(fake.latitude(), fake.longitude())
print(fake.url())
输出
ybanks@example.com
Mayotte
Mr. Jose Browning DDS
Dog might bank dog total life financial. Dark view doctor time just.
Stay second treatment language theory. Space seek adult create matter imagine lay.
51.7514185 -148.802970
http://fischer.info/
示例 2
您可以使用不同的本地化来为不同语言和地区生成数据。
在下面的示例中,我们将生成西班牙语、地区为西班牙的数据。
fake = Faker("es_ES")
print(fake.email())
print(fake.country())
print(fake.name())
print(fake.text())
print(fake.latitude(), fake.longitude())
print(fake.url())
输出
可以看到,个人姓名发生了变化,文本为西班牙语。
casandrahierro@example.com
Tonga
Juan Solera-Mancebo
Cumque adipisci eligendi aperiam. Quas laboriosam amet at dignissimos. Excepturi pariatur ipsam esse.
89.180798 -2.274117
https://corbacho-galan.net/
我们再试试德语,并将国家设置为德国。要生成完整的用户档案,我们将使用 `profile()` 函数。
fake = Faker("de_DE")
fake.profile()
输出
很明显,我们可以使用 Faker 为不同国家的多种语言生成数据。更改本地化将根据语言和国家变化姓名、职位、地址、公司和其他用户识别信息。
{'job': 'Erzieher',
'company': 'Stadelmann Thanel GmbH',
'ssn': '631-64-0521',
'residence': 'Leo-Schinke-Allee 298\n26224 Altötting',
'current_location': (Decimal('51.5788595'), Decimal('29.780659')),
'blood_group': 'B+',
'website': ['https://www.schmidtke.de/',
'https://roskoth.com/',
'http://www.textor.de/',
'https://www.zirme.com/'],
'username': 'vdoerr',
'name': 'Francesca Fröhlich',
'sex': 'F',
'address': 'Steinbergallee 13\n84765 Saarbrücken',
'mail': 'smuehle@gmail.com',
'birthdate': datetime.date(1998, 3, 19)}
示例 3
在本示例中,我们将使用 Faker 创建一个 pandas 数据框。
- 创建空的 pandas 数据框(data)
- 循环 x 次以创建多行
- 使用 `randint()` 生成唯一 id
- 使用 Faker 创建姓名、地址和地理位置
- 以 x=10 运行 `input_data()` 函数
from random import randint
import pandas as pd
fake = Faker()
def input_data(x):
# pandas dataframe
data = pd.DataFrame()
for i in range(0, x):
data.loc[i,'id']= randint(1, 100)
data.loc[i,'name']= fake.name()
data.loc[i,'address']= fake.address()
data.loc[i,'latitude']= str(fake.latitude())
data.loc[i,'longitude']= str(fake.longitude())
return data
input_data(10)
输出效果非常好。我们得到了包含唯一用户数据的 id、name、address、latitude 和 longitude 列。

要复现实验结果,我们需要设置随机种子。这样每次再次运行代码单元,都能得到相似的结果。
Faker.seed(2)
input_data(10)
示例 4
我们还可以生成包含指定关键词的句子。类似于 `text(), texts(), paragraph(), word(), 以及 words()`。您可以通过设置 nb_words 参数来增加句子中的词数。
在下面的示例中,我们使用一个词表生成五个句子。虽然不够完美,但对于需要大量文本数据的应用测试很有帮助。
word_list = ["DataCamp", "says", "great", "loves", "tutorial", "workplace"]
for i in range(0, 5):
print(fake.sentence(ext_word_list=word_list))
输出
Loves great says.
Says workplace workplace tutorial great loves.
Loves workplace workplace loves workplace loves great DataCamp.
Loves says workplace great.
Workplace great DataCamp.
融合合成与真实数据
本部分我们将使用 DataCamp 数据集仓库中的电商数据,并基于 CustomerID 和 Country 列添加虚拟用户数据。这将帮助我们在维护用户隐私的同时,用更多参数测试系统。
要加载 CSV 文件,我们将使用 pandas 的 `read_csv()` 函数,并用 `head()` 展示前五行
# Loading CSV file
Ecommerce = pd.read_csv("e-commerce.csv")
Ecommerce.head()
该数据集包含 InvoiceNo、StockCode(产品 ID)、Description、Product(商品)名称、Quantity(每次交易数量)、InvoiceDate、UnitPrice(英镑计价)、CustomerID 和 Country 列。

为创建本地化的 faker 对象,我们将先展示唯一的国家名称,并用它们创建字典。可以看到共有七个国家,下一步我们将创建七个本地化的 faker 生成器。
Ecommerce.Country.dropna().unique()
>>> array(['United Kingdom', 'France', 'Australia', 'Netherlands', 'Germany',
'Norway', 'EIRE'], dtype=object)
在 `anonymous` 函数中,我们:
- 提取唯一的客户 ID,并删除缺失值
- 创建国家名称与本地化简称的字典
- 为唯一客户 ID 提取行索引与国家名称
- 使用字典和国家名称初始化本地化 faker 生成器
- 将客户姓名、地址与地理位置添加到现有数据框。
下面的函数使用数据框,并基于 CustomerID 和 Country 列添加四个包含用户数据的新列。
def anonymous(df):
# Extracting unique CustomerID
unique_id = df.CustomerID.dropna().unique()
# Creating the dictionary for Faker localized providers
local = {
"United Kingdom": "en_GB",
"France": "fr_FR",
"Australia": "en_AU",
"Netherlands": "nl_NL",
"Germany": "de_DE",
"Norway": "no_NO",
"EIRE": "ga_IE",
}
for i in unique_id:
# Extracting row index
row_id = df[df["CustomerID"] == i].index
# Extracting country name for faker locale
CountryName = Ecommerce.loc[
Ecommerce["CustomerID"] == i, "Country"
].to_numpy()[0]
# Using locale dictionary to create faker locale generator
code = local[CountryName]
fake = Faker(code)
# Generating fake data and adding it to dataframe
CustomerName = fake.name()
Address = fake.address()
Latitude = str(fake.latitude())
Longitude = str(fake.longitude())
for x in row_id:
df.loc[x, "CustomerName"] = CustomerName
df.loc[x, "Address"] = Address
df.loc[x, "Latitude"] = Latitude
df.loc[x, "Longitude"] = Longitude
return df
我们将使用 seed(5) 以实现可复现性,并在 Ecommerce 数据框上运行 `anonymous` 函数。
# Using seed for reproducibility
Faker.seed(5)
secure_db = anonymous(Ecommerce)
secure_db
前几条结果显示了 CustomerID 为 17850、国家为英国、姓名为 Pamela Cox-James 的数据。

为可视化函数的本地化结果,我们需要查看每个唯一国家的数据。
display_db = []
for i in Ecommerce.Country.dropna().unique():
display_db.append(secure_db[secure_db["Country"] == i].to_numpy()[0])
pd.DataFrame(display_db, columns=Ecommerce.columns)
结果令人满意。您可以看到不同地区和语言对应不同姓名。地址与国家相匹配。通过这种方法,您可以去除个人识别信息,并使用 Faker 创建本地化数据,从而保护用户隐私并节省成本。

代码来源可在此 DataLab 工作簿中获取。
结语
使用 Python Faker 的一个缺点是数据质量较差。它适合用于应用测试,但缺乏数据准确性。例如,姓名与邮箱、域名或用户名并不匹配。
您可以按需自定义提供者或创建新的提供者,但要花费额外时间去完善系统。在同等时间内,您也可以使用 `random.choice()` 创建自己的 Python 包。
在大型科技公司中,数据科学家使用多种工具来处理敏感数据并维护数据隐私。他们还使用合成数据来提升模型性能、降低偏差、测试应用,并在开发前沿 AI 方案时节省成本。
如果您有兴趣继续学习,请查看 Data Scientist with Python 职业路径,开启成为自信数据科学家的旅程。
在本教程中,我们学习了合成数据的重要性及其应用。我们还使用 Python Faker 从零生成了虚拟数据,以测试数据系统并维护用户隐私。
