Isomapの教師ありハイパーパラメーターチューニング

[「t-SNEの教師ありハイパーパラメーターチューニング」](https://qiita.com/maskot1977/items/2213e33c31cfc5403bf6)の続編です。同じ方法論が、 Isomap にも適用可能ということで、やってみました。

# Isomap でパラメータを変化させる

Isomap は scikit-learn に実装されているので、それを使ってみましょう。お試し用のデータとして、scikit-learn で取得できる糖尿病データを用いてみます。


```python
from sklearn.manifold import Isomap

import sklearn.datasets
import matplotlib.pyplot as plt

dataset = sklearn.datasets.load_diabetes()

mapper = Isomap()
embedding = mapper.fit_transform(dataset.data)
plt.scatter(embedding[:, 0], embedding[:, 1], c=dataset.target, alpha=0.5)
plt.colorbar()
plt.show()
```

![Isomapの教師ありハイパーパラメーターチューニング_1_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/08a15ff8-9c07-67f8-755f-0bb40c47c5a5.png)


    

    


ここで、点の色は dataset.target にある変数で、この値は Isomap の学習に用いられていないことに注意してください。 Isomap は「教師なし学習」の一種であり、学習に用いた高次元データの構造を可視化する働きをするのですが、その結果として、学習に用いていない変数との関係が見えてくることもあります。

さて、パラメータを変えると、このマッピングがどのくらい変わってしまうのかを見てみましょう。

## n_neighbors


```python
from sklearn.manifold import Isomap
import sklearn.datasets
import matplotlib.pyplot as plt

dataset = sklearn.datasets.load_diabetes()

for n_neighbors in (5, 10, 30, 50):
    mapper = Isomap(n_neighbors=n_neighbors)
    embedding = mapper.fit_transform(dataset.data)
    title='n_neighbors = {0}'.format(n_neighbors)
    plt.title(title)
    plt.scatter(embedding[:, 0], embedding[:, 1], c=dataset.target, alpha=0.5)
    plt.colorbar()
    plt.show()
```

![Isomapの教師ありハイパーパラメーターチューニング_3_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/10170092-53f1-234e-7063-f9031eec3425.png)

    
![Isomapの教師ありハイパーパラメーターチューニング_3_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/5d4a0cab-fa64-918d-3604-3234f75d4b83.png)

    



    
![Isomapの教師ありハイパーパラメーターチューニング_3_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/3ecfb81e-c89d-71d0-f36b-95c22c2ad37b.png)

    



    
![Isomapの教師ありハイパーパラメーターチューニング_3_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/f1a82312-e326-52c5-3819-bdfa8d7685e0.png)

    



    

    


## eigen_solver


```python
from sklearn.manifold import Isomap
import sklearn.datasets
import matplotlib.pyplot as plt

dataset = sklearn.datasets.load_diabetes()

for eigen_solver in ("arpack", "dense"):
    mapper = Isomap(eigen_solver=eigen_solver)
    embedding = mapper.fit_transform(dataset.data)
    title='eigen_solver = {0}'.format(eigen_solver)
    plt.title(title)
    plt.scatter(embedding[:, 0], embedding[:, 1], c=dataset.target, alpha=0.5)
    plt.colorbar()
    plt.show()
```


    
![Isomapの教師ありハイパーパラメーターチューニング_5_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/8e87cfc8-7ff4-9397-30b6-90aee624f296.png)

![Isomapの教師ありハイパーパラメーターチューニング_5_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/b8cc7c40-3826-24b4-5ace-830412483dce.png)

    



    

    


## path_method


```python
from sklearn.manifold import Isomap
import sklearn.datasets
import matplotlib.pyplot as plt

dataset = sklearn.datasets.load_diabetes()

for path_method in ["FW", "D"]:
    mapper = Isomap(path_method=path_method)
    embedding = mapper.fit_transform(dataset.data)
    title='path_method = {0}'.format(path_method)
    plt.title(title)
    plt.scatter(embedding[:, 0], embedding[:, 1], c=dataset.target, alpha=0.5)
    plt.colorbar()
    plt.show()
```


    
![Isomapの教師ありハイパーパラメーターチューニング_7_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/a1483661-9945-cd84-d648-f432634133f1.png)

    



    
![Isomapの教師ありハイパーパラメーターチューニング_7_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/742dc37f-46bb-3a6a-c327-24a86f2bad53.png)

    


## neighbors_algorithm


```python
from sklearn.manifold import Isomap
import sklearn.datasets
import matplotlib.pyplot as plt

dataset = sklearn.datasets.load_diabetes()

for neighbors_algorithm in ["brute", "kd_tree", "ball_tree"]:
    mapper = Isomap(neighbors_algorithm=neighbors_algorithm)
    embedding = mapper.fit_transform(dataset.data)
    title='neighbors_algorithm = {0}'.format(neighbors_algorithm)
    plt.title(title)
    plt.scatter(embedding[:, 0], embedding[:, 1], c=dataset.target, alpha=0.5)
    plt.colorbar()
    plt.show()
```


    
![Isomapの教師ありハイパーパラメーターチューニング_9_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/c2ea84e4-d00a-e275-f3b6-f3354f15b489.png)

    



    
![Isomapの教師ありハイパーパラメーターチューニング_9_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/b1d76a87-7403-8ead-d412-f8ac6086d113.png)

    



    
![Isomapの教師ありハイパーパラメーターチューニング_9_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/954edcc5-b851-fc47-a902-95287c6af03a.png)

    


t-SNE よりは、パラメータ依存が小さいように見えますね。なので、ぶっちゃけ、これ以降の解析の意味はあまりないのかもしれません。



# 回帰問題用スコア関数

教師なし学習である Isomap を「教師あり Isomap」にするためのスコア関数を設計しましょう。回帰問題の場合は、たとえば次のように作れると思います。マッピングされた２点に対して、目的変数の差を計算し、それを２点間のユークリッド距離で割った数値の総和です。


```python
def regression_scorer(X, Y):
    sum = 0
    n1 = 0
    for x1, y1 in zip(X, Y):
        n1 += 1
        n2 = 0
        for x2, y2 in zip(X, Y):
            n2 += 1
            if n1 > n2:
                dist = ((x1[0] - x2[0])**2 + (x1[1] - x2[1])**2) + 1e-53
                sum += (y1 - y2)**2 / dist

    return sum / (len(Y) * (len(Y) - 1) / 2)
```

# Optuna で最適化

パラメータの最適化といえば Optuna。Optuna と言えばパラメータの最適化。ということでインストールします。


```python
!pip install optuna
```

    Collecting optuna
      Downloading optuna-2.10.0-py3-none-any.whl (308 kB)
    [K     |████████████████████████████████| 308 kB 6.8 MB/s 
    [?25hCollecting cmaes>=0.8.2
      Downloading cmaes-0.8.2-py3-none-any.whl (15 kB)
    Requirement already satisfied: scipy!=1.4.0 in /usr/local/lib/python3.7/dist-packages (from optuna) (1.4.1)
    Requirement already satisfied: PyYAML in /usr/local/lib/python3.7/dist-packages (from optuna) (3.13)
    Requirement already satisfied: tqdm in /usr/local/lib/python3.7/dist-packages (from optuna) (4.63.0)
    Collecting colorlog
      Downloading colorlog-6.6.0-py2.py3-none-any.whl (11 kB)
    Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.7/dist-packages (from optuna) (21.3)
    Collecting alembic
      Downloading alembic-1.7.7-py3-none-any.whl (210 kB)
    [K     |████████████████████████████████| 210 kB 45.1 MB/s 
    [?25hCollecting cliff
      Downloading cliff-3.10.1-py3-none-any.whl (81 kB)
    [K     |████████████████████████████████| 81 kB 7.4 MB/s 
    [?25hRequirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from optuna) (1.21.5)
    Requirement already satisfied: sqlalchemy>=1.1.0 in /usr/local/lib/python3.7/dist-packages (from optuna) (1.4.32)
    Requirement already satisfied: pyparsing!=3.0.5,>=2.0.2 in /usr/local/lib/python3.7/dist-packages (from packaging>=20.0->optuna) (3.0.7)
    Requirement already satisfied: importlib-metadata in /usr/local/lib/python3.7/dist-packages (from sqlalchemy>=1.1.0->optuna) (4.11.3)
    Requirement already satisfied: greenlet!=0.4.17 in /usr/local/lib/python3.7/dist-packages (from sqlalchemy>=1.1.0->optuna) (1.1.2)
    Requirement already satisfied: importlib-resources in /usr/local/lib/python3.7/dist-packages (from alembic->optuna) (5.4.0)
    Collecting Mako
      Downloading Mako-1.2.0-py3-none-any.whl (78 kB)
    [K     |████████████████████████████████| 78 kB 7.5 MB/s 
    [?25hCollecting stevedore>=2.0.1
      Downloading stevedore-3.5.0-py3-none-any.whl (49 kB)
    [K     |████████████████████████████████| 49 kB 6.1 MB/s 
    [?25hCollecting pbr!=2.1.0,>=2.0.0
      Downloading pbr-5.8.1-py2.py3-none-any.whl (113 kB)
    [K     |████████████████████████████████| 113 kB 46.7 MB/s 
    [?25hCollecting autopage>=0.4.0
      Downloading autopage-0.5.0-py3-none-any.whl (29 kB)
    Collecting cmd2>=1.0.0
      Downloading cmd2-2.4.0-py3-none-any.whl (150 kB)
    [K     |████████████████████████████████| 150 kB 49.1 MB/s 
    [?25hRequirement already satisfied: PrettyTable>=0.7.2 in /usr/local/lib/python3.7/dist-packages (from cliff->optuna) (3.2.0)
    Requirement already satisfied: typing-extensions in /usr/local/lib/python3.7/dist-packages (from cmd2>=1.0.0->cliff->optuna) (3.10.0.2)
    Collecting pyperclip>=1.6
      Downloading pyperclip-1.8.2.tar.gz (20 kB)
    Requirement already satisfied: wcwidth>=0.1.7 in /usr/local/lib/python3.7/dist-packages (from cmd2>=1.0.0->cliff->optuna) (0.2.5)
    Requirement already satisfied: attrs>=16.3.0 in /usr/local/lib/python3.7/dist-packages (from cmd2>=1.0.0->cliff->optuna) (21.4.0)
    Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata->sqlalchemy>=1.1.0->optuna) (3.7.0)
    Requirement already satisfied: MarkupSafe>=0.9.2 in /usr/local/lib/python3.7/dist-packages (from Mako->alembic->optuna) (2.0.1)
    Building wheels for collected packages: pyperclip
      Building wheel for pyperclip (setup.py) ... [?25l[?25hdone
      Created wheel for pyperclip: filename=pyperclip-1.8.2-py3-none-any.whl size=11137 sha256=0959dc9560c6c3701ab101a86a0767d09a14c52af3fbe2c9212397cecf5f2e79
      Stored in directory: /root/.cache/pip/wheels/9f/18/84/8f69f8b08169c7bae2dde6bd7daf0c19fca8c8e500ee620a28
    Successfully built pyperclip
    Installing collected packages: pyperclip, pbr, stevedore, Mako, cmd2, autopage, colorlog, cmaes, cliff, alembic, optuna
    Successfully installed Mako-1.2.0 alembic-1.7.7 autopage-0.5.0 cliff-3.10.1 cmaes-0.8.2 cmd2-2.4.0 colorlog-6.6.0 optuna-2.10.0 pbr-5.8.1 pyperclip-1.8.2 stevedore-3.5.0


# 教師あり Isomap

Optuna を使って、Isomap を最適化するクラスを設計します。


```python
import scipy

class SupervisedIsomap:
    def __init__(self, X, Y, scorer):
        self.X = X
        self.Y = Y
        self.scorer = scorer
        self.best_score = 1e53
        self.best_model = None

    def __call__(self, trial):
        n_neighbors = trial.suggest_int("n_neighbors", 5, 50)
        eigen_solver = trial.suggest_categorical("eigen_solver", ["arpack", "dense"])
        path_method = trial.suggest_categorical("path_method", ["FW", "D"])
        neighbors_algorithm = trial.suggest_categorical("neighbors_algorithm", ["brute", "kd_tree", "ball_tree"])

        mapper = Isomap(
            n_neighbors=n_neighbors, 
            eigen_solver=eigen_solver,
            path_method=path_method,
            neighbors_algorithm=neighbors_algorithm,
            )
        embedding = mapper.fit_transform(self.X)
        score = self.scorer(scipy.stats.zscore(embedding), self.Y)

        if self.best_score > score:
            self.best_score = score
            self.best_model = mapper
            
            print(self.best_model)
            title='trial={0}, score={1:.3e}'.format(trial.number, score)
            plt.title(title)
            plt.scatter(embedding[:, 0], embedding[:, 1], c=self.Y, alpha=0.5)
            plt.colorbar()
            plt.show()      

        return score
```

最適化計算の実行例です。いくらか省略しながら結果を示します。


```python
import optuna

objective = SupervisedIsomap(dataset.data, dataset.target, regression_scorer)
study = optuna.create_study(direction="minimize")
study.optimize(objective, n_trials=100)
```




    Isomap(eigen_solver='dense', n_neighbors=50, neighbors_algorithm='brute',
           path_method='FW')



![Isomapの教師ありハイパーパラメーターチューニング_19_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/7b1a0649-822d-f115-1c0f-4b04b43ceba2.png)
    

    




    Isomap(eigen_solver='dense', n_neighbors=41, neighbors_algorithm='brute',
           path_method='FW')



    
![Isomapの教師ありハイパーパラメーターチューニング_19_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/c1fd4db6-23d4-d331-c24e-c1e283a50413.png)

    




    Isomap(eigen_solver='arpack', n_neighbors=41, neighbors_algorithm='brute',
           path_method='D')



    
![Isomapの教師ありハイパーパラメーターチューニング_19_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/b915ea00-3560-9e5a-3aba-e6332ef6a4c1.png)

    





    Isomap(eigen_solver='arpack', n_neighbors=44, neighbors_algorithm='brute',
           path_method='D')



    
![Isomapの教師ありハイパーパラメーターチューニング_19_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/e39a88a6-df59-a3a6-956d-39279ac4c622.png)

    





    Isomap(eigen_solver='arpack', n_neighbors=44, neighbors_algorithm='ball_tree',
           path_method='D')



    
![Isomapの教師ありハイパーパラメーターチューニング_19_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/15533321-b9ff-98ee-875c-bb0fa03f22fc.png)

    





    Isomap(eigen_solver='dense', n_neighbors=47, neighbors_algorithm='brute',
           path_method='FW')



    
![Isomapの教師ありハイパーパラメーターチューニング_19_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/2ea08a00-a4fc-1c28-4ff5-5c21362cb002.png)

    





目的変数の分離が最もしやすいパラメータが選択できたのではないかなと思います。

# 分類問題用スコア関数

回帰問題用スコア関数を少しだけ改変して、分類問題用スコア関数にします。分類問題と異なり、回帰問題では異なるクラス間の「差」は常に１であるとします。


```python
def classification_scorer(X, Y, alpha=1e-3):
    sum = 0
    n1 = 0
    for x1, y1 in zip(X, Y):
        n1 += 1
        n2 = 0
        for x2, y2 in zip(X, Y):
            n2 += 1
            if n1 > n2:
                dist = ((x1[0] - x2[0])**2 + (x1[1] - x2[1])**2) + 1e-53
                if y1 != y2:
                    sum += 1 / dist
                else:
                    pass
                    
    return sum / (len(Y) * (len(Y) - 1) / 2)
```

それ以外は、回帰問題と同じですね。

## 乳がんデータセット

乳がんデータセットを用いた２値分類の例です。


```python
from sklearn.datasets import load_breast_cancer

dataset = load_breast_cancer()
```


```python
import optuna

objective = SupervisedIsomap(dataset.data, dataset.target, classification_scorer)
study = optuna.create_study(direction="minimize")
study.optimize(objective, n_trials=100)
```




    Isomap(eigen_solver='dense', n_neighbors=47, neighbors_algorithm='ball_tree',
           path_method='D')



    
![Isomapの教師ありハイパーパラメーターチューニング_24_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/8fa361fc-e5aa-77a0-ac55-5eeb469f3f51.png)

    





    Isomap(eigen_solver='arpack', n_neighbors=47, neighbors_algorithm='brute',
           path_method='FW')



    
![Isomapの教師ありハイパーパラメーターチューニング_24_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/c54b8384-06b4-7b0a-ba3f-f2bbbb1ad0a1.png)

    





    Isomap(eigen_solver='arpack', n_neighbors=47, neighbors_algorithm='brute',
           path_method='FW')



    
![Isomapの教師ありハイパーパラメーターチューニング_24_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/f1f5cb6a-6bee-9303-1dd8-86a456ba3e72.png)

    





    Isomap(eigen_solver='arpack', n_neighbors=47, neighbors_algorithm='brute',
           path_method='FW')



    
![Isomapの教師ありハイパーパラメーターチューニング_24_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/76f3f6d4-2e28-3fef-f34f-f6d397f94bad.png)

    





    Isomap(eigen_solver='arpack', n_neighbors=47, neighbors_algorithm='brute',
           path_method='FW')



    
![Isomapの教師ありハイパーパラメーターチューニング_24_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/9b5164df-f73d-12ec-4c73-c8e3bee5b03c.png)

    





    Isomap(eigen_solver='arpack', n_neighbors=47, neighbors_algorithm='brute',
           path_method='FW')



    
![Isomapの教師ありハイパーパラメーターチューニング_24_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/125bd355-3f4a-6563-7b7e-0737af9b76df.png)

    




## ワインデータセット

ワインデータセットを用いた例です。このように、ラベルが３種類以上の場合でも実行可能です。


```python
from sklearn.datasets import load_wine

dataset = load_wine()
```


```python
import optuna

objective = SupervisedIsomap(dataset.data, dataset.target, classification_scorer)
study = optuna.create_study(direction="minimize")
study.optimize(objective, n_trials=100)
```




    Isomap(eigen_solver='arpack', n_neighbors=8, neighbors_algorithm='ball_tree',
           path_method='D')



    
![Isomapの教師ありハイパーパラメーターチューニング_27_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/1e9eebaa-801c-72f9-a89d-2c0ed0edc4cd.png)

    





    Isomap(eigen_solver='arpack', n_neighbors=42, neighbors_algorithm='ball_tree',
           path_method='FW')



    
![Isomapの教師ありハイパーパラメーターチューニング_27_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/04436e56-12f8-4695-b6ce-1a3f85780932.png)

    





    Isomap(eigen_solver='dense', n_neighbors=42, neighbors_algorithm='brute',
           path_method='FW')



    
![Isomapの教師ありハイパーパラメーターチューニング_27_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/bc10bf6d-96e9-eaa0-c27c-29d2ced6221f.png)

    





    Isomap(eigen_solver='arpack', n_neighbors=45, neighbors_algorithm='brute',
           path_method='D')



    
![Isomapの教師ありハイパーパラメーターチューニング_27_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/85d62597-72f4-98a2-b2de-5490adddd4fa.png)

    





    Isomap(eigen_solver='arpack', n_neighbors=45, neighbors_algorithm='ball_tree',
           path_method='D')



    

![Isomapの教師ありハイパーパラメーターチューニング_27_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/7383bc6a-6016-415c-7d63-21aed1e55e44.png)

    




## 手書き数字データセット

手書き数字データセットを用いた例です。この例ではラベルが１０種類あります。


```python
from sklearn.datasets import load_digits

dataset = load_digits()
```


```python
import optuna

objective = SupervisedIsomap(dataset.data, dataset.target, classification_scorer)
study = optuna.create_study(direction="minimize")
study.optimize(objective, n_trials=100)
```




    Isomap(eigen_solver='arpack', n_neighbors=32, neighbors_algorithm='kd_tree',
           path_method='D')



    
![Isomapの教師ありハイパーパラメーターチューニング_30_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/9aff1e3f-cddb-0033-b83a-bbe6c6f6e353.png)

    





    Isomap(eigen_solver='arpack', n_neighbors=21, neighbors_algorithm='kd_tree',
           path_method='FW')



    
![Isomapの教師ありハイパーパラメーターチューニング_30_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/6aa5aa3d-fb60-2d39-2312-560873b22b82.png)

    





    Isomap(eigen_solver='dense', n_neighbors=45, neighbors_algorithm='brute',
           path_method='FW')



    
![Isomapの教師ありハイパーパラメーターチューニング_30_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/cf3135fa-55dd-1a95-bb39-62fc3a01f496.png)

    





    Isomap(eigen_solver='dense', n_neighbors=50, neighbors_algorithm='kd_tree',
           path_method='FW')



    
![Isomapの教師ありハイパーパラメーターチューニング_30_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/8a6e3d73-7898-fb8b-d10a-a99ef499066a.png)

    





    Isomap(eigen_solver='dense', n_neighbors=44, neighbors_algorithm='kd_tree',
           path_method='FW')



    
![Isomapの教師ありハイパーパラメーターチューニング_30_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/57bbc714-25c3-9e92-d595-70bbc6b42c10.png)

    





    Isomap(eigen_solver='arpack', n_neighbors=29, neighbors_algorithm='kd_tree',
           path_method='D')



    
![Isomapの教師ありハイパーパラメーターチューニング_30_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/c15fc6e3-cb83-7bca-9a34-1b545c48bd30.png)

    





    Isomap(eigen_solver='arpack', n_neighbors=29, neighbors_algorithm='kd_tree',
           path_method='D')



    
![Isomapの教師ありハイパーパラメーターチューニング_30_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/896efff3-7c42-f688-2de4-43f6ab36286c.png)

    



# おわりに

Isomapは、データにもよりますがパラメータ依存が小さいようですね。t-SNEと比べてみると面白いです。