Orange3を使ってGUIで機械学習に入門する

### はじめに
ひょんなことから、"Orange3"というGUIベースの機械学習用ソフトウェアの存在を知った。どうやら、Scikit LearnとScipyでできることは大体できる、というソフトウェアらしい。簡単に触ってみたところ、「コーディングはしたことがないけれど、機械学習のプロセスを学びたい」という人にはちょうど良さそうだった。せっかくなので、Orange3上での操作と、それに該当するPythonのコードを併記することにした。これを一緒にみれば、機械学習のプロセスとコーディングを同時に学べるのでは？という目論みである。

### この記事で対象とする人
・コーディングしたことはないけれど、機械学習の勉強をしたい人
・↑のような初心者用の教材を探している人
・管理職やマネージャーなんかで、現場からは距離があるし今さらコーディングを勉強するのは無駄では？しかし部下の評価をしなければ、、、という人

### 使用するソフトウェアとパッケージ
Orange3は、以下からダウンロードできる。インストールは、ダウンロードしたものをダブルクリックすることにより行う。この記事の執筆時点では、最新は3.32.0になっている。

https://orangedatamining.com

Pythonのコードの方では、以下のパッケージを使用している
・Pandas
・Scikit Learn
・matplotlib
今回使ったくらいのコードなら、おそらくどのバージョンでも（よほど古くない限り）エラーは出ないと思う。

### 使用するデータ
この記事では、下記の記事で作成したデータを使っている。もちろん、手持ちのデータで試してもらっても問題はない。

https://qiita.com/ojiya/items/9f8f5d7ab439518c41ba

### 実際の操作とコード
まずはOrange3を起動し、最初に出てくる画面を閉じる。すると、アイコンの並んだ列と、何も書かれていない白い部分が出てくると思う。この白い部分に、機械学習（というか、データ解析）のフローを作っていくことになる。
まずは、ここに「データを読み込む」という命令をおいてみる。↓の動画には、該当のアイコン（CSV File Import）が隠れている可能性も考えて、隠れていた場合に必要なアイコンを探す操作も入れてみた。
![drag_drop.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1726485/9bced961-1161-f7f8-c7e6-e8902a30c8c1.gif)

↑の動画を見てもらえばわかる通り、「Data」や「Transform」など、操作がいくつかのカテゴリに分かれている。データ読み込みは、この中で「Data」のカテゴリに入っている。アイコンを見つけたら、動画のように、画面右の白い部分にドラッグ&ドロップで配置する。場所はどこでもいい。
続いて、配置したアイコンをダブルクリックすることにより、ファイルを選択することができる。OSによって画面は違うと思うが、MacOSでは、下記の通り。データを入れてあるcsvファイルを選ぶ。
![1_load_data.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1726485/bcf027f8-4111-1844-444e-c2eecca26781.png)
次に出てくる画面は、閉じてしまって問題ない。
ここで注意点だが、このOrange3の特徴として、「操作を実行する」に相当する作業がない。つまり、アイコンを配置し、条件を設定した時点で、そのフローは実行されている。「OK」や「実行」に相当するボタンがないので最初は面食らうが、慣れると楽（かもしれない）。

この操作は、以下のコードに相当する。
```
import pandas as pd
#ここではprop_desc.csvというファイル名のファイルを読み込む
df0 = pd.read_csv('prop_desc.csv')
```

続いて、読み込んだデータを、目的変数（解析対象の物理量）と、説明変数（目的変数を計算するための物理量、特性値）に分けたい。そこで、「Transform」のカテゴリから、「Select Columns」をドラッグ&ドロップで配置する。続いて、最初の「CSV File Import」と、この「Select Columns」をつなぐ操作を行う。これは以下の動画の通り。言葉で説明するとややこしいが、個別の操作のアウトプットを得たい場合は、アイコンの右側の円弧、別の操作からインプットを得たい場合は左側の円弧から線を引っ張ってくる（ドラッグ&ドロップしている）。

![connect_icons.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1726485/bca4afd5-bbf6-b1a8-1ee6-9d5dc117c37c.gif)

続いて、Select Columnsのアイコンをダブルクリックし、データの選択画面に移行する。続いて、下記の動画の要領で、目的変数を「Target」の欄に移動する。どうやら、デフォルトでは全ての列（columns）が、説明変数（Features）に入っているらしいので、一回そこから取り出す操作が必要になっている。

![select_columns.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1726485/385a68fe-2999-9ba7-59d7-f0c057a40a01.gif)

この操作は、次のコードに該当する。
```
#ここでは、'log_ed'という列に目的変数（解析対象の物理量）が入っている。
obj = df0['log_ed']
desc = df0.drop('log_ed', axis=1)
```

次の操作では、データを訓練用データとテストデータに分割する。ここでは、「Transform」カテゴリ内の「Data Sampler」を使う。「Data Sampler」を設置し、「Select Columns」と接続したら、「Data Sampler」をダブルクリックして、データの分割条件を決める。ここでは、70%を訓練データに回すことにした。

![sampling_cond_set.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1726485/f15f6045-7d41-0c98-8a1f-6c57bf0d523c.png)

該当コードは以下の通り。
```
from sklearn.model_selection import train_test_split
desc_train, desc_test, obj_train, obj_test = train_test_split(desc, obj, test_size=0.3)
```

次は機械学習モデルを作成する。「Model」カテゴリ内の「Linear Regression」を配置し、「Data Sampler」と繋いだら、「Linear Transform」をダブルクリックして、条件を設定する。ここでは、Ridge回帰を用いることにした。

![select_algorhythm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1726485/5802214b-9e63-8877-41f4-b10e92e34fb8.png)

このコードは以下の通り。
```
from sklearn.linear_model import Ridge
rdg = Ridge()
rdg.fit(desc_train, obj_train)
```

そしたら、「Evaluate」カテゴリの「Predictions」を配置し、「Data Sampler」および「Linear regression」と接続する。

![prediction.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1726485/a378f62d-6136-bfe6-45d1-a9ecc129585b.png)

ここで微妙に気をつけたいのが、「Data Sampler」とつなぐと、デフォルトでは訓練用データが入力されるようになっているらしい。そこで、以下の操作により、テストデータを入力するようにする。繋がっている線をダブルクリックしてデータ選択画面を開き、その後、出力データを選んでいる。データの出力を選ぶのが最終的に「Remaining Data」を「Predictions」につなげられればいいのだが、微妙にわかりにくいポイントとして、・すでに繋がっている線はクリックで消える ・新しく繋げたい時は、ドラッグ&ドロップする がある。

![data_select.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1726485/13ac3e32-ef4b-e7d6-dc83-a133b67bcdf0.gif)

ここは、コードで書けば一行。
```
pred = rdg.predict(desc_test)
```

最後に、解析したデータを可視化しよう。「Visualize」カテゴリから「Scatter Plot」を選択し、例によって「Predictions」と接続する。

![total_flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1726485/07fac813-d16b-dfd8-745a-03a05b2e08c1.png)

この後、「Scatter Plot」をダブルクリックしても何も表示されないが、以下の二枚の画像の要領でデータを選択することにより、散布図が得られる。つまり、「Axis x」では実測データ（元の列名になっており、ここでは「log_ed」）、「Axis y」では予想データ（Linear Regression）を選ぶ。

![x_select.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1726485/4db2ddf3-4200-681e-b2ce-32f21c8c47b8.png)

![y_select.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1726485/9f48e6fd-ebdb-2519-2236-4ff637ed94a1.png)

これもコードを載せておく。
```
import matplotlib.pyplot as plt
plt.scatter(obj_test, pred)
```

以上で、簡単な回帰のプロセスをGUIで実行することができた。フローが可視化されおり、直感的に「何をしているのか」がわかるのは、初心者には大きなメリットだろう。デザインも良いので、コーディングに慣れていても、作業プロセスを人に説明する時には便利だ。

本記事はここまで。