【NMF＆Dendrogram入門】個別銘柄をクラスタリングして株価評価する🎵

前回のコードを生かして、株の個別銘柄をクラスタリングして、実際の株価を比較して評価してみよう。
銘柄の特徴量は、以前の以下の記事で抽出したper, pbr, roe, eps、そして最新株価を利用する。
参考
[【投資入門】PER、EPS、そしてROEを生かして株価評価して遊んでみる🎵](https://qiita.com/MuAuan/items/41b48995cf3338fee5e4)

## 基本的な知識
以下は、Copilotの出力を引用しています。
### PBR（株価純資産倍率）とROE（自己資本利益率）
<details><summary>PBR（株価純資産倍率）とROE（自己資本利益率）</summary>
株式投資において重要な指標であり、両者には密接な関係があります。
PBRは、株価が企業の1株当たりの純資産に対して何倍に相当するかを示す指標で、
ROEは企業が株主から預かった資本を使ってどれだけの利益を獲得したかを示します。
**一般的に、ROEが高い企業は効率的に利益を上げていると見なされ、投資家からの評価が高くなります。これにより、PBRが高くなる傾向があります。**
つまり、ROEが高い企業は、将来の成長が期待されるため、株価が純資産に対して高い評価を受けやすいのです。
また、PBRとROEの関係を表す式として、以下のような関係が成り立ちます:

```math
 PBR=ROE×PER
```
ここで、PER（株価収益率）は、株価が企業の1株当たりの利益の何倍であるかを示す指標です。
この式から、ROEが高い企業は、PERが高い（つまり利益に対する株価が高い）場合、PBRも高くなることが分かります。
** ROEが高い企業は、少ない自己資本で大きな利益を出せるため、投資家にとって魅力的な投資先となります。 **
その結果、株価が上昇し、PBRが高くなることが一般的です。
** しかし、PBRが1倍以上であっても、ROEが高ければ、それは企業が資本を効率的に使っている証拠であり、投資価値があると考えられます。 **
以上のように、PBRとROEは互いに関連しており、投資判断の際には両指標を併せて考慮することが重要です。
</details>

### EPS（1株当たり純利益）とPBR（株価純資産倍率）
<details><summary>EPS（1株当たり純利益）とPBR（株価純資産倍率）</summary>
株式投資における重要な指標であり、それぞれ企業の収益性と資産価値を評価するために使用されますが、直接的な関係はありません。
それぞれの指標は異なる側面から企業価値を評価するためのものです。

EPSは、企業が1株あたりでどれだけの利益を生み出しているかを示す指標です。
** EPSが高いということは、企業が株主に対して多くの利益を還元していることを意味し、一般的には株価にも好影響を与えると考えられます。**
PBRは、株価が企業の純資産に対してどれだけの評価を受けているかを示す指標です。
** PBRが1倍を下回ると、企業の株価が帳簿上の純資産価値よりも低いことを意味し、理論的には割安と見なされることがあります。**

EPSとPBRは、それぞれ異なる情報を提供しますが、投資家はこれらの指標を組み合わせて、企業の財務健全性や将来の成長性を評価する際に参考にします。
** 例えば、EPSが高く、PBRが低い場合、企業は利益を効率的に生み出しているが、市場ではその資産価値が適切に評価されていない可能性があります。**
このような状況は、投資の機会と見なされることがあります。
投資判断を行う際には、EPSとPBRの両方を考慮することが重要です
</details>

### EPS（Earnings Per Share、1株当たり純利益）とPER（Price Earnings Ratio、株価収益率）

<details><summary>EPS（Earnings Per Share、1株当たり純利益）とPER（Price Earnings Ratio、株価収益率）</summary>
株式投資において密接に関連する重要な財務指標です。

EPSは、企業の当期純利益を発行済み株式総数で割ったもので、企業が1株あたりでどれだけの利益を生み出しているかを示します。
** EPSが高いということは、企業の収益性が高いことを意味し、投資家にとって魅力的な指標となります。 **

PERは、株価をEPSで割ったもので、株価が1株当たりの利益に対して何倍で取引されているかを示します。
** PERが低いということは、株価が1株当たりの利益に比べて低いことを意味し、株が割安である可能性があります。 **
逆に、PERが高いと株が割高である可能性があります2。

EPSとPERの関係は以下の式で表されます:

```math
株価=EPS×PER
```

この式から、EPSが増加すれば、同じPERを維持する場合、株価も上昇することが予想されます。
また、PERが変動すると、EPSが同じでも株価が変動することになります。

したがって、EPSとPERは、株価を理解するために共に考慮されるべき指標です
</details>

### PBRは、株価が企業の資産価値に対して割安か割高かを判断するために用いる 

<details><summary>PBR（株価純資産倍率）は、株価が企業の1株当たり純資産（BPS）に対して何倍で取引されているかを示す指標です。</summary>
PBRは、株価が企業の資産価値に対して割安か割高かを判断するために用いられます。
PBRの計算式は以下の通りです:

```math
PBR=株価​/BPS（1株当たり純資産）
```

PBRの値が1倍を超える場合、市場は企業の純資産価値以上の価値を株価に反映していると見なされ、割高と考えられます。
逆に、PBRが1倍未満の場合は、株価が純資産価値よりも低く評価されており、割安と判断されることがあります1。

例えば、株価が1000円でBPSが800円の場合、PBRは1.25倍となります。これは、企業の保有する純資産に対して25%割高な水準まで株価が買われているということを意味します。
ただし、PBRが1倍未満であるからといって必ずしも割安であるとは限らず、何らかの悪い材料がある可能性も考慮する必要があります。また、PBRが非常に高い銘柄もありますが、これらの企業が高い成長率や利益率を持っている場合、株価が高く評価される傾向があります1。
投資判断を行う際には、PBRだけでなく、他の財務指標や市場全体の動向なども考慮に入れることが重要です。
</details>

## 最新株価と諸量の相関を見る
<details><summary>データ取得</summary>

```lib.py
import numpy as np
import pandas as pd
from sklearn.cluster import AgglomerativeClustering
import matplotlib.pyplot as plt
import japanize_matplotlib
from scipy.cluster.hierarchy import linkage, dendrogram
from scipy.cluster.hierarchy import fcluster
import seaborn as sns
from sklearn.cluster import KMeans # K-means クラスタリングをおこなう
from sklearn.decomposition import PCA #主成分分析器
```

```normalize.py
def calc_std(df):
    df = df / np.std(df)
    return df
```

```get_data.py
data = pd.read_csv('df_ideal_order.csv')

data.set_index("Unnamed: 0",inplace=True)
data['Price'] = calc_std(data['最新株価'])
data['目標株価'] = calc_std(data['目標株価'])
data['上値'] = calc_std(data['上値'])
data['下値'] = calc_std(data['下値'])
data['per'] = calc_std(data['per'])
data['pbr'] = calc_std(data['pbr'])
data['roe'] = calc_std(data['roe'])
data['eps'] = calc_std(data['eps'])
data = data.drop(['最新株価','目標株価','上値','下値'], axis=1)
data
```

```
	        per     	pbr     	roe	        eps     	Price
Unnamed: 0					
TOWA	    3.158233	2.982101	2.427584	1.923361	5.304519
安川電機	3.081120	2.373520	1.980525	1.245593	3.153134
東エレデバ	2.026616	2.852751	3.618999	1.835828	2.412247
JFE	        1.742091	0.480750	0.709487	1.983220	2.641592
AGC	        1.742091	0.480750	0.709487	1.983220	2.641592
住友精化	0.784269	0.471920	1.547034	4.029884	2.448613
野村マイクロ	3.043814	5.012318	4.233666	0.937139	2.506797
キヤノン	2.242168	1.066407	1.222788	1.198750	2.103382
武田薬品	2.011720	0.609148	0.778487	1.313052	1.973436
JT	        1.626543	1.243039	1.964786	1.580390	2.105322
住友商事	0.779721	0.707647	2.333314	2.959487	2.016590
太陽誘電	1.873525	0.828893	1.137457	1.168427	1.610266
日本製鉄	0.455927	0.459301	2.589987	4.786146	1.653420
トヨタ	    2.153827	1.130729	1.349721	0.984691	1.710635
三井住友ト	1.177818	0.488838	1.067045	1.699961	1.559354
オリックス	1.359607	0.671315	1.269430	1.449289	1.661178
三菱マ  	1.754966	0.364959	0.534652	1.013289	1.463834
日本航空	3.356124	0.858957	0.658006	0.516074	1.314735
丸紅	    0.792348	0.907387	2.944235	2.095312	1.421165
ルネサス	1.462964	1.495325	2.627835	1.128014	1.213882
NTTD	    2.075947	1.300917	1.611125	0.700754	1.162485
セガサミ	1.027843	0.864922	2.163447	1.248041	1.010719
ソフトバンク	1.650660	2.392547	3.726481	0.727452	0.913260
LIXIL	    3.141161	0.487431	0.398951	0.365018	0.869379
世紀東急	5.721280	0.986717	0.443400	0.197358	0.787920
本田技研	1.377587	0.486966	0.908816	0.785603	0.847559
住石HD	    2.640146	2.885812	2.810193	0.408071	0.599789
ゆうちょ銀	1.670923	0.342853	0.527531	0.577344	0.761979
三菱ＵＦＪ	1.187847	0.548672	1.187541	0.791893	0.767798
郵政	    1.175008	0.305039	0.667439	0.772345	0.730220
東洋建設	2.059045	0.984184	1.228872	0.392787	0.623548
アルヒ	    1.075713	0.561906	1.342961	0.512227	0.412143
ユ海運  	0.808126	0.762513	2.425853	0.671280	0.411173
ENEOS	    1.398665	0.426734	0.784404	0.310665	0.342369
NTT	        1.232542	1.059961	2.210978	0.087801	0.081410
```

</details>

### 相関
<details><summary>相関行列の計算</summary>

```correlatin.py
# 相関行列の計算
correlation_matrix = data.corr()

# ヒートマップで相関行列を可視化
plt.figure(figsize=(8, 6))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', square=True)
plt.title('説明変数間の相関ヒートマップ')
plt.show()
```
</details>

![correlations_perpbrroeeps.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/cdd943a7-0562-8ec3-5d50-a57f0d9445b1.png)

<details><summary>相関グラフ描画</summary>

```cor2.py
from pandas import plotting

plotting.scatter_matrix(data[data.columns[:]], figsize=(6,6), alpha=0.8, diagonal='kde')   #全体像を眺める
plt.pause(1)
plt.close()
```
</details>

![correlations_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/f36fa0d8-ae17-82b0-e309-0dc1f50b5a36.png)
## k-meansでクラスタリングして、nmfで次元圧縮してプロットしてみる

<details><summary>NMF</summary>

```NMF.py
from sklearn.decomposition import NMF
#小数点以下2桁
data = data.round(2)

#分類にPriceは使わない
df = data.drop(['Price'], axis = 1)
# NMFを実行して特徴量を抽出
model = NMF(n_components=2, init='random', random_state=0)
W = model.fit_transform(df)
H = model.components_
print("feature1= per pbr roe eps", H[0])
print("feature2= per pbr roe eps", H[1])
```
</details>
NMFで次元圧縮した横軸縦軸は以下のとおり、
横軸；roe, eps
縦軸；per,pbr 

```
feature1= per pbr roe eps [0.         0.50188959 1.53711934 1.78278615]
feature2= per pbr roe eps [2.13742544 1.13387738 0.76728362 0.        ]
```

<details><summary>kmeansでNMF面の座標をクラスタリング</summary>

```nmfして次元圧縮した２次元平面でkmeansでクラスタリング.py

# クラスタリングを実行
kmeans = KMeans(n_clusters=6, init='k-means++', max_iter=300, n_init=10, random_state=0)
clusters2 = kmeans.fit_predict(W)
df['labels_nmf'] = clusters2
```
</details>


<details><summary>NMF面にクラスタリング結果を描画する</summary>
feature1が大きければ大きいほど、epsやroeが大きいので市場価値は高い；もっと買われるかも
feature2が大きければ大きいほど、perやpbrが大きいので市場の評価が高い；買われすぎかも
つまり、クラスター２の領域の銘柄が期待できるかもです。
※投資は自己責任でお願いします

```draw.py
# クラスタリング結果のプロット
plt.figure(figsize=(12, 12))

# それぞれに与える色を決める。
color_codes = {0:'#00FF00', 1:'#FF0000', 2:'#0000FF',3:'#00FFFF', 4:'#FFFF00', 5:'#FF00FF'}
# サンプル毎に色を与える。
colors = [color_codes[x] for x in clusters2]

for x, y, name,stock,label in zip(W[:, 0], W[:, 1], df.index, data["Price"], df['labels_nmf']): #iloc[:, 0]):
    plt.text(x, y, name, alpha=0.8, size=10)
    plt.text(x+0.1, y, stock, alpha=0.8, size=20)
    plt.text(x, y+0.1, label, alpha=0.8, size=20)
plt.scatter(W[:, 0], W[:, 1], alpha=0.8, color=colors)

for i in range(np.max(clusters2) + 1):
    plt.scatter(W[clusters2 == i, 0], W[clusters2 == i, 1], label=f'Cluster {i+1}')
    # クラスタの中心を計算
    center = np.mean(W[clusters2 == i, :], axis=0)
    plt.text(center[0], center[1], str(i), size = 40)
    # クラスタの範囲を計算
    radius = np.max(np.sqrt(np.sum((W[clusters2 == i, :] - center)**2, axis=1)))
    # クラスタを円で囲む
    circle = plt.Circle(center, radius, color='black', fill=False, linestyle='--', linewidth=1.5)
    plt.gca().add_patch(circle)

plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('NMF followed by KMeans++ Clustering with Circles')
plt.legend()
plt.show()
```
</details>

![NMF+kmean_sclustering.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/a22e0a88-fa24-ca84-2cd3-0f58adf1126a.png)

<details><summary>Wをdendrogramでクラスタリング</summary>

```dendrogram.py
linked = linkage(W, 'ward')
plt.figure(figsize=(20, 7))
dendrogram(linked, orientation='top', labels=data.index, distance_sort='ascending', show_leaf_counts=True) #descending
plt.show()
```
</details>

![NMF_dendrogram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/c589e769-3401-b42b-02af-ffcb8ca1f0e9.png)

<details><summary>種々のクラスタリング結果</summary>

```cluster.py
linked_ = linkage(df_, 'ward') #per,pbr,roe,epsで素でデンドログラム
plt.figure(figsize=(20, 7))
dendrogram(linked_, orientation='top', labels=data.index, distance_sort='ascending', show_leaf_counts=True) #descending
plt.show()

clusters_w = fcluster(linked ,t=1, criterion='distance') #NMFでデンドログラム
df['clusters'] = clusters_w # #NMFでデンドログラムでクラスタリング

clusters_df = fcluster(linked_ ,t=4, criterion='distance') #per,pbr,roe,epsで素でデンドログラム
df['clusters_df'] = clusters_df # #per,pbr,roe,epsで素でデンドログラムでクラスタリング
df['Price'] = data['Price'] 
df = df.sort_values('labels_nmf')
df
```
</details>

##### per,pbr,roe,epsをdendrogramでクラスタリング

![df_dendrogram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/7b68b5e5-5bf0-9c73-710b-12cc87d17a36.png)


| params | 解説 |解説 |
|:-:|:-:|:-:|
|labels_nmf|W面でkmeansでクラスタリング|ー|
|clusters|Wをdendrogramでクラスタリング|世紀東急以外同じ結果|
|cluster_df|素のdendrogramでクラスタリング|少し異なるがおおむね一致|


```
	        per	    pbr	    roe	    eps	labels_nmf clusters	clusters_df	Price
Unnamed: 0								
JT	        1.63	1.24	1.96	1.58	0	2	3	2.11
セガサミ	1.03	0.86	2.16	1.25	0	2	3	1.01
オリックス	1.36	0.67	1.27	1.45	0	2	4	1.66
JFE	        1.74	0.48	0.71	1.98	0	2	4	2.64
AGC	        1.74	0.48	0.71	1.98	0	2	4	2.64
三井住友ト	1.18	0.49	1.07	1.70	0	2	4	1.56
ユ海運  	0.81	0.76	2.43	0.67	0	2	3	0.41
ルネサス	1.46	1.50	2.63	1.13	0	2	3	1.21
ソフトバンク	1.65	2.39	3.73	0.73	1	5	1	0.91
TOWA	    3.16	2.98	2.43	1.92	1	5	1	5.30
野村マイクロ	3.04	5.01	4.23	0.94	1	5	1	2.51
東エレデバ	2.03	2.85	3.62	1.84	1	5	1	2.41
安川電機	3.08	2.37	1.98	1.25	1	5	1	3.15
住石HD	    2.64	2.89	2.81	0.41	1	5	1	0.60
住友商事	0.78	0.71	2.33	2.96	2	1	2	2.02
日本製鉄	0.46	0.46	2.59	4.79	2	1	2	1.65
住友精化	0.78	0.47	1.55	4.03	2	1	2	2.45
丸紅	    0.79	0.91	2.94	2.10	2	1	2	1.42
LIXIL	    3.14	0.49	0.40	0.37	3	4	4	0.87
日本航空	3.36	0.86	0.66	0.52	3	4	4	1.31
世紀東急	5.72	0.99	0.44	0.20	4	4	5	0.79
NTTD	    2.08	1.30	1.61	0.70	5	3	4	1.16
三菱マ  	1.75	0.36	0.53	1.01	5	3	4	1.46
トヨタ	    2.15	1.13	1.35	0.98	5	3	4	1.71
太陽誘電	1.87	0.83	1.14	1.17	5	3	4	1.61
本田技研	1.38	0.49	0.91	0.79	5	3	4	0.85
武田薬品	2.01	0.61	0.78	1.31	5	3	4	1.97
ゆうちょ銀	1.67	0.34	0.53	0.58	5	3	4	0.76
三菱ＵＦＪ	1.19	0.55	1.19	0.79	5	3	4	0.77
郵政	    1.18	0.31	0.67	0.77	5	3	4	0.73
東洋建設	2.06	0.98	1.23	0.39	5	3	4	0.62
アルヒ	    1.08	0.56	1.34	0.51	5	3	4	0.41
キヤノン	2.24	1.07	1.22	1.20	5	3	4	2.10
ENEOS	    1.40	0.43	0.78	0.31	5	3	4	0.34
NTT	        1.23	1.06	2.21	0.09    5	3	3	0.08
```

## まとめ
・なんとなく、一定の分析方法を手に入れたと思う
・もっといろいろ分析できるが、今回はここまでとする
・今回の推奨株の今後の株価のふるまいを見たいと思う

・今回は株価や株価の騰落率、や配当などを分類に入れていない。入れたときどうなるかは興味深いと思う