2. 数据接入与探索性分析
特征工程的质量,很大程度上取决于我们对原始数据的理解深度。在 Databricks 平台上,数据可能来自 DBFS 文件、Delta Lake 表、外部 JDBC 数据库或云对象存储(如 S3、ADLS、GCS)。本节的目标不是立刻开始构造特征,而是先把这些异构数据源统一接入 Spark,完成数据概览、缺失值分析、分布统计与可视化,最终形成一份"可信、可解释、可追溯"的原始数据集,为后续特征工程提供稳定输入。
一、四类数据源的接入方式与选择依据
Databricks 的读取能力可以概括为"统一入口、按源适配"。无论数据来自哪里,最终都通过 Spark DataFrame 或 Spark SQL 表的形式参与后续分析。
- DBFS 文件:适合 CSV、Parquet、JSON 等落地文件。使用
spark.read.format("parquet").load("/FileStore/raw/orders/")即可读取;若为 CSV,需显式指定header、inferSchema或自定义 schema,避免类型推断带来的隐性错误。 - Delta Lake 表:生产环境首选。Delta 自带事务日志、Schema 演进与时间旅行能力,读取时可直接
spark.read.table("silver.user_profile"),也可用versionAsOf回溯历史版本,便于排查数据异常。 - JDBC 数据源:对接 MySQL、PostgreSQL、SQL Server 等业务库。关键参数包括
url、dbtable、user、password、numPartitions、partitionColumn、lowerBound、upperBound。合理设置分区列可让并行读取真正生效,否则会退化为单分区全表扫描。 - 云存储:通过
s3a://、abfss://、gs://等协议访问。需要提前在集群或 Notebook 中挂载凭证,或使用 Unity Catalog 的 External Location 统一管理权限。
选择依据可以简单归纳为:结构化且需事务保障选 Delta;外部业务库选 JDBC;批量文件选 DBFS 或云存储;跨云共享选云存储 + 外部表。接入阶段就要记录数据来源、读取时间、Schema 版本,这些元信息在后续特征回溯时非常关键。
二、数据概览:先看清"有什么"
接入后第一步是概览。常用手段包括 df.printSchema() 查看字段与类型、df.count() 获取行数、df.show(5) 抽样观察、df.describe().show() 得到数值列的 count/mean/stddev/min/max。对于宽表,建议用 Spark SQL 一次性输出字段清单:
SELECT column_name, data_type
FROM system.information_schema.columns
WHERE table_name = 'raw_orders';
概览阶段要重点关注三类信号:字段类型是否符合预期(如金额被读成 string)、主键/时间字段是否存在空值、分区字段是否与业务日期一致。这些信号会直接影响后续特征构造的可行性。
三、缺失值分析:从"有多少"到"为什么"
缺失值分析不能只统计比例,还要区分缺失模式。常用做法是对每个字段计算缺失率,并按缺失率排序:
from pyspark.sql import functions as F
missing = df.select([
(F.count(F.when(F.col(c).isNull(), c)) / F.count("*")).alias(c)
for c in df.columns
])
missing.show()
如果某字段缺失率超过 60%,通常需要与业务确认是否保留;若缺失集中在特定时间段或特定渠道,则可能是采集链路问题而非随机缺失。对于关键特征字段,建议同时输出"缺失 + 异常"联合视图,例如金额为负、年龄超过 120、时间戳早于系统上线日期等,这些都会在特征工程阶段被放大。
四、分布统计与可视化:判断特征是否可用
分布统计的目标是判断特征是否偏态、是否存在极端值、类别是否极度不平衡。数值列可计算分位数(如 P1、P25、P50、P75、P99),类别列可统计 Top-N 频次。Databricks Notebook 内置 display() 可直接渲染直方图、箱线图与散点图,无需额外引入可视化库。
例如对用户年龄做分桶统计:
display(df.groupBy(F.floor(F.col("age") / 10) * 10).count().orderBy("floor(age / 10) * 10"))
观察结果时,若某类别占比超过 95%,独热编码后会产生大量稀疏列,此时应考虑目标编码或频次编码;若数值列呈长尾分布,后续标准化前可能需要先做对数变换。可视化不是装饰,而是为特征变换决策提供依据。
五、形成原始数据集:落盘与元信息记录
探索完成后,建议将清洗后的原始数据以 Delta 格式写入特征工程的输入区,例如 /mnt/feature/raw/orders_v1。写入时保留原始字段,不做业务变换,只做必要的类型修正与去重。同时记录一份元信息表,包含数据源、读取时间、行数、字段数、缺失率摘要、Schema 版本。这样在后续特征回溯或模型复现时,可以快速定位输入数据的来源与状态。
partitionColumn 与上下界,Spark 会使用单分区读取,大表可能耗时数小时。务必先用 EXPLAIN 或 Spark UI 确认并行度。完成本节后,我们得到的不只是一份数据,更是一份对数据"脾气"的理解:哪些字段可靠、哪些字段需要谨慎处理、哪些分布会影响后续编码与变换。这些判断将直接决定特征工程阶段的技术选型与验证策略。