実践型AIプログラミング特講 ライブラリ紹介編 #10

実践型AIプログラミング特講 ライブラリ紹介編 #10

前回同様に機械学習に必要なライブラリを厳選してお伝えしていこうと思います。

特に初学者の方々には馴染みのないものも多いとは思いますが今回紹介したライブラリについて実際に触れてみても構いませんし、日本語の文献も多々ネット上に公開されているのでそちらを併用しつつ自身の機械学習アルゴリズムに組み込んでみましょう。

近年の機械学習関連の開発では、多くの場合Pythonが用いられます。 本記事は、「機械学習をこれから初めてみたいけど何から始めればいいか分からない」「基本のキから学びたい」という方に向けて執筆しました。プログラミング言語「Python」の中でも、特に機械学習における使用頻度の高いライブラリを厳選し、その解説を目的としています。

「この記事の内容に沿ってPythonを学習すれば、機械学習エンジニアとして入門に必要な知識を備えられる」というレベルを目標に、機械学習モデリングを本格的に行う一歩手前まで、スムーズに学べるようかいつまんで進めます。

 

本記事では、Pythonの環境が既に整っている(コンソールにてpython hoge.pyでスクリプトを動かせる)状態を前提としています。PythonのインストールはPython.jpの環境構築ガイドがそれぞれOSごとにサポートしてくれていますので、そちらを参考にインストールを行った上で、本記事を読み進めていただければ幸いです。

 

テーブルデータに対する機械学習

scikit-learn

scikit-learn: machine learning in Python — scikit-learn 0.16.1 documentation

scikit-learn(以下、sklearn)とは、多くの機械学習アルゴリズムを含む巨大なライブラリです。Pythonにおいて、最も一般的に知られている機械学習ライブラリでしょう。

機械学習業務においても登場機会は多く、一般的な機械学習モデルの多くがsklearnに実装されていることから、プロジェクトの最初から最後まで幅広く利用されるライブラリです。本記事では、簡単な機械学習モデルの実行を試します。

まず、機械学習に用いるためにデータセットを用意する必要があります。sklearnには、小規模ですがサンプルとなるデータセットが同梱されています。サンプルの1つであるdigitsと呼ばれる手書き数字画像のデータセットを呼び出すスクリプト(sample5_1.py)を以下に示します。

from sklearn import datasets

import matplotlib.pyplot as plt

 

digits = datasets.load_digits()

print(digits.keys())

print(digits.target[10])

plt.imshow(digits.images[10], cmap=plt.cm.gray_r, interpolation=’nearest’)

plt.savefig(‘./output_digit.jpg’)

データセットをロードし、データセット内のキーを表示しています。また、10番目のラベル情報(target)と対応する画像を出力しています。

コンソールでpython sample5_1.pyと入力し実行すると、以下のような結果が出力されます。

dict_keys([‘data’, ‘target’, ‘target_names’, ‘images’, ‘DESCR’])

0

データセットは手書き数字画像の数値情報(data)やラベル(target)を持っています。 targetの10番目を見ると、どうやら10番目には手書き数字0の画像情報が入っていることが分かります。先ほどのスクリプトで出力した、10番目の画像と照らし合わせて見てみます。

データセットの中は、それぞれリストになっており、対応する順番で並べられています。このようなセットから、機械学習を行うのはそれほど難しくはありません。

以下にdigitデータセットをSupport Vector Machine(以下、SVM)という機械学習モデルで学習するスクリプト(sample5_2.py)を示します。

from sklearn import datasets

from sklearn import svm

import matplotlib.pyplot as plt

 

digits = datasets.load_digits()

 

model = svm.SVC(gamma=0.001, C=100.)

model.fit(digits.data[3:], digits.target[3:])

print(model.predict(digits.data[:3]))

print(digits.target[:3])

 

plt.imshow(digits.images[2], cmap=plt.cm.gray_r, interpolation=’nearest’)

plt.savefig(‘./output_digit2.jpg’)

svm.SVCではSVMクラスを初期化しています。gammaとCという引数を使っていますが、こちらはハイパーパラメータと呼ばれる値です。このハイパーパラメータのコントロールは、機械学習エンジニアのアルゴリズムに対する知識であったり、経験的な調整によって、より精度が高くなるよう設定されます。

今回は、gamma=0.001、C=100というパラメータを利用していますが、学習データやモデルによってパラメータはさまざまです。

model.fitにてSVMを学習させています。ここではdigits.data[3:]のように記述されていますが、これは3番目以降のデータを表しています。

このような表記方法をスライスと言います。一般的な機械学習では、「学習に使用したデータ」を「評価用データ」と混ぜて扱うことはタブーとされています。そのため、今回3番目より後ろのデータで学習しています。その後predictで評価用データとしている3番目以前のデータを評価しています。加えて2番目以前のラベル、及び2番目の画像についてもアウトプットしています。

コンソールでpython sample5_2.pyと入力し実行します。コンソールへの出力の結果は以下のようになります。

[0 1 2]

[0 1 2]

digitの0番目、1番目、2番目の画像は、[0,1,2]と並んでいるようです。SVMの予測値もそれらを全て正しく予測しています。

また、試しにラベル2であり予測値も2となった2番目の画像を見てみます。

どうやら正解のようです。

上記は、digitがかなり簡単なデータで、かつ適切なハイパーパラメータを設定したため短い時間で正しい分類に成功しています。(こちらのパラメータはsklearnの公式チュートリアルより引用しています)

機械学習の難しさや奥深さを知りたい場合は、試しにgammaとCの値を自由に触ってみてください。digit程の小さなデータセットでも、正答できるモデルを作るためのハイパーパラメータはそう多くはありません。

余談ですが、gridsearch等、機械的に最良のハイパーパラメータを探索する方法もsklearnから利用する事が可能です。

sklearnには、このような機械学習アルゴリズムや学習用のメソッド、データ整形処理の手法が多く実装されています。sklearnの公式チュートリアルを進めることで、機械学習業務においても相当な範囲をカバーできる知識と技術が身に付きますので、ぜひ挑戦してみることをお薦めします。

また、今回はSVMを利用していますが、機械学習アルゴリズムの選択に迷った時は、公式のフローチャートが非常に参考になります。

画像はscikit-learn.orgより。

全てのアルゴリズムを覚えるまでは時間がかかりますが、与えられるデータに対して、最良のモデルや整形処理、ハイパーパラメータを適切に選択できることは、機械学習業務において非常に重要です。少しずつ少しずつ身体に慣らしておきましょう。

テキストデータに対する機械学習

mecab-python

GitHub – ellie-icekler/MeCab-python: Example usage of the python wrappers for MeCab Japanese parser in MacOSX.

mecab-pythonとは、日本語向け形態素解析ライブラリMeCabのPython wrapperです。

英語の場合、単語と単語の間はスペースが挿入されており、単語を機械的に切り分けることは難しくありません。しかし、単語間にスペースが存在しない日本語において、単語ごとに文章を切り分ける作業は容易ではありません。この単語の切り分け作業を「わかち書き」、文章の構造解析の手法を「形態素解析」と呼びます。

わかち書きによって得られた単語を機械学習モデルにかけるというのは、テキストデータにおいてはメジャーな手法で、MeCabは古くから形態素解析ライブラリとして機械学習分野に大きく貢献しています。

wrapperであるmecab-pythonをインストールする前に、本体であるMeCabをインストールする必要があります。MeCabのインストールは、利用するOSによって変わってきますので、それぞれ以下に記載します。

仮にMacOSを利用している場合、brewと呼ばれるパッケージ管理ソフトウェアの導入が必要です。brewのインストールは以下brew公式ページにおける、インストールコマンドを実際に入力してください。

The missing package manager for macOS — The missing package manager for macOS

# Mac

brew install mecab

brew install mecab-ipadic

pip install mecab-python3

 

# Linux

sudo apt-get install libmecab-dev

sudo apt-get install mecab mecab-ipadic-utf8

pip install mecab-python3

 

# Windows

pip install mecab-python-windows

実際に日本語のテキストを単語単位にわかち書きするスクリプト(sample6.py)を以下に示します。

import MeCab

 

tagger = MeCab.Tagger(“-O wakati”)

text = ‘日本語のテキストを解析して分割します’

tagger.parse(text)

わかち書きを行う設定でMeCabを呼び出し、parseによって指定したテキストを分割しています。

コンソールでpython sample6.pyと入力し実行します。コンソールへの出力の結果は以下のようになります。

日本語 の テキスト を 解析 し て 分割 し ます \n

これら分割した単語は、前述したskleanライブラリのOneHotEncoderやTF-IDFにかけられ、テキストの分類や解析に用いられます。また、後述するGensimを利用して、分散表現として扱う手法も一般的です。

形態素解析ライブラリでは、その内部の単語辞書も重要です。単語が未知であれば、それらを分割することはできません。辞書においては、新語を多く収録しているipadic-neologd等が広く利用されています。

また、MeCabの他にもCaboChaJUMANといったライブラリが広く知られています。さらに、2018年にはSudachiPyという複数の辞書を比較したりアドオンによって機能拡張が可能なライブラリも登場しています。日本語テキストを機械学習モデルの入力として使いたい場合、さまざまな選択肢があることを頭に入れておくと良いでしょう。

Gensim

gensim: Topic modelling for humans

Gensimとは、テキストデータ等に対して用いられる場合の多いtopic modelingに特化した機械学習ライブラリです。実装されている手法はsklearn程ではありませんが、近年テキストデータにおいて大きな成果を残している分散表現モデル(word2vecやfasttextなど)が利用でき、機械学習業務においても多く利用されます。

他ライブラリと同様に、以下のコマンドを実行しインストールします。

pip install gensim

分散表現のチュートリアルとして、Wikipediaを学習済みのword2vecモデルを読み込んで、実行するスクリプト(sample7.py)を示します。学習済みモデルは、東北大学 乾・岡崎研究室が公開しているモデルを利用します。

以下リンクより、「20170201.tar.bz2」をダウンロード、解凍します。entity_vectorというフォルダが作成されますので、スクリプトと同じ場所に設置してください。

日本語 Wikipedia エンティティベクトル

from gensim.models import KeyedVectors

 

model = KeyedVectors.load_word2vec_format(‘./entity_vector/entity_vector.model.bin’, binary=True)

results = model.most_similar(‘Twitter’)

for result in results:

print(result)

Wikipediaのモデルを利用し、「Twitter」という単語と似た使われ方をしている単語をmost_similarによって出力するスクリプトです。

コンソールでpython sample7.pyと入力し実行します。 結果は以下のようになります。

(‘twitter’, 0.9171890020370483)

(‘ツイッター’, 0.9162642955780029)

(‘[twitter]’, 0.8979461193084717)

(‘[Twitter]’, 0.8913152813911438)

(‘[ツイッター]’, 0.8797802329063416)

(‘ブログ’, 0.8746308088302612)

(‘Facebook’, 0.8576517105102539)

(‘フェイスブック’, 0.8430535793304443)

(‘公式ブログ’, 0.8427780866622925)

(‘[ブログ]’, 0.820915162563324)

これらは、あくまで文章内での単語の位置情報を元に、似ている単語を出力しているにすぎません。most_similarの結果だけで単語の意味を判断することは一般的に行いませんが、それでも「Facebook」や「ブログ」といった、「Twitter」という単語と属性の近い単語が得られていることは分ります。

これらを利用して似た単語の辞書を作成したり、単語や文章を数値に変換したりすることができるのが分散表現モデルです。もちろん、Wikipedia以外の文章を収集し学習させることで、単語空間の拡張や修正を行うことも可能です。

Gensimは分散表現だけでなく、古くから文章の分類や内容推定に使われるモデルを含んでいます。テキストを処理する際は、一度Gensimの中の機械学習モデルに目を通しておくと良いでしょう。

画像データに対する機械学習

Pillow, scikit-image, OpenCV-Python

Pillow — Pillow (PIL Fork) 5.3.0 documentation

scikit-image: Image processing in Python — scikit-image

Welcome to OpenCV-Python Tutorials’s documentation! — OpenCV-Python Tutorials 1 documentation

Pillow、scikit-image(以下、skimage)、OpenCV-Pythonは、Pythonで画像処理を行うためのライブラリです。それぞれpipを利用してインストールすることができます。

pip install pillow

pip install scikit-image

pip install opencv-python

画像処理という同一の目的であれば、どれか1つについて記載すれば事足りるのですが、機械学習の世界でもメジャーなライブラリとして1つを選ぶのが難しく、その上それぞれに違いがあるため記載しています。

データをndarrayで保持するかオリジナルのクラスで保持するか、RGBの配列の順番等が違っており、それぞれの変換も多く発生します。あるライブラリで保持していた画像を他の形式に変換する際、RGBの順番が変化して画像認識システム全体の精度が悪かった等という事案も少なくありません。

「画像の取り扱いだけであればPillowで管理しておくに越したことはない」と筆者は考えていますが、OpenCV-Pythonには高級な画像処理アルゴリズムや一部Deep Learningを利用した機械学習モデルも実装されており、シームレスに高度な処理に接続できます。

skimageもまた、OpenCV-Python程ではありませんが高級な画像処理アルゴリズムを備えており、「毎回自前で実装してしまう」ようなアルゴリズムはskimageの中に大抵の場合存在します。

ここでは、それぞれ複雑なスクリプトを示しませんが、それぞれ画像を保持する形式が違う事を確認するスクリプト(sample8.py)を以下に示します。

import cv2

from PIL import Image

from skimage import data

 

cv2_img = cv2.imread(‘./output_digit.jpg’, cv2.IMREAD_GRAYSCALE)

pil_img = Image.open(‘./output_digit.jpg’)

sk_img = data.imread(‘./output_digit.jpg’)

 

print(type(cv2_img))

print(type(pil_img))

print(type(sk_img))

 

print(cv2_img.shape)

print(sk_img.shape)

それぞれのパッケージでsklearnの項で作成した画像を読み込み、そのtypeと大きさを表示しています。

コンソールでpython sample8.pyと入力し実行します。結果は以下のようになります。

<class ‘numpy.ndarray’>

<class ‘PIL.JpegImagePlugin.JpegImageFile’>

<class ‘numpy.ndarray’>

(246, 246)

(246, 246, 3)

1つ目のOpenCV-Pythonと3つ目のskimageは、それぞれndarrayで画像を保持していることが分ります。対してPillowはオリジナルのクラスです。また、ndarrayで保持される2つの画像のshapeを見てみるとOpenCV-Pythonは1つ軸が少なくなっていることが分かります。

これは、読み込み時にcv2.IMREAD_GRAYSCALEを指定しているため、グレースケール画像として読み込んでいるのが理由です。skimageでグレースケール画像に変換するには、rgb2grayというメソッドを利用することで実現できますが、OpenCV-Pythonは読み込み時に変換の有無を指定できます。

このように、それぞれのライブラリで機能が異なるため、処理プロセスの後段にあたる機械学習ライブラリが推奨する画像処理ライブラリを選択する必要があります。また、画像における機械学習は、統一複合された機械学習ライブラリというものが少なく、目的や用途によって機械学習ライブラリも選択する必要があります。

画像分類や画像内からの物体検出、画像検索など、自身が行いたい目的からトップダウン方式で使用すべきライブラリは決定されると理解しておくと良いと思います。

 

いかがでしたでしょうか、二回に渡って機械学習に必要なライブラリ及びパッケージについて紹介していきました。ここで豆知識ですがライブラリとパッケージ、そしてメソッドの違いについて理解されている方が意外と少なかったので皆様にお伝えするとメソッドが一つの便利道具だとすると、複数の役立つ便利道具がまとまって収納された道具箱がパッケージ、複数のパッケージが一つに纏まったのがライブラリになります。

特に言葉の定義に捉われる必要はありませんが、情報交換において一つの単語でものが伝えられたら非常に効率的ですよね?ですから、社会人の方々はある事柄を一般化し一つの単語にする傾向が強く、そうすることでコミュニケーションの円滑化と時間的効率を図っているのです。

プログラミングカテゴリの最新記事