我们可以在 Python 中对多元时间序列数据集进行聚类吗
Posted
技术标签:
【中文标题】我们可以在 Python 中对多元时间序列数据集进行聚类吗【英文标题】:Can we cluster Multivariate Time Series dataset in Python 【发布时间】:2020-08-15 15:42:33 【问题描述】:我有一个数据集,其中包含不同股票在不同时间的许多金融信号值。例如
StockName Date Signal1 Signal2
----------------------------------
Stock1 1/1/20 a b
Stock1 1/2/20 c d
.
.
.
Stock2 1/1/20 e f
Stock2 1/2/20 g h
.
.
.
我想建立一个如下所示的时间序列表,并根据信号 1 和信号 2(2 个变量)对股票进行聚类
StockName 1/1/20 1/2/20 ........ Cluster#
----------------------------------------------------
Stock1 [a,b] [c,d] 0
Stock2 [e,f] [g,h] 1
Stock3 ...... ..... 0
.
.
.
1)有什么方法可以做到这一点吗? (基于时间序列数据的多个变量对股票进行聚类)。我尝试在线搜索,但它们都是关于基于一个变量的聚类时间序列。
2)另外,有没有办法在不同的时间对不同的股票进行聚类? (所以也许时间 1 的 Stock1 与时间 3 的 Stock2 在同一个集群中)
【问题讨论】:
我们可以吗?当然:datascience.stackexchange.com/questions/29287/… 【参考方案1】:值得阅读的好材料(标题:时间序列聚类和降维)
https://towardsdatascience.com/time-series-clustering-and-dimensionality-reduction-5b3b4e84f6a3
【讨论】:
【参考方案2】:我正在根据您上次发布的新信息在这里修改我的答案。
from utils import *
import time
import numpy as np
from mxnet import nd, autograd, gluon
from mxnet.gluon import nn, rnn
import mxnet as mx
import datetime
import seaborn as sns
import matplotlib.pyplot as plt
# %matplotlib inline
from sklearn.decomposition import PCA
import math
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
from sklearn.preprocessing import StandardScaler
import xgboost as xgb
from sklearn.metrics import accuracy_score
import warnings
warnings.filterwarnings("ignore")
context = mx.cpu(); model_ctx=mx.cpu()
mx.random.seed(1719)
# Note: The purpose of this section (3. The Data) is to show the data preprocessing and to give rationale for using different sources of data, hence I will only use a subset of the full data (that is used for training).
def parser(x):
return datetime.datetime.strptime(x,'%Y-%m-%d')
# dataset_ex_df = pd.read_csv('data/panel_data_close.csv', header=0, parse_dates=[0], date_parser=parser)
import yfinance as yf
# Get the data for the stock AAPL
start = '2018-01-01'
end = '2020-04-22'
data = yf.download('GS', start, end)
data = data.reset_index()
data
data.dtypes
# re-name field from 'Adj Close' to 'Adj_Close'
data = data.rename(columns="Adj Close": "Adj_Close")
data
num_training_days = int(data.shape[0]*.7)
print('Number of training days: . Number of test days: .'.format(num_training_days, data.shape[0]-num_training_days))
# TECHNICAL INDICATORS
#def get_technical_indicators(dataset):
# Create 7 and 21 days Moving Average
data['ma7'] = data['Adj_Close'].rolling(window=7).mean()
data['ma21'] = data['Adj_Close'].rolling(window=21).mean()
# Create exponential weighted moving average
data['26ema'] = data['Adj_Close'].ewm(span=26).mean()
data['12ema'] = data['Adj_Close'].ewm(span=12).mean()
data['MACD'] = (data['12ema']-data['26ema'])
# Create Bollinger Bands
data['20sd'] = data['Adj_Close'].rolling(window=20).std()
data['upper_band'] = data['ma21'] + (data['20sd']*2)
data['lower_band'] = data['ma21'] - (data['20sd']*2)
# Create Exponential moving average
data['ema'] = data['Adj_Close'].ewm(com=0.5).mean()
# Create Momentum
data['momentum'] = data['Adj_Close']-1
dataset_TI_df = data
dataset = data
def plot_technical_indicators(dataset, last_days):
plt.figure(figsize=(16, 10), dpi=100)
shape_0 = dataset.shape[0]
xmacd_ = shape_0-last_days
dataset = dataset.iloc[-last_days:, :]
x_ = range(3, dataset.shape[0])
x_ =list(dataset.index)
# Plot first subplot
plt.subplot(2, 1, 1)
plt.plot(dataset['ma7'],label='MA 7', color='g',linestyle='--')
plt.plot(dataset['Adj_Close'],label='Closing Price', color='b')
plt.plot(dataset['ma21'],label='MA 21', color='r',linestyle='--')
plt.plot(dataset['upper_band'],label='Upper Band', color='c')
plt.plot(dataset['lower_band'],label='Lower Band', color='c')
plt.fill_between(x_, dataset['lower_band'], dataset['upper_band'], alpha=0.35)
plt.title('Technical indicators for Goldman Sachs - last days.'.format(last_days))
plt.ylabel('USD')
plt.legend()
# Plot second subplot
plt.subplot(2, 1, 2)
plt.title('MACD')
plt.plot(dataset['MACD'],label='MACD', linestyle='-.')
plt.hlines(15, xmacd_, shape_0, colors='g', linestyles='--')
plt.hlines(-15, xmacd_, shape_0, colors='g', linestyles='--')
# plt.plot(dataset['log_momentum'],label='Momentum', color='b',linestyle='-')
plt.legend()
plt.show()
plot_technical_indicators(dataset_TI_df, 400)
这将为您提供一些可以使用的信号。当然,这些功能可以是您想要的任何东西。我相信你知道这是技术分析,而不是基本面分析。现在,您可以进行聚类,以及您想要的任何其他内容。
这是一个很好的聚类链接。
https://www.pythonforfinance.net/2018/02/08/stock-clusters-using-k-means-algorithm-in-python/
【讨论】:
嗨 ASH,感谢您的评论。根据您附加的数据框,我想要实现的是每个单元格具有多个功能的数据框。 (例如,2017-1-3 中的 MMM 可能在一天内产生多个信号。);对于问题二,根据您所附的df,我想实现类似2017-1-3的MMM与2017-1-4的ABT在同一个集群中(不同日期的不同股票可以聚集在一起)跨度> 啊,我明白了。好的,我认为我发送给您的链接将回答这两个问题。试试吧;你会学到很多东西。如果您在某个地方卡住了,请回复您正在努力解决的问题的详细信息,我会尽力提供更多帮助。我认为您目前拥有所需的一切。 嗨,ASH,我确实看到该示例确实计算了“回报”和“波动率”。但是,我发现每个代码只对应一个“回报”值和一个“波动率”值。我想做一些类似于您附加的数据框的事情。它反映了一段时间内的调整收盘价。我还想添加其他随时间变化的信号。所以每个单元格不仅会有 Adj.Close 值,而且会有不同的信号值。 (每个单元格表示一个特定时间的一个代码)。所以df变成了不同变量随时间的变化以上是关于我们可以在 Python 中对多元时间序列数据集进行聚类吗的主要内容,如果未能解决你的问题,请参考以下文章
Python使用sklearn和statsmodels构建多元线性回归模型(Multiple Linear Regression)并解读