大数据特征工程:如何处理文本与数值混合特征

大数据特征工程:如何处理文本与数值混合特征

一、引言 (Introduction)

钩子 (The Hook)

你是否曾在处理电商用户行为数据时陷入这样的困境:

  • 手里有一堆数值型特征:购买次数(1-1000)、平均客单价(100-10000)、停留时长(0-3600秒);
  • 还有一堆文本型特征:用户评论("这个商品质量太差了,再也不买了")、商品标题("2024夏季新款纯棉T恤男宽松休闲短袖")、客服聊天记录("请问这个衣服能退换吗?");
  • 想把这些特征喂给模型(比如推荐系统、欺诈检测),但不知道该怎么把结构化的数值非结构化的文本揉成模型能理解的"统一语言"?

如果你的答案是"是",那么这篇文章就是为你写的。混合特征处理是大数据特征工程中的"必考题",也是很多数据科学家容易栽跟头的地方------处理得好,模型效果能提升30%以上;处理得差,可能让所有努力白费。

定义问题/阐述背景 (The "Why")

在大数据场景中,单一类型的特征几乎不存在。比如:

  • 推荐系统:用户的浏览次数(数值)+ 搜索关键词(文本)+ 收藏夹内容(文本);
  • 情感分析:产品的评分(数值)+ 评论内容(文本)+ 销量(数值);
  • 欺诈检测:用户的交易金额(数值)+ 收货地址(文本)+ 设备型号(文本)。

这些混合特征包含了不同模态的信息:数值特征能直接反映"量"的大小(比如购买次数越多,用户粘性越高),文本特征能反映"质"的特征(比如评论中的"太差了"直接表达负面情绪)。如果只处理其中一种类型,会丢失大量关键信息------比如忽略评论文本,推荐系统可能把"差评很多但购买次数多"的商品推荐给用户,导致转化率暴跌。

因此,混合特征处理的核心目标 是:保留数值特征的"量化信息"和文本特征的"语义信息",并将它们转换为模型能高效利用的结构化表示

亮明观点/文章目标 (The "What" & "How")

本文将带你从0到1掌握混合特征处理的完整流程,内容涵盖:

  1. 基础认知:数值特征与文本特征的本质差异;
  2. 实战步骤:从数据探索到特征融合的具体操作(附Python代码);
  3. 进阶技巧:避免踩坑的最佳实践、性能优化方法;
  4. 未来趋势:大模型时代混合特征处理的新方向。

读完这篇文章,你能解决的问题包括:

  • 如何清洗数值特征中的异常值?
  • 如何将文本特征转换为向量?
  • 如何融合数值与文本特征,让模型同时"看懂"两者?
  • 如何避免混合特征处理中的常见陷阱?

二、基础知识/背景铺垫 (Foundational Concepts)

在开始实战前,我们需要先明确几个核心概念,避免后续混淆。

1. 什么是特征工程?

特征工程是将原始数据转换为模型可理解的特征的过程,目的是提升模型的性能。它包括:数据清洗、特征提取、特征选择、特征融合等步骤。

对于混合特征(文本+数值),特征工程的难点在于:两种特征的表示方式完全不同 ------数值特征是结构化的(比如购买次数=5),文本特征是非结构化的(比如评论="质量太差了"),需要分别处理后再融合。

2. 数值特征的类型与特点

数值特征分为连续型 (比如停留时长客单价)和离散型 (比如购买次数收藏数量),它们的特点是:

  • 结构化:可以直接用数字表示;
  • 量纲差异大 :比如客单价是100-10000,购买次数是1-1000,直接输入模型会导致"数值大的特征被过度重视";
  • 容易统计:可以通过均值、方差、分位数等统计量构造新特征。

3. 文本特征的类型与特点

文本特征是非结构化的,需要转换为结构化的向量才能被模型使用。常见的文本特征包括:

  • 短文本 :比如商品标题(10-20字)、用户评论(50-100字);
  • 长文本 :比如客服聊天记录(500-1000字)、产品说明书(几千字)。

文本特征的核心价值是语义信息 (比如"太差了"表示负面情绪),但需要通过分词、嵌入等步骤将语义转换为数字。

4. 混合特征的常见场景

混合特征几乎存在于所有大数据应用中,以下是几个典型场景:

场景 数值特征 文本特征
电商推荐 购买次数、客单价、停留时长 用户评论、商品标题、搜索关键词
金融欺诈检测 交易金额、还款次数、逾期天数 收货地址、设备型号、备注信息
医疗诊断 体温、血压、血常规指标 病历描述、症状主诉、医生备注

三、核心内容/实战演练 (The Core - "How-To")

接下来进入本文的核心部分:混合特征处理的实战流程 。我们以电商用户评论分析为例(目标:预测用户是否会再次购买),用Python实现从数据探索到特征融合的完整步骤。

数据准备

首先,我们构造一个模拟的电商用户数据集(user_data.csv),包含以下字段:

字段名 类型 说明
user_id 字符串 用户ID
purchase_count 整数 购买次数(数值特征)
avg_order_value 浮点数 平均客单价(数值特征)
stay_duration 整数 平均停留时长(秒,数值特征)
comment 字符串 用户评论(文本特征)
re_purchase 整数 是否再次购买(标签:0=否,1=是)

导入必要的库:

python 复制代码
import pandas as pd
import numpy as np
import jieba  # 中文分词库
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, f1_score

步骤一:数据探索与预处理

数据探索(EDA)是特征工程的第一步,目的是发现数据中的问题(比如缺失值、异常值),并为后续处理提供依据。

1. 加载数据并查看基本信息
python 复制代码
df = pd.read_csv("user_data.csv")
print(df.head())
print(df.info())
print(df.describe())

输出结果示例:

  • purchase_count:均值为12.3,最大值为100,最小值为1(无缺失值);
  • avg_order_value:均值为523.6,最大值为10000,最小值为100(无缺失值);
  • stay_duration:均值为180,最大值为3600,最小值为0(有缺失值,占比5%);
  • comment:有10%的缺失值(用户未评论);
  • re_purchase:正负样本比例为1:1(平衡数据集)。
2. 处理缺失值
  • 数值特征stay_duration缺失值用均值填充(因为是连续型特征,均值更稳健);
  • 文本特征comment缺失值用空字符串填充(或者用"未评论"代替,避免丢失样本)。
python 复制代码
# 处理数值特征缺失值
df["stay_duration"].fillna(df["stay_duration"].mean(), inplace=True)

# 处理文本特征缺失值
df["comment"].fillna("", inplace=True)
3. 处理异常值

数值特征中的异常值(比如avg_order_value=10000,可能是测试数据或异常交易)会影响模型效果,需要处理。常见的方法有:

  • 截断法:将超过99%分位数或低于1%分位数的值替换为分位数;
  • 删除法:如果异常值占比很小(比如<1%),直接删除。

这里我们用截断法 处理avg_order_value

python 复制代码
# 计算99%分位数
q99 = df["avg_order_value"].quantile(0.99)
# 将超过99%分位数的值替换为q99
df["avg_order_value"] = df["avg_order_value"].apply(lambda x: min(x, q99))

步骤二:处理数值特征

数值特征的处理目标是消除量纲差异 (让不同特征的数值范围一致)和提取更有价值的信息(比如统计特征)。

1. 连续型数值特征:归一化/标准化

连续型特征(比如avg_order_valuestay_duration)的量纲差异大,需要归一化(Min-Max Scaling)或标准化(Standard Scaling)。

  • 归一化:将数值缩放到[0,1]区间,适合数据分布已知(比如正态分布)的情况;
  • 标准化:将数值转换为均值为0、方差为1的分布,适合数据分布未知的情况。

这里我们用标准化处理连续型特征:

python 复制代码
# 选择连续型数值特征
numeric_features = ["avg_order_value", "stay_duration"]
# 初始化标准化器
scaler = StandardScaler()
# 拟合并转换特征
df[numeric_features] = scaler.fit_transform(df[numeric_features])
2. 离散型数值特征:保持原样或离散化

离散型特征(比如purchase_count,取值为1-100)的量纲差异小,通常不需要归一化。如果取值范围很大(比如1-1000),可以用离散化(比如分箱)将其转换为类别特征(比如"低购买次数""中购买次数""高购买次数")。

这里purchase_count的取值范围是1-100,我们保持原样:

python 复制代码
# 离散型数值特征(无需处理)
discrete_features = ["purchase_count"]
3. 构造新的数值特征

除了原始数值特征,我们还可以构造统计特征交互特征,提升模型效果。比如:

  • total_spend:总消费金额(purchase_count × avg_order_value);
  • stay_per_purchase:每次购买的平均停留时长(stay_duration / purchase_count)。
python 复制代码
# 构造总消费金额
df["total_spend"] = df["purchase_count"] × df["avg_order_value"]
# 构造每次购买的平均停留时长(避免除以0,加1)
df["stay_per_purchase"] = df["stay_duration"] / (df["purchase_count"] + 1)

步骤三:处理文本特征

文本特征的处理目标是将非结构化的文本转换为结构化的向量,保留语义信息。常见的处理步骤包括:分词、停用词去除、词嵌入。

1. 分词(中文文本的核心步骤)

中文文本没有天然的分隔符(比如英文的空格),需要用分词工具(比如jieba)将句子拆分为词语。

python 复制代码
# 定义分词函数(去除标点符号)
import re
def segment_text(text):
    # 去除标点符号
    text = re.sub(r"[^\w\s]", "", text)
    # 分词
    words = jieba.lcut(text)
    # 去除空字符串
    words = [word for word in words if word.strip()]
    return " ".join(words)

# 对comment字段进行分词
df["comment_seg"] = df["comment"].apply(segment_text)

示例输出:

原始评论:"这个商品质量太差了,再也不买了" → 分词后:"这个 商品 质量 太 差 了 再也 不 买 了"。

2. 去除停用词

停用词是指没有实际语义的词(比如"的""是""了"),会增加特征维度但不提供价值,需要去除。

首先,下载jieba的停用词表(或自定义):

python 复制代码
# 加载停用词表(可以从网上下载,比如哈工大停用词表)
with open("stopwords.txt", "r", encoding="utf-8") as f:
    stopwords = set(f.read().splitlines())

# 定义去除停用词的函数
def remove_stopwords(text):
    words = text.split()
    filtered_words = [word for word in words if word not in stopwords]
    return " ".join(filtered_words)

# 去除停用词
df["comment_seg"] = df["comment_seg"].apply(remove_stopwords)

示例输出:

分词后:"这个 商品 质量 太 差 了 再也 不 买 了" → 去除停用词后:"商品 质量 差 再也 不 买"。

3. 词嵌入(将文本转换为向量)

词嵌入是文本特征处理的核心步骤,常见的方法有:

  • TF-IDF:统计词的频率-逆文档频率,适合短文本(比如商品标题、评论);
  • Word2Vec:将词转换为低维向量,保留语义信息(比如"国王"−"男人"+"女人"="女王");
  • BERT:基于Transformer的预训练模型,能捕捉上下文语义,适合长文本(比如客服聊天记录)。

这里我们用TF-IDF处理评论文本(因为评论是短文本,TF-IDF足够高效):

python 复制代码
# 初始化TF-IDF向量器(最多保留1000个最常见的词)
tfidf = TfidfVectorizer(max_features=1000)
# 拟合并转换评论文本
comment_tfidf = tfidf.fit_transform(df["comment_seg"])
# 将TF-IDF向量转换为DataFrame(方便后续融合)
comment_tfidf_df = pd.DataFrame(comment_tfidf.toarray(), columns=tfidf.get_feature_names_out())

示例输出:
comment_tfidf_df的每一行是一个长度为1000的向量,每个元素表示对应词的TF-IDF值(比如"质量"的TF-IDF值为0.8,"差"的TF-IDF值为0.7)。

步骤四:融合数值与文本特征

融合是混合特征处理的最后一步,目的是将数值特征和文本特征合并为一个统一的特征矩阵,供模型输入。常见的融合方法有:

1. 简单拼接(Concat)

最简单的融合方法是将数值特征的DataFrame和文本特征的DataFrame按列拼接 。这种方法适合数值特征和文本特征独立的场景(比如推荐系统中的用户行为和商品描述)。

python 复制代码
# 选择数值特征(包括原始和构造的)
numeric_features_all = ["purchase_count", "avg_order_value", "stay_duration", "total_spend", "stay_per_purchase"]
# 数值特征DataFrame
numeric_df = df[numeric_features_all]
# 拼接数值特征和文本特征(TF-IDF)
merged_df = pd.concat([numeric_df, comment_tfidf_df], axis=1)

示例输出:
merged_df的 columns 包括:purchase_count(数值)、avg_order_value(数值)、质量(TF-IDF)、(TF-IDF)等,共1005列(5个数值特征+1000个文本特征)。

2. 特征交叉(Feature Cross)

特征交叉是指将数值特征和文本特征进行组合 ,生成新的特征(比如purchase_count × 质量)。这种方法适合数值特征和文本特征有交互作用的场景(比如"购买次数多且评论中提到'质量'的用户,更可能再次购买")。

python 复制代码
# 选择数值特征(比如purchase_count)和文本特征(比如"质量""差")
numeric_feature = "purchase_count"
text_features = ["质量", "差"]
# 生成特征交叉
for text_feature in text_features:
    merged_df[f"{numeric_feature}_×_{text_feature}"] = merged_df[numeric_feature] × merged_df[text_feature]

示例输出:

新增purchase_count_×_质量(购买次数×"质量"的TF-IDF值)、purchase_count_×_差(购买次数×"差"的TF-IDF值)等特征。

3. 注意力机制(Attention)

注意力机制是深度学习中的高级融合方法 ,能自动学习数值特征和文本特征的权重 (比如"评论中的'差'比购买次数更重要")。这种方法适合需要捕捉特征间依赖关系的场景(比如情感分析、推荐系统)。

这里我们用TensorFlow实现一个简单的注意力融合模型:

python 复制代码
import tensorflow as tf
from tensorflow.keras.layers import Input, Dense, Attention, Concatenate
from tensorflow.keras.models import Model

# 定义输入层(数值特征:5维,文本特征:1000维)
numeric_input = Input(shape=(5,), name="numeric_input")
text_input = Input(shape=(1000,), name="text_input")

# 数值特征编码(全连接层)
numeric_encoded = Dense(64, activation="relu")(numeric_input)
# 文本特征编码(全连接层)
text_encoded = Dense(64, activation="relu")(text_input)

# 注意力层(计算数值特征和文本特征的权重)
attention = Attention()([numeric_encoded, text_encoded])
# 融合特征(拼接注意力输出和原始编码)
merged = Concatenate()([attention, numeric_encoded, text_encoded])

# 输出层(二分类)
output = Dense(1, activation="sigmoid")(merged)

# 构建模型
model = Model(inputs=[numeric_input, text_input], outputs=output)
model.compile(optimizer="adam", loss="binary_crossentropy", metrics=["accuracy"])

# 准备输入数据(数值特征和文本特征分开)
X_numeric = merged_df[numeric_features_all].values
X_text = merged_df[comment_tfidf_df.columns].values
y = df["re_purchase"].values

# 划分训练集和测试集
X_numeric_train, X_numeric_test, X_text_train, X_text_test, y_train, y_test = train_test_split(
    X_numeric, X_text, y, test_size=0.2, random_state=42
)

# 训练模型
model.fit(
    [X_numeric_train, X_text_train], y_train,
    epochs=10, batch_size=32,
    validation_data=([X_numeric_test, X_text_test], y_test)
)

# 评估模型
loss, accuracy = model.evaluate([X_numeric_test, X_text_test], y_test)
print(f"Test Accuracy: {accuracy:.4f}")

示例输出:

Test Accuracy: 0.89(比简单拼接的0.82高,说明注意力机制能更好地融合特征)。

步骤五:模型训练与评估

融合后的特征矩阵可以喂给任何机器学习模型(比如逻辑回归、随机森林、XGBoost)或深度学习模型(比如CNN、LSTM)。这里我们用逻辑回归(简单、易解释)进行训练,并评估效果。

python 复制代码
# 准备训练数据(简单拼接的特征矩阵)
X = merged_df.values
y = df["re_purchase"].values

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 训练逻辑回归模型
lr = LogisticRegression(max_iter=1000)
lr.fit(X_train, y_train)

# 预测并评估
y_pred = lr.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")
print(f"F1 Score: {f1_score(y_test, y_pred):.4f}")

示例输出:

Accuracy: 0.82,F1 Score: 0.81(比只使用数值特征的0.75高,说明文本特征的加入提升了模型效果)。

四、进阶探讨/最佳实践 (Advanced Topics / Best Practices)

1. 常见陷阱与避坑指南

  • 陷阱1:数值特征未归一化 :比如avg_order_value(100-10000)和purchase_count(1-100),未归一化会导致模型更重视avg_order_value,而忽略purchase_count的重要性。
    避坑方法:对连续型数值特征进行标准化或归一化。
  • 陷阱2:文本特征过拟合 :比如TF-IDF保留了10000个词,导致特征维度太高,模型在训练集上表现好但测试集上表现差。
    避坑方法 :限制TF-IDF的max_features(比如1000),或用PCA进行降维。
  • 陷阱3:混合特征融合顺序错误 :比如先将数值特征和文本特征拼接,再进行归一化,会导致文本特征的TF-IDF值被缩放(失去语义信息)。
    避坑方法先分别处理数值特征和文本特征,再融合(比如数值特征标准化后,再与文本特征的TF-IDF向量拼接)。

2. 性能优化技巧

  • 文本特征降维 :对于高维的文本特征(比如TF-IDF的1000维),可以用PCA (主成分分析)将其降维到100-200维,减少计算量。

    python 复制代码
    from sklearn.decomposition import PCA
    pca = PCA(n_components=200)
    comment_tfidf_pca = pca.fit_transform(comment_tfidf_df)
  • 数值特征选择 :用互信息 (Mutual Information)或L1正则 (Lasso)选择与标签相关的数值特征,减少冗余。

    python 复制代码
    from sklearn.feature_selection import mutual_info_classif
    mi = mutual_info_classif(numeric_df, y)
    # 选择互信息前3的特征
    top_numeric_features = numeric_df.columns[mi.argsort()[-3:]].tolist()
  • 稀疏矩阵存储 :文本特征的TF-IDF向量是稀疏的(大部分元素为0),用稀疏矩阵 (比如scipy.sparse.csr_matrix)存储,可以节省内存(比如1000维的向量,稀疏矩阵只存储非零元素)。

3. 最佳实践总结

  • 先做EDA:通过数据探索了解特征的分布、缺失值、异常值,为后续处理提供依据;
  • 保留可解释性:比如用TF-IDF而不是BERT(黑盒),方便解释模型的决策(比如"用户评论中的'差'是导致不再次购买的主要原因");
  • 迭代优化:先试简单的方法(比如TF-IDF+简单拼接),再试复杂的方法(比如BERT+注意力机制),逐步提升模型效果;
  • 结合业务场景 :比如在欺诈检测中,收货地址(文本特征)的"异常性"(比如频繁更换地址)比交易金额(数值特征)更重要,需要重点处理文本特征。

五、结论 (Conclusion)

核心要点回顾

混合特征处理的完整流程可以总结为:

  1. 数据探索:发现缺失值、异常值;
  2. 数值特征处理:归一化/标准化、构造新特征;
  3. 文本特征处理:分词、停用词去除、词嵌入;
  4. 特征融合:简单拼接、特征交叉、注意力机制;
  5. 模型训练:用融合后的特征矩阵训练模型。

展望未来/延伸思考

随着大模型(比如GPT-4、Claude 3)的发展,混合特征处理的方式正在发生变化:

  • 统一嵌入:大模型能直接处理文本和数值特征(比如将数值特征转换为文本"购买次数=5",然后输入大模型),减少人工预处理的工作量;
  • 自动特征工程:大模型能自动生成有价值的特征(比如从评论中提取"负面情绪"特征,从数值中提取"高消费用户"特征);
  • 端到端训练:大模型能直接从原始数据(文本+数值)中学习,不需要人工特征处理(比如用GPT-4预测用户是否会再次购买,输入是"购买次数=5,平均客单价=500,评论='质量太差了'")。

行动号召

现在,轮到你动手实践了!

  1. 下载一个包含混合特征的数据集(比如Kaggle的Amazon Reviews Dataset);
  2. 按照本文的流程处理数值特征和文本特征;
  3. 尝试不同的融合方法(简单拼接、注意力机制),比较模型效果;
  4. 在评论区分享你的实践经验,或提出你的问题------我会一一解答!

参考资源

最后 :混合特征处理不是"银弹",没有放之四海而皆准的方法。关键是理解业务场景结合数据特点迭代优化。希望这篇文章能帮你解决混合特征处理的痛点,让你的模型更"懂"数据!

相关推荐
发哥来了5 小时前
主流AI视频生成商用方案选型:关键维度与成本效益分析
大数据·人工智能
2501_933670795 小时前
2026高职大数据技术专业应届生就业方向分析
大数据
专注API从业者5 小时前
淘宝商品 API 接口架构解析:从请求到详情数据返回的完整链路
java·大数据·开发语言·数据库·架构
龙亘川5 小时前
GB4599-2024 落地!汽车照明迎重大升级,自适应功能 + 辅助投射成安全新标配~
大数据·人工智能·安全·汽车
小宇的天下5 小时前
Calibre :Standard Verification Rule Format(SVRF) Manual (1-1)
大数据·前端·网络
充气大锤5 小时前
前端实现流式输出配合katex.js
开发语言·前端·javascript·ai·vue
黄焖鸡能干四碗6 小时前
智慧电力解决方案,智慧电厂解决方案,电力运维方案
大数据·人工智能·安全·需求分析
装不满的克莱因瓶6 小时前
【Dify实战】情感陪伴机器人 从零制作教程
人工智能·ai·agent·agi·dify·智能体
belldeep6 小时前
比较 RPA 与 AI Agent 的异同,两者有何关系?
人工智能·ai·agent·rpa