【问题标题】:Can we cluster Multivariate Time Series dataset in Python我们可以在 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 在同一个集群中)

【问题讨论】:

标签: python time-series cluster-analysis k-means euclidean-distance


【解决方案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变成了不同变量随时间的变化
    猜你喜欢
    • 2018-01-18
    • 2019-08-24
    • 2021-12-21
    • 2017-09-12
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 2020-09-27
    • 2019-03-23
    相关资源
    最近更新 更多