はじめに
Pythonで機械学習などを扱っていると,二次元以上の多次元の行列を可視化したくなりますよね.
自分用メモとしてスニペットを載せます.
前提
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
Qiita記事用に使用するデータはすべてランダムデータ
matrix_2d = np.random.rand(5, 5)
matrix_3d = np.random.rand(5, 5, 5)
2次元
ヒートマップ
大体の可視化手法はこれに勝てない.
ヒートマップ亜種みたいなものがたくさんある.
plt.figure(figsize=(10, 10))
sns.heatmap(matrix_2d, annot=True, fmt=".2f", cmap='viridis')
plt.title('2D Matrix Heatmap')
plt.show()
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F609800%2F65074908-69df-46a4-edda-b8b3570e9460.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=bf99df63d545b3d58820b4a5402b6009)
等高線
plt.figure(figsize=(10, 8))
contour = plt.contour(matrix_2d, cmap='viridis')
plt.clabel(contour, inline=True, fontsize=8)
plt.colorbar(contour, label='Scale')
plt.title('2D Matrix Contour Plot')
plt.xlabel('X-axis Label')
plt.ylabel('Y-axis Label')
plt.show()
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F609800%2F44ffc2c8-def6-59e5-7f78-8dd31089f30e.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=2e6a2bd6ffcac8f5bc74c929d15f73b4)
3Dプロット
from mpl_toolkits.mplot3d import Axes3D
x = np.arange(matrix_2d.shape[0])
y = np.arange(matrix_2d.shape[1])
x, y = np.meshgrid(x, y)
z = matrix_2d
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(x, y, z, cmap='viridis')
plt.title('2D Matrix Surface Plot')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
ax.set_zlabel('Z-axis')
plt.show()
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F609800%2Fe5446350-b3a0-4ac1-6aad-f6bfb5dce581.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=21bbffafcac17ce09ce056b6fbe37790)
3次元
ちゃんと傾向がはっきりしているデータなら可視化しやすいが,そうでないなら可視化より他の統計的な手法で分析した方がいい.
複数ヒートマップ
2次元ヒートマップをいくつも並べるだけ
for i in range(matrix_3d.shape[2]):
plt.figure(figsize=(6, 5))
sns.heatmap(matrix_3d[:, :, i], annot=False, cmap='viridis')
plt.title(f'Slice {i+1} of 3D Matrix')
plt.show()
Axes3D
数字の格納されている場所のプロット
0と1や0と小数など,0がいっぱい入っているようなSparseな行列の可視化には使えるかも?
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
x, y, z = matrix_3d.nonzero()
ax.scatter(x, y, z, c=matrix_3d[x, y, z], cmap='viridis')
plt.title('3D Matrix Scatter Plot')
plt.show()
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F609800%2F56ae92f7-a8da-1699-9194-3f3e899d52e2.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=1c0ea072bbdc54b100628a7a0ca6e1f7)
マーチングキューブ法
点の配置に規則性があるなら,メッシュを張れば何か分かるかもしれない.
そんなデータはあまりなさそうな気もする.
from skimage import measure
verts, faces, _, _ = measure.marching_cubes(matrix_3d, level=0.5)
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(verts[:, 0], verts[:, 1], faces, verts[:, 2], cmap='Spectral', lw=1)
plt.title('3D marching cubes Plot')
plt.show()
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F609800%2Ff4b1b18e-b879-35ec-a299-7d45291ab802.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=1e4224ba7784f01d9abe0c4f10f8861d)
多次元
可視化というよりは,可視化したい次元をどう選択するか,どう処理して次元を削減するか,といったことを考えた方が良さそう
4次元データ: 複数のAxes3D
単純だが分かりにくい
for i in range(matrix_4d.shape[3]):
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
data_slice = matrix_4d[:, :, :, i]
x, y, z = data_slice.nonzero()
ax.scatter(x, y, z, c=data_slice[x, y, z], cmap='viridis')
plt.title(f'Slice {i+1} of 4D Matrix')
plt.show()
主成分分析
皆さんご存じ主成分分析.
ライブラリが勝手にやってくれるが,主成分分析が効くようなデータであることが前提
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
reduced_matrix = pca.fit_transform(matrix_5d)
plt.figure(figsize=(8, 6))
plt.scatter(reduced_matrix[:, 0], reduced_matrix[:, 1])
plt.title('5D Matrix Reduced to 2D using PCA')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.show()
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F609800%2F94ed4d18-951b-3011-0bb6-b410a871034a.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=91a8ee26f91b0a4848e0526bea62a6a4)
t-SNE
こちらも主成分分析と同様に次元圧縮の手法.
特に可視化に使用することを意図しているらしい.
sklearnが勝手にやってくれるので,使用感はPCAと一緒.
from sklearn.manifold import TSNE
tsne = TSNE(n_components=2, random_state=42)
reduced_matrix_tsne = tsne.fit_transform(matrix_5d)
plt.scatter(reduced_matrix_tsne[:, 0], reduced_matrix_tsne[:, 1])
UMAP
非線形データでもいけるらしい.
import umap
reducer = umap.UMAP(n_components=2)
embedding = reducer.fit_transform(matrix_5d)
plt.scatter(embedding[:, 0], embedding[:, 1])
MDS
データの位置関係を大事にするらしい.
from sklearn.manifold import MDS
mds = MDS(n_components=2, random_state=42)
mds_result = mds.fit_transform(matrix_5d)
plt.scatter(mds_result[:, 0], mds_result[:, 1])
さいご
行列の可視化手法って,亜種みたいなものは多いですが,アイデア自体は思ったより少ないですね……筆者が見つけられていないだけかも