ipywidgetでデータサイエンスの効率化をしたい(KMeans)

分析をしていると、少しだけ変数を変えたいが、同じ処理をいくつか試したい、ということがあります。
短期間であれば、ループを回し変数を変える、でいけるのですが、
やや時間があきながらやる場合、めんどくさいな、と思います。

逆にGUIツールを使うと、(お金がかかったり)、加工処理で無理する必要もでてきます。

そこで、ipywidget + jupyterで自分用にコードとGUIの中間のようなツールをつくるようになりました。

今回はKmeansのGUI化です。

使うパッケージ

import ipywidgets as wi
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
import pandas as pd
ir = load_iris()

インプットをつくる

kmeansは教師なしなので、説明変数を選択できるチェックボックスを用意します。
また、クラスターの数のインプットをつくります。 ▼Kmeansを試した時の記事はこちら [esu-ko.hatenablog.com]

checks = []
for n in ir['feature_names']:
  checks.append(wi.Checkbox(description=n))

cls_num = wi.IntText(
    value=3,
    description='n:',
    disabled=False
)

配置

上記のインプットを並べます。

left_box = wi.VBox([cls_num])
right_box = wi.VBox(checks)
wi.HBox([left_box, right_box])

Kmeansの実行ボタン

ひとまずべたがきで、on_clickとボタンを実装します。

def on_click(submit):
    feature_names = [cb.value for cb in checks ]
    cls_ = cls_num.value 
    km = KMeans(n_clusters=cls_)
    df = pd.DataFrame(ir.data)
    res = km.fit(df.loc[:,feature_names])


button = wi.Button(description='実行')
button.on_click(gui.on_click)
display(button)

ここまでをjupyter上で順に実行し、対象の変数を選んでボタンを押せば実行されます。

クラスにまとめる

実行結果などをとり扱いしやすくするため、
また再利用しやすくするためにクラスにまとめます。
ついでに実行しやすくなるようにボタンも同じところに表示するようにしました。

class KmeansGui:
  def __init__(self):
    self.res = None
    self.data = load_iris()
    self.checks = [wi.Checkbox(description=n) for n in self.data['feature_names']]

    self.cls_num = wi.IntText(
      value=3,
      description='n cluster:',
      disabled=False
    )

    self.button = wi.Button(description='実行')
    self.button.on_click(self.on_click)

    self.left_box = wi.VBox([self.cls_num])
    self.center_box = wi.VBox(self.checks)
    self.right_box = wi.VBox([self.button])


  def panel(self):
    display(wi.HBox([self.left_box, self.center_box,self.right_box]) )


  def on_click(self,e):
    feature_names = [cb.value for cb in self.checks ]
    cls_ = self.cls_num.value 
    km = KMeans(n_clusters=cls_)
    df = pd.DataFrame(self.data.data)
    self.res = km.fit(df.loc[:,feature_names])

gui = KmeansGui()
gui.panel()

実行後、gui.resで中身が取れるので、
pivottablejsなんかで簡単に傾向がみれます。
▼pivot_tablesjsの使い方はこちら esu-ko.hatenablog.com