在生成数值数据的同时,我们也常需要创建合成分类数据。分类数据代表着属于不同组或标签的特性,而非数值。例如产品类型(“电子产品”、“服装”、“杂货”)、用户状态(“活跃”、“不活跃”、“新用户”)或简单分类(“是”、“否”)。生成这类数据对于许多机器学习任务(如分类问题)必不可少。定义类别在生成分类数据之前,你必须先定义可能类别的集合。这个集合代表着分类特征可以取的所有独有值。例如,如果你正在模拟客户满意度调查的回复,你的类别可能是:“非常满意”、“满意”、“中立”、“不满意”、“非常不满意”。方法一:均匀随机抽样生成分类值最直接的方法是简单地从你定义的集合中随机选择一个类别,其中每个类别被选中的机会均等。这类似于掷一个公平的骰子,其中每个面(类别)出现的概率是 $1/N$, $N$ 是类别的总数。这种方法适用情况是,你没有关于每个类别预期频率的具体信息,或者你想要在初步测试时获得一个完全平衡的表示。假设我们的类别是 ['Red', 'Green', 'Blue']。均匀随机抽样意味着每次我们生成一个数据点时,“红色”有 1/3 的机会,“绿色”有 1/3 的机会,“蓝色”有 1/3 的机会。示例(类 Python 伪代码):import random categories = ['Red', 'Green', 'Blue'] # 生成一个随机类别 random_category = random.choice(categories) print(random_category) # 输出可能是“红色”、“绿色”或“蓝色” # 生成 10 个随机类别 synthetic_data = [random.choice(categories) for _ in range(10)] print(synthetic_data) # 示例输出:['Green', 'Blue', 'Green', 'Red', 'Blue', 'Blue', 'Red', 'Green', 'Green', 'Red']方法二:按指定概率抽样通常,真实数据中的类别出现频率不均等。例如,在一个在线交易数据集中,“已完成”类别可能远比“失败”或“已退款”类别常见。为模拟这种情况,你可以为每个类别分配特定的概率。主要要求是所有类别的概率总和必须为 1.0(或 100%)。然后你根据这些分配的权重或概率从类别中抽样。概率较高的类别将在生成的数据中更频繁地出现。假设我们想生成用户类型的数据,但我们预期大多数用户是“活跃”的。我们可以这样定义概率:“活跃”:70% (0.7)“不活跃”:20% (0.2)“新用户”:10% (0.1)概率总和 = 0.7 + 0.2 + 0.1 = 1.0。示例(类 Python 伪代码):import random categories = ['Active', 'Inactive', 'New'] probabilities = [0.7, 0.2, 0.1] # 根据概率生成一个随机类别 weighted_category = random.choices(categories, weights=probabilities, k=1)[0] print(weighted_category) # 输出最可能是“活跃” # 生成 100 个随机类别 synthetic_data = random.choices(categories, weights=probabilities, k=100) # 统计出现次数以检查分布(近似值) from collections import Counter print(Counter(synthetic_data)) # 示例输出:Counter({'Active': 68, 'Inactive': 22, 'New': 10})我们可以将目标概率与从生成样本中获得的频率进行可视化。{"layout": {"title": "分类数据生成:目标频率与样本频率对比", "xaxis": {"title": "类别"}, "yaxis": {"title": "频率 / 概率"}, "barmode": "group"}, "data": [{"type": "bar", "name": "目标概率", "x": ["活跃", "不活跃", "新用户"], "y": [0.7, 0.2, 0.1], "marker": {"color": "#228be6"}}, {"type": "bar", "name": "样本频率 (N=100)", "x": ["活跃", "不活跃", "新用户"], "y": [0.68, 0.22, 0.10], "marker": {"color": "#ff922b"}}]}对比使用加权抽样从 100 个生成点样本中获得的所需概率分布与实际频率分布。样本频率与目标概率非常接近。方法三:基于规则的生成有时,一个数据点的类别取决于其他特征的值。这与前面提到的基于规则的系统有关。你可以定义明确的规则,根据其他生成数据满足的条件来分配类别。这种方法允许你在合成数据集中不同列之间引入简单的关系,使其可能比独立生成每一列更具真实感。示例:年龄组: 如果你已经生成了数值型“年龄”特征,你可以使用规则创建一个分类型“年龄组”特征:如果 年龄 < 18 则 年龄组 = “儿童”如果 18 <= 年龄 < 65 则 年龄组 = “成人”如果 年龄 >= 65 则 年龄组 = “老年人”产品推荐: 基于一个已生成的“购买历史”类别,你可能会分配一个“推荐产品类型”:如果 购买历史 = “电子产品” 则 推荐产品类型 = “配件”如果 购买历史 = “图书” 则 推荐产品类型 = “文具”基于规则的生成需要定义连接不同数据块的逻辑。虽然简单规则易于实现,但复杂的依赖关系可能需要更精细的方法。示例(结合数值和基于规则的分类数据的类 Python 伪代码):import random def generate_age_group(age): if age < 18: return '儿童' elif 18 <= age < 65: return '成人' else: return '老年人' synthetic_data = [] for _ in range(5): # 生成一个随机年龄(数值型) age = random.randint(10, 80) # 根据年龄生成年龄组(基于规则的分类型) age_group = generate_age_group(age) synthetic_data.append({'Age': age, 'Age Group': age_group}) print(synthetic_data) # 示例输出: # [{'Age': 45, 'Age Group': '成人'}, # {'Age': 12, 'Age Group': '儿童'}, # {'Age': 71, 'Age Group': '老年人'}, # {'Age': 25, 'Age Group': '成人'}, # {'Age': 66, 'Age Group': '老年人'}]“这些基本方法——均匀抽样、加权抽样和基于规则的分配——为生成简单分类数据提供了依据。虽然它们可能无法捕捉分布和依赖关系的所有复杂性,但它们是创建基本合成数据集用于测试、开发或扩充有限数据的重要起点。随着学习的推进,你会遇到更多建立在这些基本原则之上的高级技术。”