17 处理另类数据:图像与声音

本章学习目标

  • 理解应用: 认识到图像与声音数据在现代金融市场中的巨大潜力。
  • 掌握工具: 学习卷积神经网络(CNN)的核心原理,用以从图片中提取价值。
  • 拓宽视野: 了解音频信息在金融分析中的独特作用与处理方法。
  • 实践技能: 通过完整的Python代码实例,掌握预训练模型在图像识别任务中的应用。

追寻阿尔法:信息优势的探求

在金融市场,我们的核心目标是获得超越市场平均回报的超额收益,即“阿尔法”(\(\alpha\))。

而阿尔法的源泉,正是信息优势 (Informational Edge)

从数据到阿尔法的流程 一个三步流程图,展示了如何从数据通过分析和决策最终获得阿尔法(超额收益)。 数据 分析 洞见 决策 阿尔法 (α)

传统信息的困境

我们追求信息优势,但传统信息源的价值正在被快速稀释。

  • 私有信息 (Private Information)
    • 效果最好,但往往涉及内幕交易,存在严重的法律与合规风险。
  • 公开信息 (Public Information)
    • 例如公司财报、宏观经济数据。
    • 根据有效市场假说,其价值通常已迅速反映在资产价格中。

那么,新的优势从何而来?

另类数据:信息优势的新来源

答案在于:对公开数据进行更精细、更独特的处理

这就是另类数据 (Alternative Data) 的核心价值。我们并非去获取秘密信息,而是用更强大的工具,从海量的、公开的、非传统的数据源中,提炼出独到的洞见。

另类数据来源 展示了四种另类数据的来源:卫星图像、交易数据、社交媒体和网络抓取。 卫星图像 交易数据 社交媒体 网络抓取

文字之外:一个充满信息的世界

虽然文本分析至关重要,但信息传播远不止于文字。这些视觉与听觉数据,为我们提供了更直观、更及时的洞察。

图像数据

  • 卫星与无人机影像
    • 预测零售商业绩(停车场车辆)
    • 监控工业产出(工厂烟雾)
    • 判断原油供需(油轮动向)

声音数据

  • 高管采访与业绩会议
    • 分析情绪(自信/紧张)
    • 检测欺诈信号(声音微特征)
    • 快速获取关键信息(语音转文字)

机器学习:解锁另类数据的钥匙

这些图像、声音数据是非结构化的,传统计量经济学方法难以处理。

深度学习模型,特别是我们今天要学习的卷积神经网络 (CNN),是解锁这些数据价值的关键。它们能自动从原始数据中学习和提取有意义的模式。

机器学习处理非结构化数据 流程图显示非结构化数据通过机器学习模型转化为结构化洞见。 非结构化数据 (图像, 声音) 机器学习模型 (CNN) 结构化洞见 (预测, 分类)

第一部分:图像数据及处理

图像中蕴含的经济信号

一张图片胜过千言万语,在金融领域尤其如此。

案例:利用卫星图像预测零售商业绩

  1. 数据采集: 对冲基金获取目标零售商(如沃尔玛)停车场的高频卫星图像。
  2. 模型分析: 使用图像识别模型自动计数停车场内的汽车数量。
  3. 信号提取: 汽车数量的变化趋势,可以作为预测该公司季度销售额和客流量的高频领先指标
  4. 交易决策: 在官方财报发布前,根据该信号调整投资组合,从而获得信息优势。

另一个经典应用:库存清点

  • 验证数据: 租用飞机或卫星拍摄零售商仓库,快速验证官方库存数据的准确性,抢先判断其销售状况。
  • 自动盘点: 训练机器学习模型对库存商品进行自动识别和计数,实现大规模、高效率的库存监控。
库存清点概念图 一张仓库图片通过AI模型处理后,输出了被识别和计数的商品。 仓库原始图像 AI 模型 识别与计数结果 商品A (蓝色): 2件 商品B (红色): 2件 商品C (黄色): 1件

本章案例:识别货架上的电器

我们的代码实践任务是:让计算机自动识别出照片中的电视、微波炉和烤箱。

import matplotlib.pyplot as plt
from PIL import Image
import requests
from io import BytesIO

# 使用一个稳定的URL来加载图片,确保代码可复现
try:
    url = 'https://upload.wikimedia.org/wikipedia/commons/3/33/Dacor-Distinctive-Appliances-display.jpg'
    response = requests.get(url, timeout=10)
    img_pil = Image.open(BytesIO(response.content))

    plt.imshow(img_pil)
    plt.axis('off')
    plt.show()
except Exception as e:
    fig, ax = plt.subplots()
    ax.text(0.5, 0.5, '图像加载失败\n请检查网络连接', 
            horizontalalignment='center', verticalalignment='center',
            fontsize=12, color='red')
    ax.set_xticks([])
    ax.set_yticks([])
    plt.show()
Figure 1: 我们将要分析的货架图像

核心工具:卷积神经网络 (CNN)

要让机器理解图片,我们主要使用卷积神经网络 (Convolutional Neural Network, CNN)

在深入其内部结构之前,我们先建立一个直观的认识:计算机如何“看待”图像?

计算机眼中的图像:像素与通道

  • 像素 (Pixel): 图像的基本单位,每个像素代表图像中一个点。
  • 通道 (Channel):
    • 灰度图: 只有一个通道,每个像素值代表亮度 (0=黑, 255=白)。
    • 彩色图 (RGB): 有三个通道(红、绿、蓝),每个像素由三个数值组成,代表三种颜色的强度。
RGB像素表示 一个放大的像素网格,展示了一个像素如何由红、绿、蓝三个通道值组成。 图像由像素网格组成 单个像素由RGB值构成 R: 210 G: 80 B: 30

图像的矩阵表示

对于计算机,一张灰度图就是一个由数字组成的矩阵。每个数字代表一个像素的亮度。

例如,我们可以用 5x5 的矩阵,清晰地表示字母 ‘O’ 和 ‘X’。

字母O和X的矩阵表示 两个5x5的矩阵,用0和1表示像素,分别构成了字母O和X的形状。 字母 O 的矩阵表示 0 1 1 1 0 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 0 1 1 1 0 字母 X 的矩阵表示 1 0 0 0 1 0 1 0 1 0 0 0 1 0 0 0 1 0 1 0 1 0 0 0 1

CNN 的三大核心构建模块

最简单的CNN模型,可以看作是由三个核心部件按顺序组装起来的“信息处理流水线”。

CNN核心模块流程图 流程图显示输入图像依次通过卷积层、池化层和全连接层,最终输出结果。 输入图像 1. 卷积层 特征提取 2. 池化层 降采样 📉 3. 全连接 分类 🎯

模块一:卷积层 (Convolutional Layer)

  • 目标:从原始图片中检测出基础的特征 (Features)
  • 什么是特征? 图像的局部模式,例如边缘、角落、纹理、颜色块等。
图像特征示例 展示了三种基本图像特征:垂直边缘、水平边缘和角落。 垂直边缘 水平边缘 角落

卷积层的工具:卷积核 (Kernel)

卷积核 (或称滤波器 Filter) 是一个很小的矩阵 (例如 3x3),它被设计用来识别一种特定的微观模式。

  • 卷积层的工作,就是让这个小的卷积核,在大的输入图像上滑动 (Slide),并进行计算。
  • 它的参数(矩阵中的数值)通过模型训练不断学习和优化,最终变得能够识别有意义的特征。

图解卷积运算

下图展示了一个 5x5 输入图像和一个 2x2 卷积核。卷积核从左上角开始,在输入图像上滑动。

卷积运算图解 一个2x2的卷积核覆盖在一个5x5的输入图像的左上角,准备进行计算。 输入图像 (5x5) 0 1 1 1 0 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 0 1 1 1 0 卷积核 (2x2) 1 0 0 1

卷积运算步骤

在每个位置,执行元素级相乘 (element-wise product),然后将所有结果求和

位置 1 (左上角): (0×1) + (1×0) + (1×0) + (0×1) = 0

卷积运算步骤1 展示卷积核在第一个位置的计算过程和结果。 0 1 1 1 0 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 0 1 1 1 0 1 00 1 = (0×1)+(1×0)+(1×0)+(0×1) = 0

滑动与重复

卷积核向右滑动一个单位 (步长 Stride = 1),覆盖新的区域,并重复运算。

位置 2: (1×1) + (1×0) + (0×0) + (0×1) = 1

卷积运算步骤2 展示卷积核在第二个位置的计算过程和结果。 0 1 1 1 0 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 0 1 1 1 0 1 00 1 = (1×1)+(1×0)+(0×0)+(0×1) = 1

卷积层的产物:特征图 (Feature Map)

当卷积核遍历完整个输入图像后,会得到一个新的、尺寸稍小的矩阵,这就是特征图 (Feature Map)

  • 特征图是原始图像的“浓缩摘要”。
  • 它的每个像素值,都代表原始图像对应区域与该卷积核所寻找的特定模式的匹配程度。值越大,匹配度越高。
特征图生成 流程图显示输入图像经过卷积核处理后生成特征图。 输入图像 (5x5) 0 1 1 1 01 0 0 0 11 0 0 0 1 1 0 0 0 10 1 1 1 0 卷积核 [1 0; 0 1] 特征图 (4x4) 0 1 1 2 1 0 0 1 1 0 0 1 2 1 1 0

一个卷积层,多个卷积核

一个卷积核只能检测一种特征。为了识别多种特征(横线、竖线、曲线等),一个卷积层通常包含多个不同的卷积核。

  • 每一个卷积核都会生成一个自己独立的特征图。
  • 因此,一个卷积层的输出是一叠(多个)特征图,共同描绘了原始图像的多种基础特征。
多卷积核与特征图堆栈 一张输入图像被三个不同的卷积核处理,生成了三张堆叠在一起的特征图。 输入图像 核 1 核 2 核 3 特征图堆栈

重要细节:激活函数 (Activation)

在生成特征图后,通常会使用一个激活函数,最常用的是 ReLU (Rectified Linear Unit)

\[ \large{ReLU(x) = \max(0, x)} \]

  • 作用: 它会把特征图里所有的负数值都变为0,保留正数值。
  • 目的: 为模型引入非线性 (non-linearity),使得神经网络能够学习更复杂的模式。可以简单理解为“只关注那些显著匹配的特征,忽略不匹配的”。

可选细节:填充(Padding)与步长(Stride)

  • 填充 (Padding)
    • 在输入图像的边缘添加额外的像素(通常是0)。
    • 目的: 保持输出特征图的尺寸与输入图像相同;更好地处理图像边缘的特征。
  • 步长 (Stride)
    • 卷积核每次滑动的像素数。
    • 目的: 步长大于1可以减小输出特征图的尺寸,实现降采样。

模块二:池化层 (Pooling Layer)

  • 目标: 对特征图进行降采样 (Downsampling)
  • 两大目的:
    1. 减少计算量: 特征图尺寸变小,后续计算更快。
    2. 特征不变性 (Invariance): 让模型对特征在图像中的微小位置变化不那么敏感,从而提高模型的稳健性。

特征不变性直观理解

无论猫在图片的左边还是右边,它仍然是一只猫。池化操作帮助模型忽略这种微小的空间位置差异,更专注于特征本身是否存在。

特征不变性 两张图片,一张猫在左边,一张猫在右边,经过池化层后都得到相似的特征表示。 😺 池化 F 😺 池化 F 相似的特征表示

池化的操作过程

与卷积类似,池化窗口 (通常2x2) 在特征图上滑动,但没有重叠。它对每个窗口内的数值进行聚合。

池化操作过程 一个4x4的特征图被四个不重叠的2x2池化窗口覆盖。 4x4 特征图被 2x2 池化窗口覆盖 0 1 1 2 1 0 0 1 1 0 0 1 2 1 1 0

池化的两种主要方法

  1. 最大池化 (Max Pooling): 取池化窗口内所有元素的最大值。最常用
  2. 平均池化 (Average Pooling): 取池化窗口内所有元素的平均值。

直观理解: 最大池化可以看作是“只保留每个小区域内最显著的特征信号”。

最大池化实例

对之前的特征图采用最大池化: max(0,1,1,0) = 1 max(1,2,0,1) = 2 max(1,0,2,1) = 2 max(0,1,1,0) = 1

最终得到一个 2x2 的池化后矩阵:

1 2
2 1

尺寸从 4x4 降为 2x2,计算量减少了75%!

模块三:全连接层 (Fully Connected Layer)

目标: 在经过多轮“卷积-池化”提取出高级特征后,做出最终的分类预测

  • 输入: 最后的池化层输出被“压平”(Flatten) 成一个长向量。
  • 结构: 本质上就是一个标准的前馈神经网络。
  • 输出: 对于分类任务,它会输出一个概率分布,表明输入图像属于每个类别的概率。
全连接层 池化后的特征图被压平送入全连接神经网络进行分类。 池化层输出 压平 特征向量 输出概率 电视: 0.90 烤箱: 0.08 其他: 0.02

CNN 的完整训练流程

训练过程是一个不断迭代优化的循环。

CNN训练流程 一个循环图展示了CNN训练的四个步骤:前向传播、计算损失、反向传播和更新参数。 1. 前向传播 输入图片,得到预测 2. 计算损失 比较预测与真实标签 3. 反向传播 计算误差梯度 4. 参数更新 优化网络权重

真实世界的复杂模型:AlexNet

实际应用的CNN模型会堆叠多个卷积层和池化层,以学习从低级到高级的层级化特征。

  • AlexNet (2012): 深度学习领域的里程碑,证明了深层CNN在复杂图像识别任务上的巨大潜力。
简化的AlexNet结构 流程图展示了AlexNet中多个卷积层和池化层堆叠的结构。 输入 Conv1 Pool1 Conv2 Pool2 Conv3 Conv4 Conv5 Pool3 FC 输出

挑战:识别图像中的多个物体

在金融应用中,我们往往需要识别和计数多个物体。例如,清点整个货架的库存,而不是为每件商品单独拍照。

这需要更高级的模型,能够同时完成物体定位 (Localization)分类 (Classification)

高级模型:R-CNN vs. YOLO

R-CNN (Region-based CNN)

两步法: 1. 区域提议: 先用算法找出可能包含物体的候选区域。 2. 分类: 再对每个区域运行CNN进行分类。

缺点: 速度较慢。

R-CNN流程 1. 提议区域 2. 逐个分类 CNN CNN 物体A 物体B

YOLO (You Only Look Once)

一步法: 1. 将物体定位和识别合并到一个单一的神经网络中完成。

优点: 速度极快,适合实时应用。

YOLO流程 一步完成定位与分类 YOLONetwork 物体A 物体B

第二部分:代码实践——用PyTorch进行图像识别

实践目标与策略

  • 目标: 自动识别 Figure 1 中的电器。
  • 策略: 我们将使用一个在大型图像数据集 (COCO) 上预训练 (pre-trained) 好的 Faster R-CNN 模型。

什么是预训练模型?

预训练模型是在海量数据集(如包含数百万张图片的ImageNet或COCO)上已经训练好的模型。

为什么要使用它?

  1. 节省时间与算力: 从零开始训练一个深度模型需要数天甚至数周,以及昂贵的硬件。
  2. 性能更优: 模型已经从海量数据中学到了通用的图像特征(边缘、纹理等),我们只需在其基础上进行微调或直接使用,就能在自己的任务上获得很好效果。
预训练模型概念 一个大脑图标代表预训练模型,它已经包含了从海量数据中学到的通用知识,并能应用于特定任务。 海量数据 (COCO) 🚗🏠 🍌🐘 大规模训练 预训练模型 (通用知识) 直接应用 我们的任务 📺

我们的代码流程

  1. 环境准备: 导入必要的 Python 库。
  2. 数据加载: 从网络URL下载并准备图像。
  3. 模型加载: 加载 PyTorch 中预训练好的 Faster R-CNN 模型。
  4. 数据预处理: 将图像转换为模型所需的张量 (Tensor) 格式。
  5. 执行预测: 将张量输入模型,获取预测结果。
  6. 结果可视化: 将模型识别出的边界框和标签绘制在原始图像上。

步骤 1:导入必要的 Python 库

#| label: code-imports
#| code-line-numbers: true

# PyTorch核心库和图像处理工具
import torch
import torchvision.models as models
from torchvision import transforms

# 图像处理和绘图库
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib.patches as patches

# 用于从网络下载图片的库
import requests
from io import BytesIO

步骤 2:下载并准备图像

为了让代码可复现,我们直接从网络URL加载图片,而不是依赖本地文件。

#| label: code-load-image

# 一个公开、稳定的货架图片URL
url = 'https://upload.wikimedia.org/wikipedia/commons/3/33/Dacor-Distinctive-Appliances-display.jpg'

# 使用try-except块来处理可能的网络错误
try:
    response = requests.get(url)
    response.raise_for_status() # 如果请求失败则抛出异常
    img_pil = Image.open(BytesIO(response.content))

    # 显示下载的图片
    plt.imshow(img_pil)
    plt.title("Downloaded Image")
    plt.axis('off')
    plt.show()
except requests.exceptions.RequestException as e:
    print(f"图像下载失败: {e}")

步骤 3:加载预训练的 Faster R-CNN 模型

pretrained=True 是关键,它告诉 PyTorch 加载已经在大规模数据集上训练好的权重。

#| label: code-load-model

# 加载基于 ResNet50 骨干网络的 Faster R-CNN 模型
# pretrained=True 会自动下载并加载预训练权重
model = models.detection.fasterrcnn_resnet50_fpn(pretrained=True)

# 将模型设置为评估模式 (evaluation mode)
# 这会关闭 Dropout 和 BatchNorm 等只在训练时使用的层,确保预测结果的确定性
model.eval()

步骤 4:定义图像预处理操作

模型需要的输入不是原始的PIL图像,而是特定格式的张量 (Tensor)

#| label: code-transform

# 定义一个转换流程:将PIL图像转换为PyTorch张量
transform = transforms.Compose([
    transforms.ToTensor(), 
])

# 应用转换
img_tensor = transform(img_pil)

# 打印张量的形状,理解其结构
# 输出应为 [通道数, 高度, 宽度],例如
print(f"图像张量的形状: {img_tensor.shape}")

transforms.ToTensor() 会将图像的像素值从 [0, 255] 范围归一化到 [0.0, 1.0],并调整维度顺序。

步骤 5:准备模型输入并进行预测

模型期望的输入是一个 batch(一批)图像,所以我们需要为单个图像增加一个批次维度。

#| label: code-predict

# 使用 unsqueeze(0) 在最前面增加一个维度: [C, H, W] -> [1, C, H, W]
input_batch = img_tensor.unsqueeze(0)

# 使用 torch.no_grad() 来关闭梯度计算,这在推理(预测)时可以节省内存和计算资源
with torch.no_grad():
    prediction = model(input_batch) # 直接获取第一个(也是唯一一个)结果

# prediction 是一个字典,包含了检测结果
# print(prediction.keys()) # dict_keys(['boxes', 'labels', 'scores'])

步骤 6:定义类别名称

模型的输出标签是数字编码。我们需要一个字典来将这些数字映射回人类可读的物体名称。我们只定义我们关心的几个类别。

#| label: code-coco-map

# COCO 数据集的部分类别名称
# 模型的输出是一个数字,我们用这个字典来查找对应的名称
COCO_INSTANCE_CATEGORY_NAMES = {
    72: 'tv', 73: 'laptop', 74: 'mouse', 75: 'remote', 76: 'keyboard',
    77: 'cell phone', 78: 'microwave', 79: 'oven', 80: 'toaster',
    81: 'sink', 82: 'refrigerator'
}

步骤 7:编写可视化函数

我们编写一个函数,将预测结果(边界框、标签、置信度分数)绘制到原始图像上。

#| label: code-show-detections-def
#| code-line-numbers: true

def show_detections(image, prediction, threshold=0.5):
    fig, ax = plt.subplots(1, figsize=(12, 9))
    ax.imshow(image)

    boxes = prediction['boxes']
    labels = prediction['labels']
    scores = prediction['scores']

    for i in range(len(boxes)):
        score = scores[i]
        # 只显示置信度高于阈值的检测结果
        if score > threshold:
            box = boxes[i].cpu().numpy()
            label_id = labels[i].item()
            label_text = COCO_INSTANCE_CATEGORY_NAMES.get(label_id, f'Label {label_id}')
            
            x1, y1, x2, y2 = box
            # 创建一个矩形框
            rect = patches.Rectangle((x1, y1), x2 - x1, y2 - y1, 
                                     linewidth=2, edgecolor='lime', facecolor='none')
            ax.add_patch(rect)
            
            # 在矩形框左上角添加标签和分数
            ax.text(x1, y1 - 5, f'{label_text} {score:.2f}',
                    bbox=dict(facecolor='yellow', alpha=0.5), fontsize=10, color='black')
    
    plt.axis('off')
    plt.show()

步骤 8:运行并展示最终结果!

现在,调用我们定义的函数,传入原始图片和模型的预测结果。

Code
# Re-run all necessary code for this final chunk to be self-contained
import torchvision.models as models
from torchvision import transforms
import torch
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from PIL import Image
import requests
from io import BytesIO

def show_detections_final(image, prediction_list, threshold=0.5):
    fig, ax = plt.subplots(1, figsize=(12, 9))
    ax.imshow(image)
    coco_names = {72: 'tv', 73: 'laptop', 74: 'mouse', 75: 'remote', 76: 'keyboard', 77: 'cell phone', 78: 'microwave', 79: 'oven', 80: 'toaster', 81: 'sink', 82: 'refrigerator'}
    prediction = prediction_list # The model returns a list with one dict
    if not prediction or 'boxes' not in prediction: return
    boxes, labels, scores = prediction['boxes'], prediction['labels'], prediction['scores']
    for i in range(len(boxes)):
        score = scores[i]
        if score > threshold:
            box = boxes[i].cpu().numpy()
            label_id = labels[i].item()
            label_text = coco_names.get(label_id, f'Label {label_id}')
            x1, y1, x2, y2 = box
            rect = patches.Rectangle((x1, y1), x2 - x1, y2 - y1, linewidth=2, edgecolor='lime', facecolor='none')
            ax.add_patch(rect)
            ax.text(x1, y1 - 5, f'{label_text} {score:.2f}', bbox=dict(facecolor='yellow', alpha=0.5), fontsize=10, color='black')
    plt.axis('off')
    plt.show()

# Execute the full pipeline
try:
    url = 'https://upload.wikimedia.org/wikipedia/commons/3/33/Dacor-Distinctive-Appliances-display.jpg'
    response = requests.get(url, timeout=10)
    response.raise_for_status()
    img_pil = Image.open(BytesIO(response.content))
    model = models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
    model.eval()
    transform = transforms.Compose([transforms.ToTensor()])
    img_tensor = transform(img_pil)
    input_batch = img_tensor.unsqueeze(0)
    with torch.no_grad():
        prediction = model(input_batch)
    # Set a high threshold to show only confident predictions
    show_detections_final(img_pil, prediction, threshold=0.7)
except Exception as e:
    print(f"代码执行出错: {e}")
代码执行出错: 403 Client Error: Forbidden for url: https://upload.wikimedia.org/wikipedia/commons/3/33/Dacor-Distinctive-Appliances-display.jpg
Figure 2

解读结果与局限

结果解读: 大家看,结果非常惊人。模型不仅准确地识别出了微波炉 (microwave) 和烤箱 (oven),还给出了每个识别结果的置信度分数

模型的局限: - 类别限制: 模型只能识别出它在训练数据(COCO数据集)中见过的物体。 - 识别错误: 对于不常见的物体或复杂的场景,模型可能会出错或漏检。 - 下一步: 如果需要在特定领域(如识别特定型号的工业零件)获得更高精度,我们可以对预训练模型进行微调 (Fine-tuning)

第三部分:知识拓展——用图片预测股市回报

传统智慧:技术分析

长久以来,金融从业者都试图通过分析股市回报的图表 (Charts) 来预测未来走势,这被称为技术分析

  • 核心思想: 历史价格的模式会重复出现。
  • 经典模式: 例如头肩顶、双底、金叉等。
技术分析图表模式 展示了两种经典的技术分析模式:头肩顶和双底。 头肩顶 (看跌) 双底 (看涨) W 形底

新兴趋势:让CNN“看懂”股票图表

一个革命性的想法:我们能否将股票价格走势图本身当作一张图片,然后用CNN来分析它,从而预测未来的股票回报?

核心论文: Jiang, Kelly, and Xiu (2023), “(Re-)Imag(in)ing Price Trends”, The Journal of Finance.

J.K.X. (2023) 的核心思想

  1. 数据转换: 将每只股票过去一段时间(如一年)的价格序列,渲染成一张标准化的价格走势图图片。
  2. 模型训练:
    • 输入 (X): 股票价格图(.png 文件)。
    • 标签 (Y): 该股票未来一个月的回报。
    • 任务: 训练一个深度CNN模型,学习从“图的模式”到“未来回报”的映射关系。
JKX (2023) 核心思想 流程图显示时间序列数据被渲染成图片,然后输入CNN模型以预测未来回报。 价格时间序列 渲染 价格图 (图片) CNN 模型 ⊞ → 📉 → 🎯 未来回报预测

J.K.X. (2023) 的惊人发现

  • 发现新模式
    • CNN能够发现许多传统技术分析和量化模型(如动量、反转)无法捕捉到的、预测未来回报的非线性信号。
  • 超额收益
    • 基于CNN预测信号构建的投资组合,能够获得显著的、在经济上和统计上都非常可观的超额收益。
  • 稳健性
    • 从美国股市图表中学习到的模式,在国际市场上同样有效,证明了这些模式具有一定的普适性。
  • 启示
    • 这篇论文雄辩地证明了,将最新的机器学习技术应用于金融数据,可以从看似饱和的信息中挖掘出全新的alpha来源。

第四部分:声音信息及处理

声音:另一个价值洼地

除了图像,声音——尤其是人类的语音——也包含了丰富的信息。处理声音数据主要有两条路径。

路径一:语音转文字 (Speech-to-Text)

  • 核心任务: 将语音信息转化为文字信息。
  • 代表模型: OpenAI 的 Whisper 模型是目前最先进的开源语音识别模型之一。
  • 金融应用: 自动转录公司的业绩发布会、分析师电话会议、高管访谈等,将其转化为文本,然后就可以用我们之前学过的NLP技术进行情绪分析、主题建模等。
语音转文字流程 一个声波图标通过Whisper模型转换为文本文件。 语音信号 Whisper 模型 文本记录

路径二:分析非语言信息 (Vocal Analysis)

我们说话时,传递的不仅仅是文字内容,还有情绪

  • 核心任务: 从语音的声学特征(如音高、语速、音量、音色)中,直接分析说话者的情绪状态。
  • 金融应用: 分析CEO在业绩发布会上的声音情绪。
    • 如果CEO在描述公司前景时声音充满自信,这可能是一个积极信号。
    • 反之,如果言辞闪烁、语气紧张,则可能预示着潜在的问题。
声音情绪分析 一个声波图标通过情绪分析模型输出情绪标签。 语音信号 情绪分析模型 92% 情绪: 自信

声音的可视化:声谱图

如何让一个为图像设计的CNN模型来处理声音?

答案是:将一维的声音信号转换为二维的声谱图 (Spectrogram)

  • X轴: 时间
  • Y轴: 频率
  • 颜色: 强度(音量)

声谱图就像是声音的“指纹”,CNN可以像分析普通图片一样,从声谱图中学习和识别声音模式。

结论:另类数据处理的未来

今天,我们打开了一扇通往新世界的大门。我们学习了:

  • 另类数据的价值
    • 它是信息严重同质化的现代金融市场中,获取超额收益的关键。
  • CNN的强大
    • 卷积神经网络是解锁图像数据价值的核心工具,其应用从实体经济监控到纯粹的金融预测。
  • 声音信息的潜力
    • 无论是转录为文本,还是直接分析情绪,语音数据都为我们理解公司基本面提供了全新的维度。
  • 核心竞争力
    • 随着算力的提升和模型的发展,从这些非结构化数据中提取价值的能力,将成为未来顶尖金融机构的核心竞争力。

课后思考与习题

  1. 头脑风暴: 除了本章提到的停车场汽车和库存盘点,还有哪些语音和图片数据,可能有助于投资者预测公司的盈利能力?(例如:工厂的开工迹象、社交媒体上的产品图片、建筑工地的活跃度等)
  2. 概念理解: 在我们的代码实践中,模型需要从图片中提炼出哪些信息才能完成识别任务?(提示:物体的轮廓、颜色、纹理、相对位置等)
  3. 动手实践: 请在你附近的超市或商店用手机拍一张照片,尝试修改并运行本章中的程序(可能需要查找COCO数据集中对应的类别ID),看看模型能否识别出你照片中的商品。