引言 股票市場(chǎng)的波動(dòng)往往存在一定的共振,,尤其是同一個(gè)行業(yè)或主題概念的公司股票,當(dāng)面臨行業(yè)基本面的沖擊時(shí),,其波動(dòng)存在一定的相似性,,即表現(xiàn)出同漲同跌。如果能通過(guò)交易行情數(shù)據(jù)對(duì)股票市場(chǎng)的波動(dòng)結(jié)構(gòu)進(jìn)行刻畫,,對(duì)于我們深入理解板塊輪動(dòng)和網(wǎng)絡(luò)關(guān)聯(lián)性具有重要的啟示作用,。那么如何借助可視化的手段對(duì)股票市場(chǎng)結(jié)構(gòu)進(jìn)行分析呢?機(jī)器學(xué)習(xí)中的無(wú)監(jiān)督學(xué)習(xí)算法或許可以幫助我們解決這一問(wèn)題,。本文以上證50指數(shù)成分股為例,,使用稀疏逆協(xié)方差(GraphicalLassoCV)計(jì)算股票之間的條件相關(guān)性,,然后使用聚類分析將行為相似的股票分組在一起并進(jìn)行可視化。數(shù)據(jù)獲取 使用tushare pro獲取上證50指數(shù)成分股收盤價(jià)和開(kāi)盤價(jià)數(shù)據(jù),,以收盤價(jià)減去開(kāi)盤價(jià)作為日波動(dòng)的替代變量,。以下代碼使用Jupyter notebook運(yùn)行。import pandas as pdimport numpy as npimport matplotlib.pyplot as pltfrom matplotlib.collections import LineCollectionfrom sklearn import cluster, covariance, manifold%matplotlib inline #Jupyter Notebook顯示圖形專用plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=False
import tushare as tstoken='到tushare pro官網(wǎng)獲取你的token'pro=ts.pro_api(token)#獲取上證50成分股票代碼和名稱def get_50_code(): #獲取上證50成分股代碼 dd=pro.index_weight(index_code='000016.SH') dd=dd[dd.trade_date=='20201130'] codes50=dd.con_code.values #獲取全市場(chǎng)股票基本信息 df = pro.stock_basic(exchange='', list_status='L') df=df[df.ts_code.isin(codes50)] codes=df.ts_code.values names=df.name.values stocks=dict(zip(codes,names)) return stocksdef get_data(code,start='20191210',end='20201210'): df=ts.pro_bar(ts_code=code,adj='qfq', start_date=start, end_date=end) df.index=pd.to_datetime(df.trade_date) df=df.sort_index() return dfcodes, names = np.array(sorted(get_50_code().items())).Tdata=pd.DataFrame({name:(get_data(code).close-get_data(code).open) for code,name in zip(codes,names)})variation=data.dropna().valuesdata.head()
上證50成分股股價(jià)日變動(dòng)情況: 聚類分析 由于相互關(guān)聯(lián)的股票會(huì)在交易中產(chǎn)生共波動(dòng),,所以我們可以使用無(wú)監(jiān)督學(xué)習(xí)算法從歷史報(bào)價(jià)中提取股票市場(chǎng)結(jié)構(gòu)的變化,,如使用(收盤價(jià)-開(kāi)盤價(jià))來(lái)刻畫股價(jià)每日價(jià)格變動(dòng),然后使用稀疏逆協(xié)方差估計(jì)找出哪些股票存在條件相關(guān)性,。換句話說(shuō),,稀疏逆協(xié)方差可以得到一個(gè)方差關(guān)聯(lián)性列表,對(duì)于每只股票來(lái)說(shuō),,與之相關(guān)的股票有助于解釋其波動(dòng),。然后再使用聚類分析將行為相似的股票分組在一起。scikit-learn提供了十種不同的聚類算法,,本文用“Affinity_propagation”(AP算法),,主要基于該算法可以從數(shù)據(jù)中自動(dòng)選擇聚類的數(shù)量。AP算法的基本思想是將全部樣本看作網(wǎng)絡(luò)的節(jié)點(diǎn),,然后通過(guò)網(wǎng)絡(luò)中各條邊的消息傳遞計(jì)算出各樣本的聚類中心,,關(guān)于該算法的詳細(xì)原理可參考scikit-learn官網(wǎng)或相關(guān)書籍。# 相關(guān)系數(shù)edge_model = covariance.GraphicalLassoCV()X = variation.copy()X /= X.std(axis=0)edge_model.fit(X)_, labels = cluster.affinity_propagation(edge_model.covariance_)n_labels = labels.max()for i in range(n_labels + 1): print('Cluster %i: %s' % ((i + 1), ', '.join(names[labels == i])))
#輸出結(jié)果:Cluster 1: 萬(wàn)華化學(xué)Cluster 2: 恒瑞醫(yī)藥, 貴州茅臺(tái), 伊利股份Cluster 3: 山東黃金Cluster 4: 三安光電, 聞泰科技, 匯頂科技Cluster 5: 浦發(fā)銀行, 民生銀行, 中國(guó)石化, 招商銀行, 興業(yè)銀行, 農(nóng)業(yè)銀行, 中國(guó)平安, 交通銀行, 工商銀行, 郵儲(chǔ)銀行, 光大銀行, 中國(guó)石油, 中國(guó)銀行Cluster 6: 三一重工, 保利地產(chǎn), 海螺水泥, 中國(guó)神華, 中國(guó)鐵建, 中國(guó)建筑Cluster 7: 上海機(jī)場(chǎng), 中信證券, 中國(guó)聯(lián)通, 上汽集團(tuán), 海爾智家, 海通證券, 中信建投, 工業(yè)富聯(lián), 國(guó)泰君安, 紅塔證券, 中國(guó)人保, 新華保險(xiǎn), 中國(guó)太保, 中國(guó)人壽, 華泰證券, 中國(guó)中免, 中國(guó)重工, 洛陽(yáng)鉬業(yè)Cluster 8: 京滬高鐵Cluster 9: 復(fù)星醫(yī)藥, 用友網(wǎng)絡(luò), 隆基股份, 藥明康德
數(shù)據(jù)可視化 為了將上述聚類分析進(jìn)行可視化,,需要在一個(gè)2D畫布上布置不同的股票,。為此,需要使用“流形”技術(shù)來(lái)檢索二維嵌入,。模型的輸出組合成一個(gè)二維圖,,其中節(jié)點(diǎn)代表股票名稱,邊表示:集群標(biāo)簽用于定義節(jié)點(diǎn)的顏色使用稀疏協(xié)方差模型來(lái)顯示邊緣的強(qiáng)度二維嵌入用于在平面中定位節(jié)點(diǎn) node_position_model = manifold.LocallyLinearEmbedding( n_components=2, eigen_solver='dense', n_neighbors=6)embedding = node_position_model.fit_transform(X.T).T
# 可視化plt.figure(1, facecolor='w', figsize=(10, 8))plt.clf()ax = plt.axes([0., 0., 1., 1.])plt.axis('off')# 計(jì)算偏相關(guān)系數(shù)partial_correlations = edge_model.precision_.copy()d = 1 / np.sqrt(np.diag(partial_correlations))partial_correlations *= dpartial_correlations *= d[:, np.newaxis]non_zero = (np.abs(np.triu(partial_correlations, k=1)) > 0.02)# 使用嵌入的坐標(biāo)繪制節(jié)點(diǎn)plt.scatter(embedding[0], embedding[1], s=100 * d ** 2, c=labels, cmap=plt.cm.nipy_spectral)# 畫相互關(guān)聯(lián)的邊start_idx, end_idx = np.where(non_zero)segments = [[embedding[:, start], embedding[:, stop]] for start, stop in zip(start_idx, end_idx)]values = np.abs(partial_correlations[non_zero])lc = LineCollection(segments, zorder=0, cmap=plt.cm.hot_r, norm=plt.Normalize(0, .7 * values.max()))lc.set_array(values)lc.set_linewidths(15 * values)ax.add_collection(lc)#向每個(gè)節(jié)點(diǎn)添加一個(gè)標(biāo)簽,,難點(diǎn)在于定位標(biāo)簽,,以避免與其他標(biāo)簽重疊for index, (name, label, (x, y)) in enumerate( zip(names, labels, embedding.T)): dx = x - embedding[0] dx[index] = 1 dy = y - embedding[1] dy[index] = 1 this_dx = dx[np.argmin(np.abs(dy))] this_dy = dy[np.argmin(np.abs(dx))] if this_dx > 0: horizontalalignment = 'left' x = x + .002 else: horizontalalignment = 'right' x = x - .002 if this_dy > 0: verticalalignment = 'bottom' y = y + .002 else: verticalalignment = 'top' y = y - .002 plt.text(x, y, name, size=10, horizontalalignment=horizontalalignment, verticalalignment=verticalalignment, bbox=dict(facecolor='w', edgecolor=plt.cm.nipy_spectral(label / float(n_labels)), alpha=.6))plt.xlim(embedding[0].min() - .15 * embedding[0].ptp(), embedding[0].max() + .10 * embedding[0].ptp(),)plt.ylim(embedding[1].min() - .03 * embedding[1].ptp(), embedding[1].max() + .03 * embedding[1].ptp())plt.show()
圖表反映了變量之間的條件關(guān)系,而聚類反映了邊際屬性:聚在一起的變量可以被認(rèn)為在整個(gè)股票市場(chǎng)水平上具有類似的影響,。從下圖中可以看出,,無(wú)監(jiān)督學(xué)習(xí)通過(guò)對(duì)交易報(bào)價(jià)信息的提取,可以大致勾勒出上證50指數(shù)成分股的一個(gè)市場(chǎng)結(jié)構(gòu),,具有相同行業(yè)屬性或概念屬性的個(gè)股其波動(dòng)表現(xiàn)出相似性,,如醫(yī)藥、銀行,、券商,、保險(xiǎn)、大基建等。 結(jié)語(yǔ) 機(jī)器學(xué)習(xí)是量化分析的一個(gè)重要工具,,掌握機(jī)器學(xué)習(xí)算法的基本原理和應(yīng)用場(chǎng)景可以為我們分析和研究金融市場(chǎng)提供一個(gè)參考框架,。無(wú)監(jiān)督機(jī)器學(xué)習(xí)中的聚類分析能夠從紛繁復(fù)雜的數(shù)據(jù)中提取有用信息,刻畫多維特征的“相似性”和“關(guān)聯(lián)性”,,再借助網(wǎng)絡(luò)分析的視角,,可以進(jìn)一步考察數(shù)據(jù)變量間的微觀結(jié)構(gòu)和運(yùn)動(dòng)狀態(tài)。本文參考scikit-learn官方網(wǎng)站示例,,對(duì)上證50指數(shù)成分股的“共波動(dòng)”結(jié)構(gòu)進(jìn)行了可視化分析,,為大家深入學(xué)習(xí)機(jī)器學(xué)習(xí)拋磚引玉。關(guān)于網(wǎng)絡(luò)分析方面,,Python有個(gè)很好用的第三方庫(kù)——networkx,,可以畫出各種精美的網(wǎng)絡(luò)分析圖,感興趣的讀者可以進(jìn)一步了解,。
參考資料: scikit-learn官方網(wǎng)站案例: https:///stable/auto_examples/applications/plot_stock_market.html?highlight=plot%20stock%20market
|