我们可以在 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)并解读

多元线性回归多重共线性检验及避免方法,简单点的

python / scipy中的多元样条插值?

Python检验多元共线性-VIF方差扩大因子

python多元线性回归怎么计算

是否可以在 python 数据类中对变量进行分组?