機械学習

データサイエンスを体験しよう!scikit-learnを使って機械学習に挑戦

データサイエンスとは?                      

データサイエンスとはデータ収集や、データから利用価値の高い情報を抽出する原理と方法をまとめた用語です。

データサイエンスを利用することで、慣習や勘では解決できなかった問題解決の方法を、自動的に発見することができます。

次に情報の抽出原理と方法について紹介します。

情報の抽出は、傾向からデータパターンやモデルを作成することが最終的な目標です。情報の抽出ですが、これまでは統計学やスコアリングなどの手法が一般的でした。

近年では、コンピュータの性能が飛躍的に向上していることから、ディープラーニングや機械学習が注目されています。(むしろ最近のデータ分析方法はこちらの方が中心です)。

特にディープラーニングは人の脳細胞(ニューロン)を模したプロクラムが、自動的に収集したデータを学習することで、人間では発見できなかったデータの傾向を見つけることができる方法です。

しかし、上記で紹介した事例はあくまで方法です。

データを抽出した後は、パターンやモデルの評価と修正が必要です。

例えば、テストデータを使用して分析した結果が、作成したパターンと一致するか評価し、一致しない場合はデータの抽出方法を修正する必要があります。

データサイエンスの身近な応用例とは?

データサイエンスはビジネスのあらゆるところに活用されますが、特にIT系や販売、工場など数値を扱う分野で使用されています。

これはデータサイエンスが過去のデータを元に企業の売上や効率向上となるデータ傾向を抽出するために使用されるからです。具体的な応用例として以下の例があります。

画像認識:不良商品や病状を判定する。

例えばみかん缶詰の生産工場を想像してみましょう。

缶詰は金属型の容器にみかんを入れてパッケージされることで完成しますが、まれにパッケージにミスプリントが発生する事があります。

従来は人間の目で仕分けしていましたが、ディープラーニングを応用すればセンサーで受け取った画像データから、パッケージのミスプリントを判断して不良品を取り除くことができます。

ディープラーニングは、人間側があらかじめ正解のパッケージ画像を数百枚から数千枚読み込ませてコンピュータに学習させることで、正解とは異なるパッケージを自動判断します。

また、病状の判定にも画像認識が使用されています。

医療現場ではレントゲン写真を撮影して患者の病気を判定しますが、判定を下すのは医者(人間)の目です。これと同様の作業をディープラーニングによって行わせたのが、医療診断支援システムとして一躍脚光を浴びた『ワトソン※』です。

ワトソンは患者のレントゲン写真を数万点学習することによって、数万点に2〜3件という奇病を正確に判定しました。

※ワトソンは米国IBMによって開発されたクイズ回答を目的として作成されたシステムですが、医療分野にも応用されています。

 

回帰

回帰処理は過去のデータから傾向を読み取り、数値を予想する方法です。

中でも直線近似は最も簡単な回帰処理なので、具体例を出さずとも皆さんも一度は使ったことがあると思います。

気温とアイスクリームの売上高や勉強時間とテストの点数など、世の中に直線関係は無限に存在します。

しかし、一般的なデータを無作為に抽出しても、直線関係で表せるものは意外と多くありません。むしろ結果に対して複数の要因が影響していることが多く、パラメータ同士の相関関係すらつかむことは困難です。

機械学習を用いると、結果に対するパラメータの寄与率を自動で抽出してくれます。

つまり、結果と複数のパラメータさえ用意すれば、どのパラメータが結果にどれくらい影響しているか自動で機械学習が判断してくれます。これは人間が想像もできなかった相関関係を洗い出したり、結果を改善するための効果的なアプローチを見つけることに役立ちます。

例えば、アイスクリームの売上高を伸ばすために回帰分析を行った結果、販売側は『値段』こそ最も重要なパラメータと考えていたものの、実際は『サイズ』や『カロリー』の方が売り上げに貢献しているパラメータだと判明することがあります。この事実が分かれば、販売側は売上高上昇のために効果的な施策を打つことが出来るでしょう。

機械学習はどのような方法があるの?

データサイエンスにおいては機械学習を用いた分析が多く使用されている事が分かりました。次は機械学習の手法について紹介しますが、それぞれの手法が特徴を持っているため、細かく分けて説明します。

○教師あり/なし学習

①教師あり学習

②教師なし学習

③半教師あり学習

④強化学習

○バッチ学習/オンライン学習

⑤バッチ学習

⑥オンライン学習

①教師あり学習

パラメータと正解のラベルが付いているデータセットを利用して学習する方法で、分類を行うときに使われます。分類はスパムメールや迷惑メールの自動振り分けとして身近に使用されています。メール本文とスパムメールか否か、迷惑メールか否かの情報を与え、メール内容との関係をコンピュータが学習してくれます。

②教師なし学習

教師なし学習は、教師あり学習と違い正解のラベルが無いデータセットを使用して学習する方法で、主にクラスタリングで利用されます。クラスタリングとは複数の特徴量を元にデータを自動分類する方法です。花や動物の種類を判定するのに使用されます。

③半教師あり学習

教師あり学習ではすべてのパラメータに正解ラベルが付いていましたが、実際のデータでは一部しか正解データが無い場合もあり、半教師あり学習と呼ばれています。

この手法はGoogleフォトで使用されています。アップロードした写真の登場人物を登録すると、どの写真にどの人物が移っているか判断し、自動でフォルダに分類してくれます。

④強化学習

学習アルゴリズムが導き出した結果と正解データの差分から報酬データを生成して、報酬データが最大となるように行動を選択させる手法です

ロボットへ歩き方を学習させたり、囲碁ソフトが棋譜から碁の打ち方を学習するのに使用されました。

⑤バッチ学習

バッチ学習オフラインで行われる学習方法の事です。

通常の機械学習では学習データをあらかじめ用意する必要があり、一度作成した学習モデルに新しいデータを加えたい場合は、モデルを破棄する必要があります。

データセットが巨大になった場合は、学習モデルの作成に時間がかかるので、モデルのアップデートは短くても1週間ごとになります。

⑥オンライン学習

オンライン学習は最新情報を常にモデルへ取り込む手法で、株価の予想モデルや金融関係モデルなどで使用されます。

具体的には、バッチ処理で行っていた処理を細かく分割したミニバッチ処理を行い、モデルを段階的に訓練する方法です。

処理システムのメモリ容量を遥かに超過したデータセットに対してもモデル学習ができ、一度使用したデータは廃棄しても良いため、計算コストが安くなるメリットがあります。

逆に、ミニバッチの評価を学習モデルへ反映するため、データの『ノイズ』が大きくなる欠点があります。

 scikit-learnを具体的に体験してみよう!

scikit-learnは機械学習に使用されているプログラミング言語Pythonのライブラリです。

scikit-learnは主に教師あり学習で用いられており、その代表として手書き文字の認識学習が有名です。

ここでは手書きの0-9のデータセットであるMNISTとscikit-learnを利用して、手書きの数字を認識するプログラムを試し、実際にscikit-learnを用いた機械学習を体感しましょう。

なお、本プログラムは下記の参考文献から流用していますので、機械学習についてご興味のある方は本書をご参照ください。

『オライリージャパン、Aurélien Géron 著、下田 倫大 監訳、長尾 高弘 訳『scikit-learn、Keras、TensorFlowによる実践機械学習 第2版』、ISBN

978-4-87311-928-1』

事前準備

プログラムはPythonjupyter notebookを使用します。開発環境を整えるならば、Anadondaをダウンロードすれば必要なソフトウェアを一斉にダウンロードできます。下記サイトを参考に開発環境を構築しましょう。

Anaconda のインストール: Python環境構築ガイド – python.jp

Anaconda | The World’s Most Popular Data Science Platform

モジュールのインポートと画像保存場所の定義

さっそくjupyter notebookを起動し、次のコマンドを記述しましょう。

pythonはモジュール化されたプログラムを呼び出すことで、少ないコードで多種多様のデータ処理を行うことができます。

モジュールの読み込みはimportで行います。scikit-learnもモジュール化されており、import sklearn文でプログラム中に読み込んでいます。

モジュールの読み込みのコード

“`python
# Python3.5を使用する。
import sys
assert sys.version_info >= (3, 5)
IS_COLAB = “google.colab” in sys.modules
IS_KAGGLE = “kaggle_secrets” in sys.modules
# Scikit-Learn ver 0.20を使用する。
import sklearn
assert sklearn.__version__ >= “0.20”

# 数値処理用のモジュールをインポートする。
import numpy as np
import os

# 機械学習の結果を一定にするため、シード値を固定する。
np.random.seed(42)

# グラフプロット用のモジュールをインポートして、初期設定を行う。
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rc(‘axes’, labelsize=14)
mpl.rc(‘xtick’, labelsize=12)
mpl.rc(‘ytick’, labelsize=12)
“`

続いて、データセットであるMNISTのダウンロードを行います。

scikit-learnは頻繁に使用されるデータセットを簡単にダウンロードできるようにコマンドが整備されており、次のコマンドを利用することで、70000万点の数字データが配列としてインストールできます。

同時に、今後のデータ処理を行うためにデータラベルへ名称を付け、データ型を決めます。

MNISTのダウンロードのコード

“`python
from sklearn.datasets import fetch_openml
mnist = fetch_openml(‘mnist_784’, version=1, as_frame=False)
mnist.keys()
“`

機械学習を行う前にダウンロードした数値データを確認してみましょう。

matplotlibモジュールを使用することで、画像データを簡単に扱うことができます。

確認のために最初の配列データを確認してみましょう。

表示した画像はイメージフォルダを作成して保存します。

画像データを扱うコード

“`python
X, y = mnist[“data”], mnist[“target”]
X.shape
y = y.astype(np.uint8)
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt

some_digit = X[0]
some_digit_image = some_digit.reshape(28, 28)
plt.imshow(some_digit_image, cmap=mpl.cm.binary)
plt.axis(“off”)

# save_fig(“some_digit_plot”)
plt.savefig(“number.png”)
plt.show()
“`

最初の配列だけではなく、100個分の数値を確認してみます。細かい説明は省略しますが、100個の数値データを10×10の行列データとして表示します。

MNISTは学生や公務員などの様々な人に手書き数字を記載してもらったデータです。数値一つ一つに個性があることが感じられると思います。中には人間にも判定が難しい数値がありますが、これらをscikit-learnを使ってコンピュータに学習させ、正解と照らし合わせていきます。

画像データの照らし合わせを行う

“`python
def plot_digit(data):
    image = data.reshape(28, 28)
    plt.imshow(image, cmap = mpl.cm.binary,
               interpolation=”nearest”)
    plt.axis(“off”)

def plot_digits(instances, images_per_row=10, **options):
    size = 28
    images_per_row = min(len(instances), images_per_row)
    # This is equivalent to n_rows = ceil(len(instances) / images_per_row):
    n_rows = (len(instances) – 1) // images_per_row + 1

    # Append empty images to fill the end of the grid, if needed:
    n_empty = n_rows * images_per_row – len(instances)
    padded_instances = np.concatenate([instances, np.zeros((n_empty, size * size))], axis=0)

    # Reshape the array so it’s organized as a grid containing 28×28 images:
    image_grid = padded_instances.reshape((n_rows, images_per_row, size, size))

    # Combine axes 0 and 2 (vertical image grid axis, and vertical image axis),
    # and axes 1 and 3 (horizontal axes). We first need to move the axes that we
    # want to combine next to each other, using transpose(), and only then we
    # can reshape:
    big_image = image_grid.transpose(0, 2, 1, 3).reshape(n_rows * size,
                                                         images_per_row * size)
    # Now that we have a big image, we just need to show it:
    plt.imshow(big_image, cmap = mpl.cm.binary, **options)
    plt.axis(“off”)

example_images = X[:100]
plot_digits(example_images, images_per_row=10)
plt.savefig(“number100.png”)
plt.show()
“`

MNISTは訓練用データとテスト用データに分かれているので、名称を分けて記載します。データを分ける理由は単純で、本番用の試験問題を練習で解いていたらモデルの精度向上を確認できないためです。練習問題と本番の問題は全く違う必要があります。

 
“`python
X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:]
y_train_5 = (y_train == 5)
y_test_5 = (y_test == 5)
“`

それでは機械学習を始めてみましょう。今回は0〜9の数値の中から”5”を判定する学習を行います。学習後はまだ使用していない10000文字のテストデータを使用して、データモデルの正解率を導き出します。

機械学習を行う

“`python
from sklearn.linear_model import SGDClassifier
sgd_clf = SGDClassifier(random_state = 42)
sgd_clf.fit(X_train,y_train_5)
from sklearn.model_selection import cross_val_score
cross_val_score(sgd_clf,X_train,y_train_5, cv=5 ,scoring = “accuracy”)
“`

結果としては95.47%の一致率でした。比較的短いコードですが、データモデルが文字を学習して、5と5以外を認識できている事が分かります。なお、正解率はお使いの環境によって多少変化します。

 

まとめ

データサイエンスで用いられている機械学習の概要と、機械学習に使用されるscikit-learnモジュールの概要説明を行いました。機械学習は画像認識や回帰など、私たちの身の回りに溢れている問題をコンピュータに学習させて、自動的に判断してもらう仕組みです。

試しに手書き文字の認識をコード付きでご紹介し、機械学習の雰囲気を掴んで頂けたと思います。