主成分分析と因子分析でのbiplotの作り方

R言語ではbiplotが関数としてありますがPythonではコーディングしないとできません。
そこでR言語と同じようなbiplotの作り方を紹介します。

# ライブラリのインポート
## 共通のライブラリ
```Python3
from sklearn.preprocessing import StandardScaler
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
```
## 次元圧縮ライブラリ
```Python
from sklearn.decomposition import PCA #主成分分析
from sklearn.decomposition import FactorAnalysis as FA #因子分析
```
# データの読み込み
```Python3
df = pd.read_csv("wine.csv")
```
## 説明変数と目的変数を分離
教師ありの場合などは圧縮後に色を付けると構造が分かりやすくなります。
```Python3
y = df["Wine"]
x = df.drop("Wine", axis=1)
```

# データの標準化
基本的に単位尺度を揃えないと大きな値や外れ値に影響されやすくなり本来の分布と異なるため標準化を行います。
```Python3
ss = StandardScaler()
ss.fit(x)
sx = ss.transform(x)
```

# 主成分分析
ここからは実際に主成分分析で次元を圧縮します。
## PCAで圧縮
```Python3
model = PCA()
model.fit(sx)
tx = model.transform(sx)
```

## 寄与率と固有ベクトルから因子負荷量を計算
```Python3
evr = model.explained_variance_ratio_
com = model.components_
fac = []
for i in range(len(evr)):
    fac.append(np.sqrt(evr[i])*com[i])
```

## 両軸グラフを作る
片方のX軸Y軸は圧縮後のデータ用に、もう片方のX軸Y軸は因子負荷量にします。
```Python3
fig, ax = plt.subplots()
ax1 = ax.twinx()
ax2 = ax.twiny()
```

### 圧縮したデータをプロット
```Python3
ax1.scatter(tx[:, 0], tx[:, 1], c=y, cmap="brg")
```
### プロット範囲のリストを作る
```Python3
xlim = [abs(min(fac[0])), abs(max(fac[0]))]
ylim = [abs(min(fac[1])), abs(max(fac[1]))]
```
### プロット範囲を指定する
```Python3
ax2.set_xlim(-max(xlim), max(xlim))
ax2.set_ylim(-max(ylim), max(ylim))
```
### 因子負荷量をベクトル化する
```Python3
for i in range(len(x.columns)):
    ax2.annotate("", xytext=[0, 0], xy=[fac[0][i], fac[1][i]],
                 arrowprops=dict(shrink=0, width=1, headwidth=6, 
                                headlength=10, connectionstyle='arc3',
                                facecolor='red', edgecolor='red'))
    ax2.text(fac[0][i], fac[1][i], x.columns[i])
plt.show()
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/c397ea17-3a4c-a0dd-fb1b-4217e1d0861d.png)
完成しました。

# 因子分析
因子分析では「components_」が因子負荷量に相当します。
## 次元圧縮
```Python3
model = FA()
model.fit(sx)
tx = model.transform(sx)
```

## 因子負荷量の計算
```Python3
com = model.components_
```

## 両軸グラフを作る
基本的な流れは主成分分析と変わりません
```Python3
fig, ax = plt.subplots()
ax1 = ax.twinx()
ax2 = ax.twiny()
```
### 圧縮したデータをプロット
```Python3
ax1.scatter(tx[:, 0], tx[:, 1], c=y, cmap="brg")
```
### プロット範囲のリストを作成
```Python3
xlim = [abs(min(com[0])), abs(max(com[0]))]
ylim = [abs(min(com[1])), abs(max(com[1]))]
```
### プロット範囲を指定
```Python3
ax2.set_xlim(-max(xlim), max(xlim))
ax2.set_ylim(-max(ylim), max(ylim))
```
### 因子負荷量のベクトルを図示
```Python3
for i in range(len(x.columns)):
    ax2.annotate("", xytext=[0, 0], xy=[com[0][i], com[1][i]],
                 arrowprops=dict(shrink=0, width=1, headwidth=6, 
                                headlength=10, connectionstyle='arc3',
                                facecolor='red', edgecolor='red'))
    ax2.text(com[0][i], com[1][i], x.columns[i])
plt.show()
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/09fce38c-6a19-7b25-3b8f-50527dc21201.png)
完成しました。

# 全体コード
## 主成分分析
```Python3
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

df = pd.read_csv("wine.csv")
y = df["Wine"]
x = df.drop("Wine", axis=1)
ss = StandardScaler()
ss.fit(x)
sx = ss.transform(x)
model = PCA()
model.fit(sx)
tx = model.transform(sx)
evr = model.explained_variance_ratio_
com = model.components_
fac = []
for i in range(len(evr)):
    fac.append(np.sqrt(evr[i])*com[i])
fig, ax = plt.subplots()
ax1 = ax.twinx()
ax2 = ax.twiny()
ax1.scatter(tx[:, 0], tx[:, 1], c=y, cmap="brg")
xlim = [abs(min(fac[0])), abs(max(fac[0]))]
ylim = [abs(min(fac[1])), abs(max(fac[1]))]
ax2.set_xlim(-max(xlim), max(xlim))
ax2.set_ylim(-max(ylim), max(ylim))
for i in range(len(x.columns)):
    ax2.annotate("", xytext=[0, 0], xy=[fac[0][i], fac[1][i]],
                 arrowprops=dict(shrink=0, width=1, headwidth=6, 
                                headlength=10, connectionstyle='arc3',
                                facecolor='red', edgecolor='red'))
    ax2.text(fac[0][i], fac[1][i], x.columns[i])
plt.show()
```

## 因子分析
```Python3
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import FactorAnalysis as FA
from sklearn.preprocessing import StandardScaler

df = pd.read_csv("wine.csv")
y = df["Wine"]
x = df.drop("Wine", axis=1)
ss = StandardScaler()
ss.fit(x)
sx = ss.transform(x)
model = FA()
model.fit(sx)
tx = model.transform(sx)
com = model.components_
fig, ax = plt.subplots()
ax1 = ax.twinx()
ax2 = ax.twiny()
ax1.scatter(tx[:, 0], tx[:, 1], c=y, cmap="brg")
xlim = [abs(min(com[0])), abs(max(com[0]))]
ylim = [abs(min(com[1])), abs(max(com[1]))]
ax2.set_xlim(-max(xlim), max(xlim))
ax2.set_ylim(-max(ylim), max(ylim))
for i in range(len(x.columns)):
    ax2.annotate("", xytext=[0, 0], xy=[com[0][i], com[1][i]],
                 arrowprops=dict(shrink=0, width=1, headwidth=6, 
                                headlength=10, connectionstyle='arc3',
                                facecolor='red', edgecolor='red'))
    ax2.text(com[0][i], com[1][i], x.columns[i])
plt.show()
```
# 参考文献

https://qiita.com/haru1843/items/e85fe45163cd9763023c