クラスタ分析で株の分類分け
機械学習にクラスタ分析というものがあります。
これは教師なし学習と一般に言われており、データを持つ対象物がどの分類に属しているか?を距離などを用いて計算し分類を行う方法です。
本来であればラベリングされたデータを元に正しく分類させるのですが、教師なし学習はラベリングなしで行うことができます。
シーンとしては、自分が買いたい株は日経平均と連動しているのか?
そもそも独自の値動きをしているのか?などに役立つかと思います。
事前準備
手元に株価のデータを準備します。
ある日の複数の株の始値、高値、安値、終値のデータで、それらがどのようなカテゴリに属しているか(近いか)を計算します。
なお、使用するデータはスケールを合わせる必要があるので、実際の株価のデータの始値を基点の0とし、高値、安値を割合で出しています。
こちらからデータをいただき、以下、こんなデータを利用します。
import pandas as pd
data = pd.read_csv('T171101.csv')
data.head()
日付 | コード | 銘柄 | 始値 | 高値 | 安値 | 終値 | 始値(基点) | 高値(割合) | 安値(割合) | 終値(割合) | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2017/11/1 | 1001 | 1001 日経225 | 22144.0 | 22455.0 | 22130.0 | 22420.0 | 0 | 1.404444 | -0.062347 | 1.247176 |
1 | 2017/11/1 | 1002 | 1002 TOPIX | 1775.0 | 1789.0 | 1773.0 | 1786.0 | 0 | 0.788732 | -0.111794 | 0.620417 |
2 | 2017/11/1 | 1301 | 1301 極洋 | 3670.0 | 3705.0 | 3620.0 | 3695.0 | 0 | 0.953678 | -1.349528 | 0.690608 |
3 | 2017/11/1 | 1305 | 1305 ダイワTPX | 1856.0 | 1867.0 | 1852.0 | 1865.0 | 0 | 0.592672 | -0.214247 | 0.485961 |
4 | 2017/11/1 | 1306 | 1306 TOPIX投 | 1828.0 | 1841.0 | 1825.0 | 1839.0 | 0 | 0.711160 | -0.162955 | 0.602740 |
クラスタ分析のアルゴリズム
クラスタ分析をするには様々なアルゴリズムがありますが、チートシートがあるため、それに従ってアルゴリズムを決めます。
ということで、「Kmeans」を使います。
Kmeansについては、細かく知りたい人はwikipediaなどで調べてください。
簡単に説明すると、データからランダムな値を取り出し、クラスタの重心点を計算し更新していく方法です。
分析
まずは2次元でプロットします。
import matplotlib.pyplot as plt
%matplotlib inline
plt.scatter(data['高値(割合)'], data['安値(割合)'])
plt.xlabel('high')
plt.ylabel('low')
いや、いけるかな・・・これ・・・。もうちょっとわかりやすいほうが・・・
続けてkmeansをやります。
クラスタは6くらいかなぁ(始値から上がるor 下がる、同じ、終値が上がる、下がる、同じ)と仮定
kmeans_data=data.copy()
del kmeans_data['銘柄']
del kmeans_data['日付']
del kmeans_data['コード']
del kmeans_data['始値']
del kmeans_data['高値']
del kmeans_data['安値']
del kmeans_data['終値']
kmeans_data.head()
始値(基点) | 高値(割合) | 安値(割合) | 終値(割合) | |
---|---|---|---|---|
0 | 0 | 1.404444 | -0.062347 | 1.247176 |
1 | 0 | 0.788732 | -0.111794 | 0.620417 |
2 | 0 | 0.953678 | -1.349528 | 0.690608 |
3 | 0 | 0.592672 | -0.214247 | 0.485961 |
4 | 0 | 0.711160 | -0.162955 | 0.602740 |
from sklearn.cluster import KMeans
model = KMeans(n_clusters=6)
model.fit(kmeans_data)
y = model.labels_
print(y)
[2 2 2 ..., 0 3 0]
data_results = data.copy()
data_results['分類'] = y
data_results
日付 | コード | 銘柄 | 始値 | 高値 | 安値 | 終値 | 始値(基点) | 高値(割合) | 安値(割合) | 終値(割合) | 分類 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2017/11/1 | 1001 | 1001 日経225 | 22144.0 | 22455.0 | 22130.0 | 22420.0 | 0 | 1.404444 | -0.062347 | 1.247176 | 2 |
1 | 2017/11/1 | 1002 | 1002 TOPIX | 1775.0 | 1789.0 | 1773.0 | 1786.0 | 0 | 0.788732 | -0.111794 | 0.620417 | 2 |
2 | 2017/11/1 | 1301 | 1301 極洋 | 3670.0 | 3705.0 | 3620.0 | 3695.0 | 0 | 0.953678 | -1.349528 | 0.690608 | 2 |
3 | 2017/11/1 | 1305 | 1305 ダイワTPX | 1856.0 | 1867.0 | 1852.0 | 1865.0 | 0 | 0.592672 | -0.214247 | 0.485961 | 3 |
4 | 2017/11/1 | 1306 | 1306 TOPIX投 | 1828.0 | 1841.0 | 1825.0 | 1839.0 | 0 | 0.711160 | -0.162955 | 0.602740 | 2 |
5 | 2017/11/1 | 1308 | 1308 上場TPX | 1811.0 | 1822.0 | 1808.0 | 1821.0 | 0 | 0.607399 | -0.164654 | 0.553097 | 2 |
6 | 2017/11/1 | 1309 | 1309 上海上証50 | 34050.0 | 34150.0 | 34050.0 | 34050.0 | 0 | 0.293686 | 0.000000 | 0.000000 | 3 |
7 | 2017/11/1 | 1310 | 1310 ダイワT30 | 797.0 | 801.0 | 797.0 | 800.0 | 0 | 0.501882 | 0.000000 | 0.376412 | 3 |
8 | 2017/11/1 | 1311 | 1311 T30連動投 | 806.0 | 813.0 | 806.0 | 809.0 | 0 | 0.868486 | 0.000000 | 0.372208 | 2 |
9 | 2017/11/1 | 1312 | 1312 野村小型コア | 21900.0 | 21950.0 | 21900.0 | 21950.0 | 0 | 0.228311 | 0.000000 | 0.228311 | 3 |
10 | 2017/11/1 | 1313 | 1313 KODEX200 | 3405.0 | 3460.0 | 3405.0 | 3460.0 | 0 | 1.615272 | 0.000000 | 1.615272 | 2 |
11 | 2017/11/1 | 1314 | 1314 日本新興株 | 1420.0 | 1434.0 | 1420.0 | 1432.0 | 0 | 0.985915 | 0.000000 | 0.845070 | 2 |
12 | 2017/11/1 | 1319 | 1319 日経300F | 323.0 | 331.0 | 312.0 | 313.0 | 0 | 2.476780 | -3.323263 | -3.205128 | 0 |
13 | 2017/11/1 | 1320 | 1320 ダイワ225 | 22760.0 | 23040.0 | 22760.0 | 23010.0 | 0 | 1.230228 | 0.000000 | 1.098418 | 2 |
14 | 2017/11/1 | 1321 | 1321 日経225投 | 22770.0 | 23060.0 | 22760.0 | 23010.0 | 0 | 1.273606 | -0.043365 | 1.054482 | 2 |
15 | 2017/11/1 | 1322 | 1322 上場パンダ | 5600.0 | 5640.0 | 5600.0 | 5600.0 | 0 | 0.714286 | 0.000000 | 0.000000 | 3 |
16 | 2017/11/1 | 1323 | 1323 南アフリカ投信 | 360.0 | 375.0 | 360.0 | 375.0 | 0 | 4.166667 | 0.000000 | 4.166667 | 4 |
17 | 2017/11/1 | 1324 | 1324 ロシア株投信 | 125.0 | 126.0 | 125.0 | 125.0 | 0 | 0.800000 | 0.000000 | 0.000000 | 3 |
18 | 2017/11/1 | 1325 | 1325 NFブラジル | 209.0 | 210.0 | 207.0 | 210.0 | 0 | 0.478469 | -0.952381 | 0.483092 | 3 |
19 | 2017/11/1 | 1326 | 1326 SPDRゴールド | 13720.0 | 13770.0 | 13700.0 | 13760.0 | 0 | 0.364431 | -0.145243 | 0.291971 | 3 |
20 | 2017/11/1 | 1327 | 1327 EASY商品 | 3265.0 | 3265.0 | 3250.0 | 3250.0 | 0 | 0.000000 | -0.459418 | -0.461538 | 3 |
21 | 2017/11/1 | 1328 | 1328 金連動投信 | 3750.0 | 3760.0 | 3750.0 | 3750.0 | 0 | 0.266667 | 0.000000 | 0.000000 | 3 |
22 | 2017/11/1 | 1329 | 1329 iシェ225 | 22840.0 | 23110.0 | 22840.0 | 23100.0 | 0 | 1.182137 | 0.000000 | 1.138354 | 2 |
23 | 2017/11/1 | 1330 | 1330 上場225 | 22870.0 | 23140.0 | 22850.0 | 23120.0 | 0 | 1.180586 | -0.086430 | 1.094092 | 2 |
24 | 2017/11/1 | 1332 | 1332 日水 | 697.0 | 710.0 | 695.0 | 709.0 | 0 | 1.865136 | -0.281690 | 1.726619 | 2 |
25 | 2017/11/1 | 1333 | 1333 マルハニチロ | 3500.0 | 3560.0 | 3490.0 | 3520.0 | 0 | 1.714286 | -0.280899 | 0.573066 | 2 |
26 | 2017/11/1 | 1343 | 1343 NF東REIT | 1745.0 | 1748.0 | 1743.0 | 1743.0 | 0 | 0.171920 | -0.114416 | -0.114745 | 3 |
27 | 2017/11/1 | 1344 | 1344 MXコア | 745.0 | 752.0 | 745.0 | 750.0 | 0 | 0.939597 | 0.000000 | 0.671141 | 2 |
28 | 2017/11/1 | 1345 | 1345 上場Jリート | 1650.0 | 1654.0 | 1647.0 | 1647.0 | 0 | 0.242424 | -0.181378 | -0.182149 | 3 |
29 | 2017/11/1 | 1346 | 1346 MX225投信 | 22840.0 | 23120.0 | 22840.0 | 23090.0 | 0 | 1.225919 | 0.000000 | 1.094571 | 2 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
3836 | 2017/11/1 | 9946 | 9946 ミニストップ | 2306.0 | 2306.0 | 2273.0 | 2283.0 | 0 | 0.000000 | -1.431049 | -1.011879 | 3 |
3837 | 2017/11/1 | 9948 | 9948 アークス | 2538.0 | 2545.0 | 2523.0 | 2539.0 | 0 | 0.275808 | -0.589391 | 0.039635 | 3 |
3838 | 2017/11/1 | 9950 | 9950 ハチバン | 3480.0 | 3485.0 | 3480.0 | 3480.0 | 0 | 0.143678 | 0.000000 | 0.000000 | 3 |
3839 | 2017/11/1 | 9955 | 9955 ヨンキュウ | 1461.0 | 1466.0 | 1441.0 | 1442.0 | 0 | 0.342231 | -1.364256 | -1.318529 | 3 |
3840 | 2017/11/1 | 9957 | 9957 バイテック | 1919.0 | 1936.0 | 1900.0 | 1935.0 | 0 | 0.885878 | -0.981405 | 0.842105 | 2 |
3841 | 2017/11/1 | 9959 | 9959 アシード | 710.0 | 710.0 | 710.0 | 710.0 | 0 | 0.000000 | 0.000000 | 0.000000 | 3 |
3842 | 2017/11/1 | 9960 | 9960 東テク | 2031.0 | 2038.0 | 1985.0 | 1999.0 | 0 | 0.344658 | -2.257115 | -1.612091 | 0 |
3843 | 2017/11/1 | 9962 | 9962 ミスミG | 3150.0 | 3195.0 | 3140.0 | 3185.0 | 0 | 1.428571 | -0.312989 | 1.114650 | 2 |
3844 | 2017/11/1 | 9964 | 9964 アイ・テック | 1692.0 | 1717.0 | 1622.0 | 1686.0 | 0 | 1.477541 | -4.076878 | -0.369914 | 0 |
3845 | 2017/11/1 | 9967 | 9967 堺商事 | 1744.0 | 1749.0 | 1725.0 | 1749.0 | 0 | 0.286697 | -1.086335 | 0.289855 | 3 |
3846 | 2017/11/1 | 9972 | 9972 アルテック | 308.0 | 309.0 | 300.0 | 309.0 | 0 | 0.324675 | -2.588997 | 0.333333 | 3 |
3847 | 2017/11/1 | 9973 | 9973 小僧寿し | 84.0 | 85.0 | 83.0 | 83.0 | 0 | 1.190476 | -1.176471 | -1.204819 | 3 |
3848 | 2017/11/1 | 9974 | 9974 ベルク | 6430.0 | 6430.0 | 6260.0 | 6260.0 | 0 | 0.000000 | -2.643857 | -2.715655 | 0 |
3849 | 2017/11/1 | 9976 | 9976 セキチュー | 678.0 | 678.0 | 678.0 | 678.0 | 0 | 0.000000 | 0.000000 | 0.000000 | 3 |
3850 | 2017/11/1 | 9977 | 9977 アオキスーパ | 1313.0 | 1313.0 | 1313.0 | 1313.0 | 0 | 0.000000 | 0.000000 | 0.000000 | 3 |
3851 | 2017/11/1 | 9978 | 9978 文教堂 | 409.0 | 410.0 | 406.0 | 406.0 | 0 | 0.244499 | -0.731707 | -0.738916 | 3 |
3852 | 2017/11/1 | 9979 | 9979 大庄 | 1726.0 | 1732.0 | 1723.0 | 1729.0 | 0 | 0.347625 | -0.173210 | 0.174115 | 3 |
3853 | 2017/11/1 | 9980 | 9980 マルコ | 386.0 | 395.0 | 384.0 | 389.0 | 0 | 2.331606 | -0.506329 | 0.781250 | 2 |
3854 | 2017/11/1 | 9983 | 9983 ファストリ | 37670.0 | 37860.0 | 37360.0 | 37620.0 | 0 | 0.504380 | -0.818806 | -0.133833 | 3 |
3855 | 2017/11/1 | 9984 | 9984 ソフトバンク | 10040.0 | 10145.0 | 9971.0 | 10130.0 | 0 | 1.045817 | -0.680138 | 0.902618 | 2 |
3856 | 2017/11/1 | 9986 | 9986 蔵王産業 | 1685.0 | 1690.0 | 1677.0 | 1689.0 | 0 | 0.296736 | -0.473373 | 0.238521 | 3 |
3857 | 2017/11/1 | 9989 | 9989 サンドラッグ | 5010.0 | 5040.0 | 4900.0 | 4960.0 | 0 | 0.598802 | -2.182540 | -1.020408 | 0 |
3858 | 2017/11/1 | 9990 | 9990 東京デリカ | 1352.0 | 1409.0 | 1344.0 | 1401.0 | 0 | 4.215976 | -0.567779 | 3.645833 | 4 |
3859 | 2017/11/1 | 9991 | 9991 ジェコス | 1285.0 | 1292.0 | 1278.0 | 1286.0 | 0 | 0.544747 | -0.541796 | 0.078247 | 3 |
3860 | 2017/11/1 | 9992 | 9992 理研グリン | 377.0 | 377.0 | 375.0 | 376.0 | 0 | 0.000000 | -0.530504 | -0.266667 | 3 |
3861 | 2017/11/1 | 9993 | 9993 ヤマザワ | 1744.0 | 1744.0 | 1733.0 | 1739.0 | 0 | 0.000000 | -0.630734 | -0.288517 | 3 |
3862 | 2017/11/1 | 9994 | 9994 やまや | 2382.0 | 2415.0 | 2374.0 | 2391.0 | 0 | 1.385390 | -0.331263 | 0.379107 | 2 |
3863 | 2017/11/1 | 9995 | 9995 イーストン | 728.0 | 730.0 | 712.0 | 720.0 | 0 | 0.274725 | -2.191781 | -1.123596 | 0 |
3864 | 2017/11/1 | 9996 | 9996 サトー商会 | 1398.0 | 1398.0 | 1393.0 | 1393.0 | 0 | 0.000000 | -0.357654 | -0.358938 | 3 |
3865 | 2017/11/1 | 9997 | 9997 ベルーナ | 1266.0 | 1281.0 | 1205.0 | 1262.0 | 0 | 1.184834 | -4.761905 | -0.331950 | 0 |
3866 rows × 12 columns
ちゃんと分類できてそうです。
で、ここからなのですが日経平均225と同様のカテゴリは0のもになります。
つまり、日経平均と連動した値動きになっている銘柄です。
逆にその他の数字のものは日経平均とは違う値動きになっていると思われます。
試しにやってみます。
#日経平均
x=[22144.0,22455.0,22130.0,22420.0]
plt.plot(x)
#分類4
y=[329000.0,331500.0,327500.0,330000.0]
plt.plot(y)
#分類0
z=[7320.0,7350.0,6270.0,7350.0]
plt.plot(z)
どうでしょう?微妙に違いますね。
高値と安値の時系列がないため、単純なグラフがこうとはなりませんが(高値⇔安値が入れ替わる)だいたい、グラフの形状が違うことはわあかります。
このデータをもっと多くの日にちでやることで、自分の買いたい株が日経平均と連動しているかどうかの目安にはなるかと思います。