作成したデータベースのデータを機械学習にかける

モデル構築

f:id:hanamichi_sukusuku:20210223160238p:plain

実行結果

MLPモデルのファイルが保存される。

 

hanamichi-sukusuku.hatenablog.com

扱うデータは上記で作成。

in_sizeで入力数を定義。ラベルデータとして体型の値を使用するので出力数に6を定義。

 

モデルの重みファイルの保存

f:id:hanamichi_sukusuku:20210223161016p:plain

実行結果

学習済みの重みファイルが作成される。

 

データベースから新しい100件のデータを取得し、学習データを作成する

f:id:hanamichi_sukusuku:20210223161752p:plain

 

with sqlite3.connect()でデータベースに接続、cursorオブジェクト生成。

for文で実行しているSQL文は

SELECT * FROM person ORDER BY id DESC LIMIT 100

・SELECT(データベースからデータ取得)

・* FROM person(personテーブルから全て取得、*を使うことで「全て」という意味になる)

・ORDER BY(データをソートして取得したい時に使用)

・id DESC(idを降順にソートしてレコード取得) LIMIT 100(100件取得)

ブロック変数rowにはid,height, weight, typeNoが格納されているのでそれぞれ変数に代入。

height、weightの正規化に関しては大体身長では2m、体重では150kgを最大値として考えてこの値を使用していると思う。

x、yにそれぞれ追加。

 

モデル読み込み、既に重みデータがあればそれも読み込む

model = load_model('hw_model.h5')

# 既に学習データがあれば読み込む --- (*5)
if os.path.exists('hw_weights.h5'):
   model.load_weights('hw_weights.h5')

 

既に重みデータが存在すれば、データベースに新しいデータが追加された時、保存しておいた前の重みデータをさらに追加したデータによって学習させることができる。実際のプログラムで使用するには毎回一から学習させていては時間がかかってしまう。既に学習済みのデータがある場合にmodel.fitをすると前回の学習結果に加えて新しいデータで学習できるので、新たなデータに対応するようにパラメーター修正するような仕組みになっている。

 

ラベルデータをone-hotベクトルに変換

nb_classes = 6 # 体型を6段階に分ける
y = to_categorical(y, nb_classes) # one-hotベクトルに直す

 

学習、重みファイル保存

model.fit(np.array(x), y,
  batch_size=50,
  epochs=100)

# 結果を保存する --- (*7)
model.save_weights('hw_weights.h5')

 

精度を確認していく

f:id:hanamichi_sukusuku:20210223165351p:plain

実行結果

f:id:hanamichi_sukusuku:20210223165409p:plain

身長160cm、体重50kgは「標準体重(普通体重)」であるのが正しいが、低体重(痩せ型)と間違った値を出力している。これは学習したデータが100件と少なすぎたため。

これを改善するために体重データをデータベースに挿入するプログラムとデータを学習するプログラムを交互に繰り返し実行していく。そして、5000件ほどのデータを学習させてみる。面倒なら挿入する値を一気に5000件、学習する値も5000件にして実行すると良い。

実行結果

f:id:hanamichi_sukusuku:20210223170538p:plain

正解率を向上させることができた。

 

まとめ

・データベースから定期的にデータを読み出して機械学習の分類器に学習させることができる。

・学習するデータは、CSV形式でも、RDBMSのデータベースから取り出したものでも、正しいデータであれば十分使える。

・定期的にデータが追加される学習器であれば、日々データが増えることで判定精度も向上していく。