使用TensorFlow预处理文本DataFrame的步骤顺序及操作咨询
问题解决方案
核心步骤顺序
正确的操作流程是:1. 拆分特征与标签 → 2. 划分训练/验证/测试集 → 3. 用训练数据适配向量化层并完成向量化
原因:向量化层只能基于训练数据构建词汇表,绝对不能碰验证/测试数据,否则会造成数据泄露;先拆分特征标签再划分数据集,能保证每组数据的特征与标签严格对应,逻辑更清晰。
1. 拆分特征与标签
直接从DataFrame中提取对应列即可,特征是文本列Sentence,标签是标注列Annotation:
import pandas as pd import tensorflow as tf # 假设你的数据集存储在df中 features = df['Sentence'] labels = df['Annotation']
此时features和labels都是Pandas Series,后续可直接用于数据集划分或转换为TensorFlow对象。
2. 划分训练/验证/测试集(不用sklearn)
提供两种无依赖的实现方式:
方法一:Pandas随机拆分
通过打乱原数据集后按比例切片:
# 随机打乱数据集(random_state固定保证可复现) shuffled_df = df.sample(frac=1, random_state=42) # 计算各集大小(示例比例7:2:1) train_size = int(0.7 * len(shuffled_df)) val_size = int(0.2 * len(shuffled_df)) # 拆分数据集 train_df = shuffled_df.iloc[:train_size] val_df = shuffled_df.iloc[train_size:train_size+val_size] test_df = shuffled_df.iloc[train_size+val_size:] # 提取各集的特征与标签 train_features = train_df['Sentence'] train_labels = train_df['Annotation'] val_features = val_df['Sentence'] val_labels = val_df['Annotation'] test_features = test_df['Sentence'] test_labels = test_df['Annotation']
方法二:TensorFlow Dataset划分
直接将特征和标签转为TensorFlow数据集后拆分:
# 构建TensorFlow数据集 dataset = tf.data.Dataset.from_tensor_slices((features.values, labels.values)) # 打乱数据集 dataset = dataset.shuffle(buffer_size=len(df), random_state=42) # 拆分比例 train_size = int(0.7 * len(df)) val_size = int(0.2 * len(df)) train_dataset = dataset.take(train_size) val_dataset = dataset.skip(train_size).take(val_size) test_dataset = dataset.skip(train_size + val_size)
3. 训练数据向量化(关键:仅用训练数据适配)
必须先用训练数据适配向量化层,再转换所有数据集的特征:
# 定义向量化层(maxlen替换为你的目标最大词汇量,比如10000) maxlen = 10000 vectorize_layer = tf.keras.layers.TextVectorization( max_tokens=maxlen, standardize='lower', split='whitespace', ngrams=(1,3), output_mode='tf-idf', pad_to_max_tokens=True,) # 仅用训练特征适配向量化层(核心:不能用验证/测试数据) vectorize_layer.adapt(train_features) # 转换特征(分两种场景) # 场景1:Pandas Series转张量 train_vec = vectorize_layer(train_features) val_vec = vectorize_layer(val_features) test_vec = vectorize_layer(test_features) # 场景2:TensorFlow Dataset转换 def vectorize_text(text, label): text = tf.expand_dims(text, -1) # 适配层输入维度要求 return vectorize_layer(text), label train_dataset_vec = train_dataset.map(vectorize_text) val_dataset_vec = val_dataset.map(vectorize_text) test_dataset_vec = test_dataset.map(vectorize_text)
张量访问方法
- 单独张量(如
train_vec):用numpy()转成NumPy数组查看:# 查看前5条向量化结果 print(train_vec[:5].numpy()) # 查看张量形状 print(train_vec.shape) - Dataset中的张量:用
take()取出单个元素查看:# 取出数据集第一个元素的特征和标签张量 for text_vec, label in train_dataset_vec.take(1): print("特征张量:", text_vec.numpy()) print("标签张量:", label.numpy())
常见疑问解答
- 为什么先拆分特征标签再划分数据集?
逻辑上更清晰,能确保每一组数据的特征与标签严格对应,避免划分时出现匹配错误。先划分数据集再拆分特征标签结果一致,但前者更便于后续单独处理特征或标签。 - 能不能先向量化再划分数据集?
绝对不行!向量化层适配时会学习数据的词汇分布,如果提前用全量数据适配,会让模型“偷看”到验证/测试集的词汇信息,属于数据泄露,导致测试结果失真。
内容的提问来源于stack exchange,提问作者Yana
相关产品推荐
相关产品推荐

