コパンダさん、かなり雑なアヤメ分類アプリケーションを作成したよ。実用性はないよ。
tkinterでGUIつけたんだね。実際に何かのアプリケーションとしてscikit-learnを組み込む練習になるね。
アヤメのデータ分類をしてきましたが、実際にこの処理を何かしらのアプリケーションにしたいなと思い、PythonのtkinterというGUIライブラリで雑なアプリケーションを作りました。
アヤメのデータの分類の機械学習プログラミングについては、こちらの記事を参考にしてください。
こんな人の役に立つかも
・tkinterを使ってpythonのGUIを作成したい。
・GUIプログラミングの基礎知識を学びたい人
・機械学習プログラミングにGUIはつけられないの?と思う人
GUIって何?という方はこちらの記事をどうぞ(CUIとGUIの違いについて解説しています。)
アプリの概要
テキストボックスに、アヤメのデータ(「sepal length」「sepal width」「petal length」「petal width」)の順番に入力します。
実行ボタンをおすと、k最近傍法で入力したアヤメのデータを分類して下のラベルに分類結果を出力します。出力結果がアヤメの種類となります。[0]が「setosa」、[1]が「verginica」、[2]が「versicolor」となります。
※今回は、GUIを作成するため、Anaconda環境のSpyderという開発環境でプログラミングを行います。Anaconda環境のインストールは、こちらも参考にしてください。
下の図の「①プログラム記載」の部分に記載するプログラムを下に紹介していきます。基本的に、「①プログラミング」「②実行」「③動作確認」で開発を行います。開発アプリは、spyder以外のウィンドウとして立ち上がります。開発アプリの終了は、ウィンドウの「×」ボタンでOKです。
プログラミングしてみよう
GUIプログラミングをするためには、シンプルに上から下に実行するようなプログラミングの流れではない概念が必要になります。それは、ユーザーの入力といういつ発生するかわからない「イベント」というものをきっかけに動作を開始するプログラムがある、という点です。この点を見ながらtkinterでGUIを作成していきます。
import部
まずは、importします。前回のk最近傍法のimportに、「tkinter」というPythonでウィンドウやボタンを使ったアプリを作成できるライブラリを追加しました。
#==impotr部===
#PythonのGUIライブラリtkinter
import tkinter as tk
#scikit-learnライブラリ関連
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import numpy as np
k最近傍法部
importが終わったら、scikit-learnライブラリのアヤメデータを読み込み、k最近傍法という機械学習アルゴリズムにデータを訓練させます。k最近傍法の記事についてはこちらを参考にしてください。
#==k最近傍法部==
#アヤメデータを読み込み
panda_box = load_iris()
X = panda_box.data
y = panda_box.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.5, stratify=y)
#k-最近傍法のオブジェクトの宣言
knc = KNeighborsClassifier(n_neighbors = 1)
#モデルの学習
knc.fit(X_train, y_train)
イベントハンドラ部
ボタンが押された時の機能をここで作成しています。ボタンがクリックされる動作などユーザーの操作を一般的に「イベント」といい、今回は、「実行ボタン」がクリックされたという「イベント」をきっかけに呼び出される機能のプログラムを作成します。一般的に「イベント」がきっかけで実行されるプログラムを「イベントハンドラ」と呼びます。
#==イベントハンドラ部==
#ボタンを押したときに呼び出されるプログラム
def function(num1,num2,num3,num4):
test_data = np.array([[num1,num2,num3,num4]])
test_data = test_data.astype(np.float64)
label1["text"] = knc.predict(test_data)
イベントハンドラの名前は「function」としました。このプログラムは4個のデータを外部から受け渡されます。それがnum1~4です。
・test_data = np.array([[num1,num2,num3,num4]])
num1~4は、numpyのarrayという形にして、test_dataという変数に入れます。num1~4は、テキストボックスのinput1~4に入力した数値なので、テキストデータとしてここに入っていますので、小数点の形に変更します。それが、astype(np.float64)です。
・test_data = test_data.astype(np.float64)
test_data変数自身が持つデータの形(型)をastype機能をつかって小数点に変更して、test_data自身に上書きしています。
・label1[“text”] = knc.predict(test_data)
最後に、label1という実行ボタンの下のテキストの内容をk最近傍法で分類した答えに書き換えます。labelは後から出てきます。このようにすることで、Labelの値を後から書き換えることができるという点を覚えると良いです。
GUI初期化部
GUI(ウィンドウやボタンやテキストボックスなど)を配置する部分です。プログラムの起動時に一回だけ上から下に実行されるので、初期化部とつけています。
今回は、tkinterというPythonでGUIを作成するライブラリを利用しています。
#==GUI初期化部==
#GUIを初期化
#ウィンドウの作成
gui = tk.Tk()
gui.title("iris_classification")
gui.geometry("400x300")
#GUIの上にテキストボックスとボタンを配置
input1 = tk.Entry()
input1.insert(tk.END,"5.5")
input1.pack()
input2 = tk.Entry()
input2.insert(tk.END,"2.5")
input2.pack()
input3 = tk.Entry()
input3.insert(tk.END,"4.0")
input3.pack()
input4 = tk.Entry()
input4.insert(tk.END,"1.3")
input4.pack()
execute_button = tk.Button(gui, text='実行', width=50, command=lambda: function(input1.get(),input2.get(),input3.get(),input4.get()))
execute_button.pack()
label1 = tk.Label(text="結果")
label1.pack()
「#ウィンドウの作成」では、guiという変数にtkinterを使うよ、という設定をしています。importのときtkinterをtkと短縮の命名をしたので、tkがtkinterを表しています。
ウィンドウの作成
gui = tk.Tk()とすることで、ウィンドウが生成されて、guiという変数に入ります。gui.titleは、ウィンドウのタイトルを変更します。また、gui.geometryは、ウインドウサイズを指定します。
input1~4という変数には、テキストボックスを入れています。
アヤメデータ入力テキストボックスの作成
input1 = tk.Entry()とすることで、input1にテキストボックスが入ります。
作成したテキストボックスが入った変数input1は、input1.pack()とすることで、先に作成したウィンドウ「gui」に、「input1」のテキストボックスが配置されます。
本当は、詳細にguiのどこの位置にのせる、などを指定できますが、今回はシンプルに何も設定を行わずに入れていますので、ウィンドウの中央に配置されます。
順番も、input1~4が上から下にそのまま配置されていきます。
実行ボタンの配置
excute_buttonという変数に、tk.button()というtkinterのボタン作成機能でボタンを入れています。ボタンは、先ほど作成した「イベントハンドラ」を呼び出すように、紐づけます。プログラムのように、「command=lambda:」と設定することで、イベントハンドラに数字を渡すことができます。今回渡す数字は4個です。渡すデータは、input1~4に入力されたデータです。input1.get()のように書くことで、入力されているデータを取り出すことができます。
Labelの配置
Labelは入力もできないただの文字の表示です。最初に「結果」という文字を設定しておきました。
ユーザーが入力は出来ませんが、プログラムで後から内容を変更することができますので、結果表示として利用しました。
メインループ部
tkinterでは、メインループを実行しなければいけません。メインループは、ボタンが押されたや、テキストが入力されるといったユーザーの入力をひたすら待ち続ける処理です。
#==メインループ部==
gui.mainloop()
GUIプログラミングでは、「イベント」「イベントハンドラ」「メインループ」という概念が基本になってきます。
このプログラムの改善点
テキストボックスに小数点以外のものを入れることができます。
毎回、機械学習アルゴリズムに訓練をさせているので、訓練データをあらかじめ外部に保存しておいて読み込むなどの工夫が必要になります。
tkinterも少し使えるようになった。でも、そもそもアヤメのデータがない・・・
アヤメの写真を検索して、その画像を入力、自動的に4つの花びらのデータを拾えるような機械学習アルゴリズムを入力にするともっと面白いアプリになりそう。