2021年6月11日金曜日

ちょっと惹かれるPython1行コード(その1)

【what is this】誰でも、短くて美しいコードに憧れます。参考文献[1]には、Pythonによる1行コード(Python One-Liners)の考え方と実例がたくさん載っています。それを参考に1行コードを2つほど書いてみました。

例題:キノコの毒性に関するデータの学習と学習結果による予測
 機械学習の分類問題として、キノコを有毒か無毒かに分類することをやってみます。図1には、キノコの色(赤、青、黄)、笠の形(丸、角)、柄の長さ(長、短)、場所(地面、樹木)の特性によって、それが有毒か無毒かのデータ(参考文献[2]から引用)があります。これを機械学習によって学習させ、さらに、その学習データが正しく分類(予測)されたかどうかを確認します。

(注)上記データは現実のキノコにそのまま当てはまるものではなく、あくまで機械学習を学ぶために用意された仮想データです。従って、実際のキノコの毒性判定には利用しないでください。

SVMとRandomForestの一行コード(学習と予測)
 2つの手法(SVM-サポートベクタマシンとRandomForest)によるPython1行コードとその予測結果を示します。図2は、SVMの場合です。Python numpy配列のスライシング(特性データと正解レベルを分離するため)を行い、学習(.fit)結果を予測(.predict)へ接続しています。確かに、素早く簡潔なコーディングとなりました。学習に用いたデータに対する予測結果は、正解率89%でした。9件のうち1件のみが誤まった判定となりましたが、こんな少ないデータでも良く予測できることが確認できました。


 次は、RandamForestによる場合です。こちらの結果は正解率100%でした。素晴らしい!やり方は、SVMの場合と同様です。


 なお、図1での特性データは数値で与えたが、日本語で与えたい場合は以下のようにして、別途用意した辞書型変数Dを使い、map(lambda式を使う)処理を施せばよい。以下の実行結果は、図3での実行結果と同じになります。


 上図の変数Yの計算は、以下のどちらでも良いでしょうが、2番目の方がちょっとだけ分かりやすいかもしれません。
 Y = np.array(list(map(lambda i : list(map(lambda j : D[j], i)), X)))
 Y = np.array(list(map(lambda i : [D[j] for j in i], X)))

何のために1行コードを書くのか
 さて、参考文献[1]の最後に、以下のような叙述がありました。納得ですね。
Don't cram everything into a single line of code just to show off your one-liner superpower. Instead, why not use it to make existing codebases more readable by unraveling their most complex one-liners?
(単に何でもかんでも1行に詰め込むのではなく、複雑なコードを読みやすくするために!)

[参考文献]
[1] Christian Mayer, "Python One-Liners", No Starch  Press, 2020.
[2] 黒橋禎夫, "改訂版 自然言語処理", 放送大学教育振興会, 2020.

0 件のコメント:

コメントを投稿