この投稿は 限定共有に設定されています。 投稿者本人及びURLを知っているユーザーのみアクセスすることができます。

機械学習のためのプログラミング講座 1時限目

  • 0
    コメント

はじめに

株式会社キカガクの吉崎と申します。

本日は、機械学習のためのプログラミングを学んでいきます。
プログラミングが初めての方でもわかるように工夫しておりますので、頑張っていきましょう。

また、プログラミングに慣れている方は、サンプルコードを実行後に色々なパラメータ調整や引数の調査など、空き時間を活用して、理解を深めてみてください。

キカガクでは、『機械学習・人工知能 脱ブラックボックスセミナー』を中心に、機械学習の理論とプログラミングを教えています。

自己紹介

私は株式会社キカガク代表取締役の吉崎亮介と申します。
本日の講師を担当いたしますので、どうぞよろしくお願いいたします。

略歴

  • 舞鶴高専 電子制御工学科卒業 ← 画像処理(AR)を研究
  • 舞鶴高専 電気・制御システム工学専攻卒業 ← ロボット工学・システム制御・最適化を研究
  • 京都大学大学院情報学研究科(加納研) ← 製造業向けの機械学習の応用研究
  • 株式会社SHIFT(社長室) ← 人工知能によるソフトウェアテスト自動化の研究
  • 株式会社Carat(取締役兼COO) ← LINE Bot経由でベストな旅行計画を提案してくれるアプリの自然言語処理部分と最適化エンジンを担当
  • 株式会社キカガク(代表取締役社長) ← 現在は機械学習の教育をメインに担当

過去の受賞や講演歴

研究
・ADCHEM 若手最優秀論文賞 ← 化学工学系で世界最高峰の国際会議の最優秀賞
・化学工学会 最優秀技術賞 ← 日本の化学工学系で最高峰の学会の最優秀賞

講演
・CEDEC2016『人工知能とソフトウェアテストの展望』(招待講演) ← ゲーム開発者向けで日本最大規模のカンファレンス

インターン
・CyberAgent社 ネイティブアプリインターン最優秀賞(最適なファッションのリコメンドアプリ)
・Yahoo×京都大学 HackU2016 最優秀賞(最適な旅程計画提案アプリ)
・SHIFTハッカソン 最優秀賞(ソフトウェアテストスクリプト自動生成アプリ)

株式会社キカガク

株式会社キカガクは『あたり前の便利を創ろう』を企業理念に、機械学習によって現場で『あたり前の便利』を創るための支援を行っています。
『キカガク』という名前は、機械学習を現場で導入するための4つのプロセスから構成されています。

  • キ:教育 ← 現在ここ
  • カ:課題設定
  • ガ:学習モデル構築
  • ク:組み込み

フォローや友達申請おまちしています!

機械学習だけのプログラミングでは実用性がつかめない

機械学習だけ勉強しておけば、プロダクト制作に使えるのでは無いの??という質問があるかと思いますが、実際にはそうではありません。

講師である吉崎の解釈である機械学習の位置づけを見てみましょう。

完成.png

『機械学習』とは入力となる数値から出力となる数値を予測するためのものであり、そもそも『画像』というものをどうすれば数値に落とし込んでいくのか?ということは機械学習の範疇ではありません。
そのため、画像系の方は機械学習を学ぶ以外に、この『画像処理』、『音声処理』、『自然言語処理』などを学ぶ必要があります。

なぜPythonを使うの?

本セミナーでは、プログラミング言語としてPythonを使用します。
Pythonはデータ解析でよく使用される言語ですが、実際は初期のFacebookをはじめとしたWebアプリケーション制作にもよく使われています。

多言語も含めた位置づけはこのようになります。

python.png

もちろんRubyやPHPでも解析ができたりするのですが、NumpyというライブラリがあるPythonが解析においては抜きん出ているのは間違いありません。

解析だけの観点では、MATLABやRも強力な線形代数演算をサポートするライブラリがあるのですが、Webアプリケーションへ落とし込むとなると、なかなか扱いづらかったりします。

そんな解析とWebアプリケーションの機能を両方共備えていて、かつ初心者にも扱いやすいのがPythonです。

さらに、画像処理や音声処理、自然言語処理のどの分野においても、スタンダードに近いライブラリが存在しており、リファレンスも豊富なため、機械学習とPythonの相性は非常に良いといえます。

Library.png

Pythonが初心者にオススメな理由

1. 予約語が少ないので覚えやすい

  • 予約語:プログラミング言語において字句的には識別子(変数名、関数名、クラス名など)としてのルールを満たしているにもかかわらず、識別子として使えない字句要素(wikipediaより)
  • 例えば、関数を定義するdef、条件分岐のif、ループ処理のforなどが予約語にあたる
  • Pythonは全部33個

2. 簡潔で読みやすい

  • 予約語やキーワードの長さが短い
  • (){}などが要らない
C言語の場合
int factorial(int x)
{
    if (x == 0) {
        return 1;
    } else {
        return x * factorial(x - 1);
    }
}
Pythonの場合
def factorial(x):
    if x == 0:
        return 1
    else:
        return x * factorial(x - 1)

3. インデントが強制されていてキレイに書ける

  • インデント(字下げ)が必須なので誰が書いても同じようなプログラムになる→読みやすい
  • インデントのありなしで悩む必要がない
インデントがないとエラー
def factorial(x):
    if x == 0:
        return 1
    else:
return x * factorial(x - 1) # エラー

このように、Pythonはプログラミング初心者にとって勉強しやすい言語なのですが、機械学習を学ぶ上でもオススメな言語です。

環境構築

チェックリスト

最後にインストール作業が正しく完了したか確認しましょう。
以下のチェックリストを満たしているか、確認してください。

  1. Python3系を使っている
  2. NumPyがインストールされている
  3. pandasがインストールされている
  4. matplotlibがインストールされている
  5. scikit-learnがインストールされている
  6. Jupyter Notebookがインストールされている
  7. chainerがインストールされている

確認方法

ターミナルで以下を実行してください。

$ python
Python 3.5.2 |Anaconda custom (64-bit)| (default, Jul  2 2016, 17:53:06)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy, pandas, matplotlib, sklearn, jupyter, chainer # エラーが出なければOK
>>>

※ numpy, pandas, matplotlib, sklearn, jupyterはあとの講義で使っていくライブラリやツールです。Anacondaに同梱されているため、今回は明示的にインストールしていません。

Pythonの基礎

1. Pythonの実行方法

Pythonのプログラムを実行する方法は大きく分けて3種類あります。

  1. ファイルを作成して、ファイル名を引数にpythonコマンドで実行
  2. pythonコマンドを実行して、対話的に実行
  3. Jupyter Notebook上で実行

1. ファイルを作成して実行

はじめは1番オーソドックスな方法である、ファイルを作成して実行する方法です。
以下の内容でtest.pyというファイルを作成してください。

test.py
print('hello python!')

保存したら、ターミナル(Windowsならコマンドプロンプト)上でtest.pyがあるフォルダまで移動し、次のコマンドを入力してください。

$ python test.py
hello python

2. 対話的に実行

ターミナル上でpythonと入力すると、対話的にプログラムを実行できます。

$ python
>>> print('hello python')
hello python
>>>

exit()またはCtrl+Dで終了します。

2. 基本構文

print文

print('kikagaku') # => kikagaku

四則演算

1 + 1 # => 2 加算
2 - 1 # => 1 減算
3 * 5 # => 15 乗算
10 / 2 # => 5 除算
2 ** 3 # => 8 べき乗

問題1

  1. print('kikagaku', '機械学習')を実行するとどう表示されますか? print('kikagaku', 1)は実行するとどうなりますか?
  2. 10 / 3を実行すると結果はどうなりますか?また、10 // 3を実行すると結果はどうなりますか?
  3. 余りはどう計算しますか?

問題1の答え

  1. ('kikagaku', '機械学習')(引数を複数とれる) ('kikagaku', 1)(型を混ぜてもOK)
  2. 順に3.33333..., 3(Python3系の場合)
  3. %

比較演算

1 < 2 # => True
1 != 2 # => True
2 == 5 # => False
3 >= 3 # => True
'test' == 'test' # => True

エスケープシーケンス

通常の文字列では表せない特殊な文字や機能を、規定された特別な文字の並びにより表したもの

print('キカガクの講座では\n未経験者でも\'機械学習\'を使えるよう\n\t数学・プログラミングの基礎から教えます。')
# => キカガクの講座では
#    未経験者でも'機械学習'を使えるよう
#       数学・プログラミングの基礎から教えます。

コメントアウト

# これはコメントなので、実行時に無視されます。

問題2

  1. and, or, notについて調べて使ってみてください(Python ブール演算で検索)。
  2. Pythonで複数行にわたるコメントアウトはどうしますか?
  3. test.pyを作って次のように書いてください。これをpython test.pyで実行するとどうなりますか?
if True:
# コメント
    print('コメントはインデント無視でも大丈夫?')

問題2の答え

  1. 省略
  2. """ ~ """または''' ~ '''を使用
  3. 正しく実行できる

3. 変数と型

変数

値やオブジェクトの入れ物、ラベル付け

a = 'test'
b = 15
c = 15 + b # => 30
print(3 + c) # => 33

数値

10 # int型
-20 # 負の値を取れる
1.5 # float型
complex(1, 2) # complex型(複素数)

文字列

'文字列'

"これも文字列"

"""複数行にわたる
文字列は3つのダブルクォーテーション(またはシングルクォーテーション)で囲む => コメントとして使われることが多い
"""

問題3

  1. round(),math.floor(), math.ceil()について調べて、実際に使ってみてください。
  2. 'hello' + ', world'を実行してみてください。
  3. 'hello, ' * 5を実行してみてください。

問題3の答え

  1. round()は実数値を四捨五入する組み込み関数。math.floor()mathモジュールの関数で実数値の小数部を切り捨てる。math.ceil()は実数値の小数部を切り上げる。
  2. hello, world+で文字列結合)
  3. hello, hello, hello, hello, hello,

リスト

要素を[]で囲んで並べたもの。

numbers = [1, 2, 3]
numbers[0] # => 1
numbers[1:3] # => [2, 3]
strings = ['hello', 'world']
array = ['test', 100, True] # 混ぜてもOK

タプル

  • 複数の要素を一つにまとめたもの
  • リストとの違いは、リストは後から変更ができるがタプルはできない点
t = (1, 2, 3) # []ではなく()で囲う
t[0] # => 1

辞書

キーと値のペアを保持するリスト。

d = {'key': 'value'}
result = {'math': 90, 'science': 75, 'english': 80 }
result['math'] # => 90

問題4

  1. リストの長さを計算する関数を調べてください。
  2. 文字列のjoin(),replace(), リストのappend(), remove()について調べて、実際に使ってみてください。
  3. タプルに再代入してみてエラーになるか確認してください。
  4. 辞書のキーの削除を行う関数を調べて使ってみてください。

問題4の答え

  1. len()(組み込み関数)
  2. 下記参照
  3. 省略
  4. 下記参照
問題4-2の答え
','.join(['a', 'b', 'c']) # => 'a,b,c'

'hello, python'.replace('python', 'kikagaku') # => 'hello, kikagaku'

list = ['a', 'b', 'c']
list.append('d')
print(list) # => ['a', 'b', 'c', 'd']

list.remove('d')
print(list) # => ['a', 'b', 'c']
問題4-4の答え
dict = {'key1': 'value1', 'key2': 'value2'}
del(dict['key1'])
print(dict) # => {'key2': 'value2'}
dict.pop('key2') # => {}

4. 制御構文

制御構文はプログラムの流れを制御する構文です。

Pythonにおける主要なものは以下の通りです。

  • if
  • for
  • while
  • break
  • continue

if文

条件式が真ならば、ブロック内のプログラムを実行します。

value = 3
if value == 1:
    print('valueは1です')
elif value == 2:
    print('valueは2です')
else:
    print('valueは1でも2でもありません')

elif, elseは省略可能

問題5

  1. 変数numの絶対値を返すよう、下記のプログラムを完成させてください。
def abs(arg):
    num = arg

    # ここにプログラムを書いてください

    return num

# abs()の使い方
print(abs(-10)) # => 10

問題5の答え

def abs(arg):
    num = arg

    if num < 0:
        num = num * -1

    return num

print(abs(-10))

for文

リストなどの各要素に順にアクセスします。

fruits = ['apple', 'banana', 'orange']
for fruit in fruits:
    print(fruit)

"""
=> apple
   banana
   orange
"""

問題6

  1. 以下にある変数numbersの全ての値を2乗して、1行ずつ表示するプログラムを完成させてください。
numbers = [1, 2, 3, 4, 5]

# ここにプログラムを書いてください
# 表示結果はこうなります
# 1
# 4
# 9
# 16
# 25

問題6の答え

numbers = [1, 2, 3, 4, 5]

for number in numbers:
    print(number * number)

while文

条件式が真の間、ブロック内の処理を繰り返し実行します。

value = 0
while value < 2:
    print(value)
    value = value + 1

# => 0
#    1

問題7

  1. while文を使って1から100まで数値を表示するプログラムを書いてください。
  2. 上記のプログラムを改良して、3の倍数のときだけ数値を表示するプログラムを書いてください。

問題7の答え

問題7-1の答え
i = 1
while i <= 100:
    print(i)
    i += 1
問題7-2の答え
i = 1
while i <= 100:
    if i % 3 == 0:
        print(i)
    i += 1

break

繰り返し処理を抜けるために使います。

for n in [0, 1, 2, 3]:
    print(n)
    if n == 2:
        break

問題8

  1. 上記のプログラムを実際に実行してみてください。

continue

繰り返し処理の一部をスキップしたいときに使います。

for n in [0, 1, 2, 3]:
    if n == 2:
        continue
    print(n)

問題9

  1. 上記のプログラムを実際に実行してみてください。

5. 関数とモジュール

関数

処理をまとめて、再利用可能にしたものを関数といいます。

def get_fruit_by_color(color):
    if color == 'red':
        return 'apple'
    elif color == 'yellow':
        return 'banana'
    else:
        return 'sold out'

print(get_fruit_by_color('red')) # => 'apple'

問題10

  1. 引数に数値のリストを受け取り、その中の最大値を返す関数my_max(num_list)を実装してください。
  2. 引数に三角形の底辺と高さを受け取り、その面積を返す関数calc_area(width, height)を実装してください。
問題10-1のテンプレート
def my_max(num_list):
    # ここにプログラムを書いてください

list = [2, 3, 7, -1, 10, 5, 6]
print(my_max(list)) # => 10
問題10-2のテンプレート
def calc_area(width, height):
    # ここにプログラムを書いてください

print(calc_area(10, 8))

問題10の答え

問題10-1の答え
def my_max(num_list):
    max_value = None
    for number in num_list:
        if max_value == None or max_value < number:
            max_value = number

    return max_value

list = [2, 3, 7, -1, 10, 5, 6]
print(my_max(list))
問題10-2の答え
def calc_area(width, height):
    return (width * height) / 2

print(calc_area(10, 8))

モジュール

関数などを更にまとめて、再利用しやすくしたものをモジュールと呼びます。

import math # 標準のmathモジュールを読み込み
math.floor(4.5) # => 4

問題11

  1. 自分で作成したスクリプトファイルもモジュールとして読み込めます。my_math.pyを作成してその中に引数として2つの数値を受け取り、それを加算した値を返す関数add(x, y)を実装してください。それを別ファイルのexample.pyから呼び出してください。

問題11の答え

my_math.py
def add(x, y):
    return x + y
example.py
import my_math

print(my_math.add(1, 2))

6. オブジェクト指向プログラミング

オブジェクト指向プログラミングは、データと処理を一つのオブジェクトとしてとらえ、プログラムの見通しを良くしようとする一つのプログラミング手法です。

例えば、車を一つのオブジェクトと見立てます。
運転者(プログラマー)は車がどういう仕組みで動いていて、内部状態がどうなっているかは分かりませんが、車を操作することはできます。

クラスとインスタンス

  • クラス:オブジェクトが持つデータと処理(関数、メソッドと呼ばれることが多いです)の情報をまとめたもの。車で言うと設計図にあたる
  • インスタンス:クラスから生成された、実際のデータを持つもの。車そのものにあたる
class Car: # クラス定義

    def __init__(self, engine, tire, fuel, position):
        self.engine = engine
        self.tire = tire
        self.fuel = fuel
        self.position = position

    def drive(self):
        if self.fuel == 0:
            print('no fuel')
        else:
            self.fuel -= 1
            self.position += 1

if __name__ == '__main__':
    car = Car('honda', 'honda', 100, 0) # インスタンス生成
    car.drive()
    print(car.fuel, car.position) # => 99 1

より実践的な例として、以下の例が挙げられます。

import numpy as np

A = np.array([[1, 0], [0, 1]])
print(A) # => array([[1, 0],
         #           [0, 1]])
type(A) # => <class 'numpy.ndarray'> 型やクラスを調べられる

NumPyモジュールに含まれるnumpy.ndarrayを使ったものですが、ここでポイントなのはインスタンスの状態や処理の中身を知らなくても、行列の計算はできるということです。