pyHSICLasso

# pyHSICLasso package

pyHSICLassoは、Pythonで利用可能なHSIC Lasso（Hilbert-Schmidt Independence Criterion Least Absolute Shrinkage and Selection Operator）の実装です。このライブラリは、特徴選択とデータの非線形依存関係の分析に使用されます。

https://github.com/riken-aip/pyHSICLasso


2023/12/27, GPT4を利用して記述。


## 説明

HSIC Lasso (Hilbert-Schmidt Independence Criterion Least Absolute Shrinkage and Selection Operator)は、特徴選択と非線形依存関係の検出に使用される機械学習の手法です。この手法は、複数の特徴間の依存性を評価し、関連する特徴を選択することにより、データセット内の重要な情報を抽出します。HSIC Lassoは、特に大規模なデータセットや非線形関係が含まれる場合に有用です。

HSIC Lasso自体は、予測モデルを構築するためのツールではありません。HSIC Lassoは特徴選択に特化した手法であり、データセット内の特徴量の中から、ターゲット変数と最も強い関係を持つ特徴量を選択するために使用されます。このプロセスは、データの理解を深めたり、効果的な機械学習モデルを構築するための前処理ステップとして非常に有用です。

HSIC Lassoは次のように機能します：

1. **特徴選択**: データセットから重要な特徴量を選択します。
2. **関連性の評価**: 特徴量とターゲット変数との間の非線形関係を評価します。

しかし、HSIC Lasso自体には予測機能（`predict`メソッドなど）は含まれておらず、モデルのトレーニングや予測のための直接的な機能は提供しません。代わりに、HSIC Lassoを用いて特徴選択を行った後、選択された特徴を使用して、`scikit-learn`などの機械学習ライブラリに含まれる予測モデル（例えば線形回帰、ランダムフォレスト、サポートベクターマシンなど）をトレーニングし、予測を行うことが一般的です。

つまり、HSIC Lassoは予測プロセスの一部として使用されるものの、予測自体は他の機械学習アルゴリズムによって行われます。

## インストール

```
pip install pyHSICLasso
```

## 例

### 分類モデル例１

#### ソースコード
```python
# 必要なライブラリをインポート
from pyHSICLasso import HSICLasso
from sklearn.datasets import load_iris
import numpy as np

# scikit-learnからサンプルデータセットをロード
iris = load_iris()
X = iris.data  # 特徴量の行列
y = iris.target  # ターゲット変数

# HSICLassoのインスタンスを作成
hsic_lasso = HSICLasso()

# データをHSICLassoに入力
hsic_lasso.input(X, y)

# 特徴選択を実行
# 例えば、アイリスデータセットの4つの特徴量のうち3つを選択
hsic_lasso.classification(3)

# 選択された特徴量を取得
selected_features = hsic_lasso.get_index()

# 選択された特徴量を出力
print(selected_features)

# L1 pathの出力.　標準では'path.png' filepath='...'でファイル名の指定も可能。
hsic_lasso.plot_path(filepath='L1_path.png')
```

#### 出力
```
Block HSIC Lasso B = 20.
M set to 3.
Using Gaussian kernel for the features, Delta kernel for the outcomes.

[3, 2, 1]
```


hsic_lasso.plot_path()
の出力図はファイルとして保存されます。

![](hsic-lasso1.path.png)

legendには説明変数の名前でなく、説明変数のindexが入っています。
scikit-learnで紹介されている
Regularization path of L1- Logistic Regression
のHSIC-Lasso版です。

#### 出力の解説

`[3, 2, 1]`という出力は、`pyHSICLasso`によって行われた特徴選択の結果です。この結果は、選択された特徴量のインデックスを示しています。具体的には、アイリスデータセットの中で、ターゲット変数（アイリスの種類）と最も強い非線形関係を持つと判定された特徴量のインデックスです。

アイリスデータセットには4つの特徴量があります：

1. Sepal Length（がくの長さ）
2. Sepal Width（がくの幅）
3. Petal Length（花びらの長さ）
4. Petal Width（花びらの幅）

出力された`[3, 2, 1]`は、これらの特徴量のうち、「Petal Width（インデックス3）」、「Petal Length（インデックス2）」、および「Sepal Width（インデックス1）」がターゲット変数と最も強い非線形関係を持つとHSIC Lassoによって判定されたことを意味しています。このことは、これらの特徴量がアイリスの種類を区別する上で重要な役割を果たす可能性が高いことを示唆しています。

HSIC Lassoは、特にデータの中に非線形関係が存在する場合に有用な特徴選択手法です。この結果を利用して、より効果的な機械学習モデルの構築やデータ分析が可能になります。


`hsic_lasso.plot_path()` メソッドは、HSIC Lassoアルゴリズムによる特徴選択のプロセスを視覚的に表現するためのものです。このプロットは、各特徴の重要度がどのように変化するかを示し、アルゴリズムがどの特徴を重要と判断したかを理解するのに役立ちます。

#### HSIC Lasso Path Plotの見方

1. **軸の説明**:
   - **縦軸（Y軸）**: 特徴の重要度（スコア）を表します。通常、HSIC値や関連度スコアなどとして表示されます。
   - **横軸（X軸）**: アルゴリズムが進行するにつれて考慮される特徴の数を表します。左から右に移動するにつれて、追加の特徴が考慮されます。

2. **線の解釈**:
   - プロットには、データセット内の各特徴に対応する複数の線が表示されます。
   - 各線は特定の特徴を表し、その特徴の重要度がアルゴリズムの進行とともにどのように変化するかを示します。
   - 線が上昇すると、その特徴の重要度が増加していることを意味します。

3. **選択される特徴**:
   - プロットの特定の点で、特定の線が突出して上昇する場合、その時点でその特徴が選択されたことを示します。
   - 一般に、より早く突出して上昇する特徴ほど、より重要であると考えられます。

4. **特徴の比較**:
   - 線の相対的な位置や上昇の仕方を比較することで、特徴間の相対的な重要度を評価できます。

HSIC Lasso Path Plotは、特徴選択プロセスの直感的な理解を深めるのに役立ちます。特に、多くの特徴を持つデータセットにおいて、どの特徴が最終的に選択されるか、またそれらがどのように関連しているかを視覚化するのに有用です。

#### コメント

```
hsic_lasso.dump()
hsic_lasso.save_param()
```
は残念ながらエラーが出て動作しない。


### 回帰モデル例１

#### ソースコード

```python
from pyHSICLasso import HSICLasso
from sklearn.datasets import load_diabetes
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
import numpy as np

# 糖尿病データセットをロード
diabetes = load_diabetes()
X = diabetes.data
y = diabetes.target
feature_names = diabetes.feature_names
print(X.shape, y.shape, feature_names)

# 訓練データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

# HSIC Lassoのインスタンスを作成
hsic_lasso = HSICLasso()

# HSIC Lassoで特徴選択を行う
hsic_lasso.input(X_train, y_train, featname=feature_names)
hsic_lasso.regression(num_feat=5)  # ここでは上位5つの特徴を選択

# 選択された特徴量のインデックスを取得
feature_names = np.array(feature_names)
selected_features = feature_names[hsic_lasso.get_index()]
print(selected_features)

hsic_lasso.dump()
hsic_lasso.plot_path(filepath='diabetes_path.png')

# hsic_lasso.save_param() # 機能しない。
```

####  出力
```
(442, 10) (442,) ['age', 'sex', 'bmi', 'bp', 's1', 's2', 's3', 's4', 's5', 's6']
Block HSIC Lasso B = 20.
M set to 3.
Using Gaussian kernel for the features, Gaussian kernel for the outcomes.
['s5' 'bmi' 'bp' 's3' 's4']
============================================== HSICLasso : Result ==================================================
| Order | Feature      | Score | Top-5 Related Feature (Relatedness Score)                                          |
| 1     | s5           | 1.000 | s4           (0.386), bmi          (0.288), s1           (0.262), s3           (0.256), s6           (0.245)|
| 2     | bmi          | 0.928 | s5           (0.288), s4           (0.225), bp           (0.220), s3           (0.198), s6           (0.189)|
| 3     | bp           | 0.359 | age          (0.228), bmi          (0.220), s5           (0.202), s6           (0.196), s4           (0.180)|
| 4     | s3           | 0.356 | s4           (0.552), s5           (0.256), bmi          (0.198), s6           (0.168), sex          (0.167)|
| 5     | s4           | 0.008 | s3           (0.552), s5           (0.386), s2           (0.366), s1           (0.277), s6           (0.225)|
```
`hsic_lasso.dump()` によって表示された結果は、HSIC Lassoアルゴリズムを用いた特徴選択の結果を示しています。hsic_lasso.regression(num_feat=5) のnum_featの数を変えると出力数は変わります。
この出力は、scikit-learnの`load_diabetes()`データセットに対して行われた特徴選択の結果を表しており、以下の情報が含まれています：

1. **Order**: 特徴の重要度順位。最も重要な特徴が1位です。

2. **Feature**: 特徴の名前。このデータセットでは、特徴は`s1`, `s2`, `s3`,... などと表されています。

3. **Score**: 特徴のスコア。この値は特徴の重要度を示し、1.000が最も重要で、値が小さいほど重要度が低くなります。

4. **Top-5 Related Feature (Relatedness Score)**: 選択された特徴と関連性の高い上位5つの特徴及びその関連性スコア。このスコアは、選択された特徴と他の特徴との関連性の強さを示します。

例えば、最初の行では「s5」という特徴が最も重要な特徴として選択されており、そのスコアは1.000です。また、「s5」は「s4」（関連性スコア0.386）や「bmi」（関連性スコア0.288）などと関連性が高いことが示されています。

この情報は、データセット内の特徴間の関連性や、特定の特徴がターゲット変数（この場合は糖尿病の進行状況）に対してどの程度重要であるかを理解するのに役立ちます。これにより、予測モデルの構築やデータの分析において、重点を置くべき特徴を決定することができます。

hsic_lasso.plot_path()
の出力図は以下になります。legendには説明変数の名前でなく、説明変数のindexが入っています。

![](diabetes_path.png)

## 内部パラメタについて

HSIC Lassoは特徴の数dに関してよくスケールします。しかし、通常のHSIC LassoはO(dn^2)のメモリスペースを必要とし、サンプル数nが1000を超えるとメモリ不足になる可能性があります。このような場合には、ブロックHSIC Lassoを使用することができます。これは、O(dnBM)のスペースのみを必要とします。ここで、B << nはブロックパラメータであり、Mは最終結果を安定させるための順列パラメータです。これは、回帰または分類機能でBとMパラメータを指定することによって行うことができます。現在、デフォルトのパラメータはそれぞれB=20、M=3です。通常のHSIC Lassoを使用したい場合は、B=0およびM=1を使用してください。

## 参考

- HSIC Lassoの他の実装に
https://github.com/nttcom/HSICLassoVI
があります。本原稿を記載した時点ではこちらの方が新しいpackageですが、scikit-learnをsklearnとしてインストールすることを記述し、なぜかinstall packageの記述が古くscikit-learnがinstallできなかったので試しておりません。

- 類似手法
https://github.com/jenninglim/multiscale-features