ネイティブ Python拡張の出力ノード：データとペアプロット図（散布図行列）の表示

SPSS Modeler18.5の新機能の [ネイティブ Python API](https://www.ibm.com/docs/ja/spss-modeler/18.5.0?topic=spark-native-python-apis)のテストをしてみました。これは、「拡張ノード」のなかでpandasを使ってModelerのデータを読んだり書いたりすることができる機能です。

この記事ではネイティブ Python APIで「拡張の出力ノード」が、どのように利用可能かをテストしてみました。
マニュアルに[サンプル・ストリーム](https://www.ibm.com/docs/ja/SS3RA7_18.5.0/modeler_r_nodes_ddita/clementine/python-extension-demo.zip)がついていましたので、これを修正してテストしてみています。

サンプルストリームは以下です。

https://github.com/hkwd/231229NativePythonExtension/raw/master/231229NativePythonExtensionSample/python-extension-demo_hkwd.str

* テスト環境
    * Windows 11 64bit
    * Modeler 18.5
    * Python 3.10.7

# データとデータモデルの出力
製品同梱のサンプルデータの「DRUG1n」を表示してみます。

以下のようなデータになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/b12aff95-e838-9a74-6eb7-e096cb602247.png)

「Python」を選択し、「Python Syntax」の欄に以下のスクリプトを記入します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/001a9e8a-c9ab-026e-2128-37612f1ae672.png)


```python:# データとデータモデルの出力
# ネイティブ Python APIのパッケージ
import modelerpy

#Modelerのデータをpandas Dataframeに読込
modelerData = modelerpy.readPandasDataframe()

#Modelerのデータモデルを取得
modelerDataModel = modelerpy.getDataModel()

#データの表示
print("----modelerData----")
print(modelerData)

#データモデルの表示
print("----modelerDataModel----")
for f in modelerDataModel.getFields():
    print(f.getName()+" "+f.getStorage()+" "+f.getMeasure())
```

[modelerpy.readPandasDataframe()](https://www.ibm.com/docs/ja/spss-modeler/18.5.0?topic=spark-native-python-apis#extension_nativepython_api__title__4)で前のノードのデータをpandasのDataFrameに読み込んでいます。

[modelerpy.getDataModel()](https://www.ibm.com/docs/ja/spss-modeler/18.5.0?topic=spark-native-python-apis#extension_nativepython_api__title__6)は「データ型ノード」で定義されていたデータモデルを取得します。

以下で、[modelerDataModel.getFields()](https://www.ibm.com/docs/ja/spss-modeler/18.5.0?topic=spark-native-python-apis#extension_nativepython_api__title__6)はデータモデルから各列の情報を抜き出します。getNameで列名、getStorageでデータ型、getMeasureで尺度を取り出しています。
```python
for f in modelerDataModel.getFields():
    print(f.getName()+" "+f.getStorage()+" "+f.getMeasure())
```


### 結果
以下のようにデータとデータモデルが出力されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/c358e0e3-a1cf-c6f6-b407-1201fb8941d7.png)

# ペアプロット図（散布図行列）グラフ出力
「拡張出力ノード」では、コンソールにテキストを出力するだけではなく、グラフも出力することができます。

あらかじめ、以下のコマンドを[管理者権限で実行してmatplotlibとseabornを導入しておきます](https://qiita.com/kawada2017/items/9252f93cf59948dd2810)。
```powershell
"C:\Program Files\IBM\SPSS\Modeler\18.5\python_venv\Scripts\python.exe" -m pip install matplotlib
"C:\Program Files\IBM\SPSS\Modeler\18.5\python_venv\Scripts\python.exe" -m pip install seaborn
```

「Python」を選択し、「Python Syntax」の欄に以下のスクリプトを記入します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/54d11ed1-9a4f-a184-1dd8-0cefb24a7fba.png)



```python:グラフを表示
###Use this code to import data from Modeler to Python
# ネイティブ Python APIのパッケージ
import modelerpy

#Modelerのデータをpandas Dataframeに読込
modelerData = modelerpy.readPandasDataframe()

import matplotlib.pyplot as plt
import seaborn as sns

#seabornでpairplotのグラフを表示
sns.pairplot(modelerData, hue='K')
sns.pairplot(modelerData, hue='Age')
plt.show()

```

sns.pairplot(modelerData, hue='K')などでグラフをつくり、
plt.show()で表示しています。

### 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/eaab29a6-dac6-caad-d3e8-7187f26b5b83.png)

ちなみに、Pythonのウィンドウでグラフを表示している間、下記のように常にストリームが実行中となっています。
ストリーム処理を完了させるために、Pythonのウィンドウを閉じる必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/9f961547-b6fb-1272-4efa-0992c7649734.png)

ネイティブPythonでも、Python for SparkやRのように拡張出力ノード内グラフ出力タブへのグラフ出力がサポートされると良いと思いましたので、新機能のアイデアとして投稿してみました。
ご賛同いただける方は、下記URLより、Voteをクリックして投票いただけますと幸いです。
機能の開発が確約されるものではありませんが、投票数が多いと検討対象となります。

#### Extension Output Node for Native Python with Graph Output tab like R and Python for Spark

https://ibm-data-and-ai.ideas.aha.io/ideas/MDLR-I-421

# 参考

#### SPSS Modeler18.5の新機能の ネイティブ Python API #SPSS - Qiita 
https://qiita.com/kawada2017/items/0ae6f0974788b372dc4f
#### ネイティブ Python拡張のインポートノード：CSVファイルの読み込み 
https://qiita.com/kawada2017/items/72a15c121d196b7f5b0a
#### ネイティブ Python拡張の変換ノード：置き換え 
https://qiita.com/kawada2017/items/5c58017404ddd08a60eb
#### ネイティブ Python拡張モデルノード：モデル作成OneClassSVM 
https://qiita.com/kawada2017/items/965b5bd6fff90d2cfc02
#### ネイティブ Python拡張の出力ノード：データとペアプロット図（散布図行列）の表示 
https://qiita.com/kawada2017/items/be3fddcdf7ed11d80b4c
#### ネイティブ Python拡張のエクスポートノード：CSVファイルの出力 
https://qiita.com/kawada2017/items/7a4a00c8a0f77efb6f79
#### ネイティブpythonの拡張ノードでつかうpyhtonパッケージを導入する 
https://qiita.com/kawada2017/items/9252f93cf59948dd2810