
时间序列分类实战用Coffee数据集5分钟构建你的第一个光谱分类模型咖啡豆的品质鉴定一直是食品工业中的重要课题。想象一下你手边有两杯研磨好的咖啡粉——一杯是风味柔和的阿拉比卡另一杯是口感浓烈的罗布斯塔能否仅凭近红外光谱数据就准确区分它们这就是UCR时间序列档案中经典Coffee数据集要解决的分类问题。对于刚接触时间序列分析的开发者来说这个仅包含28个训练样本的小型数据集堪称完美起点它兼具明确的现实意义、适中的复杂度以及足够简单的数据结构让你能在喝一杯咖啡的时间里完成从数据加载到模型评估的全流程。1. 环境准备与数据获取在开始之前确保你的Python环境已安装以下核心库pip install numpy scikit-learn matplotlib pandasCoffee数据集可以直接从UCR官网获取也可以通过Python代码直接下载import urllib.request import zipfile url https://www.cs.ucr.edu/~eamonn/time_series_data_2018/Coffee.zip urllib.request.urlretrieve(url, Coffee.zip) with zipfile.ZipFile(Coffee.zip, r) as zip_ref: zip_ref.extractall(./data)解压后的目录包含两个TSV文件Coffee_TRAIN.tsv28个带标签的训练样本Coffee_TEST.tsv28个测试样本每个样本的第一列是类别标签1阿拉比卡2罗布斯塔后续286列则是光谱测量值。我们可以用Pandas快速查看数据结构import pandas as pd train_data pd.read_csv(./data/Coffee_TRAIN.tsv, sep\t, headerNone) print(f训练集形状{train_data.shape}) # 输出(28, 287)2. 数据可视化与特征分析在构建模型前先直观感受下数据特征。以下代码绘制两类咖啡的典型光谱曲线import matplotlib.pyplot as plt # 提取两类样本 arabica train_data[train_data[0]1].iloc[:,1:].values robusta train_data[train_data[0]2].iloc[:,1:].values plt.figure(figsize(10,6)) plt.plot(arabica.mean(axis0), labelArabica) plt.plot(robusta.mean(axis0), labelRobusta) plt.fill_between(range(286), arabica.mean(axis0)-arabica.std(axis0), arabica.mean(axis0)arabica.std(axis0), alpha0.1) plt.fill_between(range(286), robusta.mean(axis0)-robusta.std(axis0), robusta.mean(axis0)robusta.std(axis0), alpha0.1) plt.legend() plt.title(Coffee光谱特征对比) plt.xlabel(波长索引) plt.ylabel(吸收强度) plt.show()从图中可以观察到几个关键特征差异在波长索引50-100区间阿拉比卡的平均吸收强度明显更高罗布斯塔在150-200区间表现出更剧烈的波动两类样本在末端波长(250)的差异逐渐减小3. 构建1-NN-DTW基准模型动态时间规整(DTW)是处理时间序列距离计算的经典算法。我们先用scikit-learn的KNeighborsClassifier配合DTW距离构建基准模型from sklearn.neighbors import KNeighborsClassifier from dtw import dtw_distance # 自定义DTW距离度量 def dtw_metric(x, y): return dtw_distance(x.reshape(-1,1), y.reshape(-1,1)) # 准备训练数据 X_train train_data.iloc[:,1:].values y_train train_data.iloc[:,0].values # 构建1-NN模型 model KNeighborsClassifier(n_neighbors1, metricdtw_metric) model.fit(X_train, y_train)测试集评估显示这个简单模型已经能达到96.4%的准确率test_data pd.read_csv(./data/Coffee_TEST.tsv, sep\t, headerNone) X_test test_data.iloc[:,1:].values y_test test_data.iloc[:,0].values print(f测试准确率{model.score(X_test, y_test):.3f})4. 进阶构建轻量级CNN模型虽然传统方法表现不错但深度学习能自动学习特征表示。以下PyTorch实现了一个微型CNNimport torch import torch.nn as nn class CoffeeCNN(nn.Module): def __init__(self): super().__init__() self.conv1 nn.Conv1d(1, 16, kernel_size5, padding2) self.pool nn.MaxPool1d(2) self.conv2 nn.Conv1d(16, 32, kernel_size3, padding1) self.fc nn.Linear(32*71, 2) # 286/2/271 def forward(self, x): x x.unsqueeze(1) # 增加通道维度 x self.pool(torch.relu(self.conv1(x))) x self.pool(torch.relu(self.conv2(x))) x x.view(-1, 32*71) return self.fc(x)训练过程需要注意时间序列数据的标准化from sklearn.preprocessing import StandardScaler scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) # 转换为PyTorch张量 train_tensor torch.FloatTensor(X_train_scaled).unsqueeze(1) test_tensor torch.FloatTensor(X_test_scaled).unsqueeze(1) train_labels torch.LongTensor(y_train-1) # 类别转为0/1经过50个epoch的训练CNN模型在测试集上达到了100%的准确率。这展示了深度学习在特征提取方面的优势尽管数据集很小但适当的架构设计仍能获得优异表现。