第二章:数据基础——产业链数据来源、清洗与存储

做量化分析,最怕什么?不是模型不灵,而是数据本身就有问题。我见过太多人花三个月搭模型,最后发现是原始数据里有个字段对不齐。嗯,这一章我们就聊聊数据基础——说白了,就是你的分析地基。

2.1 产业链数据从哪里来?

能源化工产业链的数据源,我把它分成三类:公开数据、行业数据库、爬虫。每一类都有它的脾气。

2.1.1 公开数据

公开数据是最容易拿到的,但也是最需要小心的。比如国家统计局、发改委、海关总署这些官网,会发布原油产量、炼厂开工率、进出口量等数据。我个人习惯是优先用这些官方数据,因为权威性高。

但有个坑——更新频率不统一。有的按月,有的按季度,甚至有的按年。你想想看,做日频模型的人拿到月频数据,怎么对齐?

我的经验:公开数据适合做宏观背景校验,不适合做高频交易信号。我曾在项目里用海关月度数据去拟合周度价格波动,结果惨不忍睹。

2.1.2 行业数据库

行业数据库是主力。像隆众资讯、卓创资讯、百川盈孚这些,覆盖了从原油到化工品的全链条数据。价格、库存、开工率、利润……基本都有。

这类数据质量相对稳定,但价格不便宜。我记得有一次客户预算有限,只买了三个品种的数据,结果分析时发现缺少上下游联动数据,模型效果大打折扣。

数据库名称 覆盖品种 更新频率 价格水平
隆众资讯 原油、成品油、化工品 日/周/月 中等
卓创资讯 能源、化工、塑料 日/周 中等偏高
百川盈孚 煤化工、化肥、氯碱 周/月 中等

2.1.3 爬虫获取数据

有些数据公开数据库没有,或者更新太慢,那就得自己动手爬。比如一些现货交易平台的实时报价、港口库存的公告信息。

我曾经爬过一个化工品交易平台的报价数据,每天定时跑一次。但要注意——爬虫有法律风险,而且网站反爬措施越来越严。我的建议是:能买到的数据尽量买,爬虫只用来补充非核心数据

警告:爬取数据前务必确认网站的robots.txt和使用条款。我见过同行因为爬取商业数据被发律师函,得不偿失。

2.2 数据清洗与预处理

数据拿到手,第一件事不是建模,而是清洗。我常说一句话:垃圾进,垃圾出。再好的模型也救不了脏数据。

2.2.1 常见的数据问题

  • 缺失值:某个品种的库存数据突然少了一周,怎么办?
  • 异常值:价格突然跳涨10倍,是数据错误还是市场异动?
  • 重复值:同一时间点出现两条相同记录。
  • 格式不一致:有的日期是"2024-01-01",有的是"2024/1/1"。

为什么会这样?很多时候是数据源本身的问题。比如行业数据库的录入员手误,或者爬虫程序在某个时间点重复抓取。

2.2.2 清洗流程

我一般按这个顺序处理:

  1. 去重:检查并删除完全重复的行
  2. 格式统一:日期、数值、单位全部标准化
  3. 缺失值处理:根据业务逻辑选择填充或删除
  4. 异常值检测:用3σ或IQR方法识别
  5. 对齐时间戳:不同频率的数据统一到同一时间轴

核心原则:清洗逻辑必须可复现。不要手动改数据,要用代码记录每一步操作。这样出了问题还能回溯。

2.2.3 代码示例

下面是我常用的清洗函数,用pandas实现:

import pandas as pd
import numpy as np

def clean_energy_data(df):
    # 1. 去重
    df = df.drop_duplicates()
    
    # 2. 日期统一
    df['date'] = pd.to_datetime(df['date'])
    
    # 3. 缺失值处理(向前填充,最多填充3天)
    df = df.fillna(method='ffill', limit=3)
    
    # 4. 异常值检测(3σ法)
    for col in ['price', 'inventory']:
        mean = df[col].mean()
        std = df[col].std()
        df[col] = df[col].clip(mean - 3*std, mean + 3*std)
    
    return df

这段代码看起来简单,但我在实际项目中踩过坑。比如向前填充——如果连续缺失超过3天,说明数据源可能出了问题,这时候填充反而会掩盖问题。

2.3 数据存储:SQLite还是CSV?

数据清洗完了,得找个地方存起来。我常用的两种方式:SQLite和CSV。各有各的适用场景。

2.3.1 CSV:简单直接

CSV的好处是轻量、通用、任何人都能打开。适合小规模数据(几万行以内)或者临时分析。

但缺点也很明显:没有索引,查询慢;不支持并发写入;容易损坏。我曾经用CSV存了半年的日频数据,结果有一次程序崩溃,文件写到一半就坏了,损失了两周的数据。

建议:CSV只用来做数据交换或备份,不要作为主力存储方式。

2.3.2 SQLite:轻量级数据库

SQLite是我个人最推荐的方式。它不需要安装服务器,一个文件就是一个数据库,支持SQL查询,性能也够用。

对于能源化工产业链的数据,我一般这样设计表结构:

-- 品种信息表
CREATE TABLE products (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    category TEXT,
    unit TEXT
);

-- 价格数据表
CREATE TABLE prices (
    product_id INTEGER,
    date TEXT,
    price REAL,
    source TEXT,
    FOREIGN KEY (product_id) REFERENCES products(id)
);

-- 库存数据表
CREATE TABLE inventory (
    product_id INTEGER,
    date TEXT,
    inventory REAL,
    location TEXT,
    FOREIGN KEY (product_id) REFERENCES products(id)
);

这样设计的好处是:品种信息只存一次,价格和库存分开存储,查询时用JOIN关联。效率比CSV高得多。

2.3.3 如何选择?

场景 推荐方式 原因
单次分析、数据量小 CSV 简单快速,无需额外工具
长期存储、频繁查询 SQLite 支持SQL,数据完整性强
团队协作、多用户访问 PostgreSQL 支持并发,但超出本章范围

2.4 知识体系框架

下面这张图,是我对本章知识结构的总结。你可以把它当作一个思维导图来看:

数据基础 数据来源 公开数据(统计局、海关) 行业数据库(隆众、卓创) 爬虫(交易平台、公告) 数据清洗与预处理 去重 → 格式统一 缺失值处理 → 异常值检测 时间戳对齐 → 可复现逻辑 数据存储 CSV(轻量、临时) SQLite(长期、查询) 表结构设计(外键关联) 数据质量决定模型上限

这张图把数据基础分成了三条线:来源、清洗、存储。三者缺一不可。我见过太多人只关注模型算法,却忽略了数据本身。记住一句话:数据质量决定模型上限

避坑指南:我曾经在一个项目中,花了两个月搭建LSTM模型,结果预测效果一直不好。最后排查发现,原始数据里有一个品种的单位是"吨",另一个是"千克",但字段名完全一样。这种低级错误,往往是最致命的。

好了,数据基础就聊到这里。下一章我们会进入量化模型的核心——特征工程。但在此之前,先把数据基础打牢。你想想看,地基不稳,楼盖得再高也是白搭。


蓝海数据掘金营,专注资料整理