【Python】㉘機械学習Ⅱ(仕組み)

始めに
前回は、機械学習の用語についてまとめていきました。
今回は、機械学習の仕組みについて学んでいきましょう。
前回の記事はこちら
モデルとは
ここでは「教師あり学習」についてです。
モデルとは、データを入力すると、内部で何らかの処理を行い、処理結果のデータを出力する仕組みのことです。
モデルの内部にはいくつかの調節可能なパラメータがあります。
学習を行う目的は、これらのパラメータを適切に調整することによって、入力から望ましい出力が得られるようなモデルに改良することです。

最初のパラメータは適当な値に設定しておきます。
適当に設定したため、多くの場合は入力から望ましい出力は得られません。
そこで、訓練データを使った学習を行います。
教師あり学習における訓練データは、入力部分と正解部分から構成されています。
例えば、多数の犬の画像と猫の画像を、訓練データとして使い、その画像が犬か猫かを見分けるプログラムを作るとします。
コンピュータはどちらが犬か猫かをそもそも知らないため、各画像にその画像が示すラベルをつけておいます。
この場合、入力部分は犬と猫の画像、正解部分はラベルです。
訓練データのモデルの入力部分をモデルに入力すると、モデルが処理した結果を出力します。
この出力と、正解部分を比較し誤差を求めます。

求めた誤差を使い、モデルのパラメータを調整していきます。
誤差がなるべく小さくなるようにすることで、正解に近い出力をするモデルに改良することができます。
テストデータとは
学習によってモデルがどの程度まで改良されたかを調べるために「テストデータ」を使用します。
このテストデータも訓練データ同様、入力部分と正解部分で構成されています。
テストデータのモデル部分を入力すると、モデルが処理結果を出力します。
その結果と正解部分を比較し、そのモデルの正解率を求めます。
「訓練データ」と「テストデータ」は異なるものを使用します。
これは、訓練データでは高い正解率を出力することができるが、未知のデータに対しては高い正解率を出力することができないという事態も起こりえるためです。
学習の目的は、既知のものに対してだけではなく、未知のものに対しても高い正解率を出力することです。

終わりに
今回は機械学習の仕組みについて学んでいきました。
次回は、実際にプログラムを実行させてみましょう。
【Python】㉗機械学習Ⅰ(用語の定義について)

始めに
今回から、いよいよ機械学習へ突入していきます!
いよいよですね!
それでは早速初めて行きましょう!
機械学習とは
機械学習とは、人間が行うような学習の能力をコンピュータで実現するための技術です。
人間がプログラムを改良するのではなく、プログラム自身が自動的に、入力されたデータ(多くの場合は大量のデータ)を使用して性能を改良していくことが特徴です。
機械学習関連の用語は多くあるため、簡単ではありますが解説していきたいと思います。
人工知能(AI : Artificial Intelligence)
人工知能(AI)とは、コンピュータを使って人間のような知能を実現する仕組みです。
最近話題となっている、画像や音声を認識する人工知能や、将棋、囲碁をプレイする人工知能などがあります。
ニューラルネットワーク(NN : Neural Network)
ニューラルネットワークは、人工知能に関する研究分野の1つです。
元々は脳の仕組みをコンピュータ上で再現することから始まった研究分野です。
多数のノード(節)が網状に結合された構造を持ちます。
ノードは入力層(Input Layer)、中間層(Hidden Layer)、出力層(Output Layer)に分かれています。
ディープラーニング(Deep Learning)
ディープラーニングとは深層学習ともいい、機械学習使用し、ディープニューラルネットワーク(階層が深いニューラルネットワーク)の性能を改良する手法です。
一般的には、中間層が2層以上のネットワークのことをいいます。
ニューラルネットワークとディープラーニングの構造は以下のようになります。

教師あり学習と教師なし学習
機械学習には、「教師あり学習」と「教師なし学習」があります。
「教師あり学習」では、正解が付属する訓練データを使います。
訓練データに対するモデルの出力と正解とを比較して、両者の誤差が小さくするなるように、モデルのパラメータを調整します。
「教師なし学習」では、正解が付属する訓練データではなく、正解が付属しない入力データを使います。
つまり、入力データにおける個々に対して、モデルが出力するべき具体的な値は決まっていません。モデルの出力を人間が解釈して、有用な結果が出ているのかどうかを判断します。
終わりに
今回は、機械学習関連の用語について、また学習手法について学んでいきました。
【Python】㉖timeモジュール

始めに
前回は、日時を扱うモジュールであるdatetimeモジュールについて学んでいきました。
今回は、プログラムの実行速度を測るモジュールであるtimeモジュールについて学んでいきましょう。
前回の記事はこちら
モジュールについてはこちら
早さの比較
プログラムには、実行速度が速いプログラムと実行速度の遅いプログラムがあります。
早速比較してみましょう。
例➀プログラム速度の比較
Rakeさんの『100万回の”I love you”』を例にしようと思います。
まずは、for文を使用してI love youを100万回表示するプログラムを書きます。

続いて、文字列に対して*演算子を使用して表示します。
*演算子は、文字列を指定した回数だけ、繰り返します。

実行してみて、実際に差があることは分かりますが、どの程度差があるか正確には分かりませんよね。
そのため、次に紹介するtimeモジュールを使用します。
timeモジュール
timeモジュールはプログラムの実行時間を測定します。
timeモジュールには様々な機能がありますが、現在の時間を求めるにはtime関数を使用します。
----------
time.time()
----------
多くの環境では、time関数は1970年の1月1日0時0分0秒からの経過時間を表示します。
また、開始時間を変数に代入し、終了時間から減算すれば、経過時間が求められます。
例②timeモジュール
先ほど使用した2つのプログラムを少々書き換えて、実行時間を計測しようと思います。
for文

*演算子

上記の結果より、for文の実行時間は5.9秒程度。
*演算子は、0.016秒程度でした。
このことから、for文は*演算子よりも368.75倍、約370倍程度の時間がかかることが分かります。
文字列を連結する処理は、何度も繰り返すと意外に時間がかかることがあります。
*演算子は、最終的な文字列に必要なメモリ領域をあらかじめ確保してから処理を行うために、メモリ領域の拡大や文字列のコピーといった処理が行われず、高速処理できているためと思われます。
終わりに
今回はプログラムの実行速度を測るモジュールである、timeモジュールについて学んでいきました。
プログラムの実行速度なんて、あまり気にしていなかったので、このように可視化されるとわかりやすいですよね。
次回は、いよいよ機会学習に突入してきましょう。
【Python】㉕datetimeモジュール

始めに
前回は、randomモジュールについて学んでいきました。
今回は、日時を扱うdatetimeモジュールについて学んでいきましょう。
前回の記事はこちら
datetimeモジュール
今日が何月何日か調べたいときなど、日時を扱えるのが、標準ライブラリのdatetimeモジュールです。
例えば、今日が何月何日かを調べるためには、以下のように書きます。
----------
datetime.date.today()
----------
前回同様、datetmeモジュールはインポートする必要があります。
datetimeはモジュール名、dateはクラス名、today()はクラスメソッド名という構造になっています。
例➀date.today
今日の日付を取得します。

前回の記事で紹介しましが、モジュール名なしで使用することができます。
date.today()では、日付までを取得するものでしたが、datetimeクラスを使用すると、日付と時刻を同時に扱えます。
現在の日時を取得するには、datatimeクラスのnowメソッドを使用します。
----------
datetime.datetime.now()
----------
例②datetime.now
今現在の時刻を調べてみましょう。

現在、2020年5月20日10時22分なので上記のように出力されます。
その後の、13,878099は13.878099秒ということです。
日時の計算
datetimeモジュールを使用すると、日時の計算を行うことができます。
指定した年月日のdateオブジェクトを作成するためには以下のように書きます。
----------
datetime.date(年,月,日)
----------
例③日付の計算
よく歌った「もういくつ寝るとお正月~」という歌ありますよね。
実際に、今日から何日でお正月なのかを数えてみましょう。
先ほど紹介したdateオブジェクトを使用すれば以下のように書くことができます。

モジュール名を省略してあることに注意してください。
今日から226日後にお正月らしいです。
次に、何日後の日付を求めるプログラムを求めます。
指定した日数を表わすには、timedeltaオブジェクトを使用します。
----------
datetime.timedelta(日数)
----------
例➃日数の加算
先ほど、お正月まで226日とのことだったので、今日の日付に226日を足し、本当にお正月になるかを確かめてみましょう。

226日後は本当にお正月でした!
今回もモジュール名は省略されているので注意しましょう。
終わりに
今回は、日時を扱うモジュール(datetimeモジュール)について学んでいきました。
次回は、プログラムの実行時間を計測するtimeモジュールについて学んでいきましょう。
【Python】㉔モジュール(randomモジュール)

始めに
前回は、例外処理について学んでいきました。
今回は、モジュールについて学んでいきましょう。
前回の記事はこちら
モジュールとは
モジュール(module)とは、「商品」という意味を持つ言葉です。
特にプログラミングの分野では、関連した機能をひとまとめにしたプログラムのことを、モジュールと呼びます。
pythonには非常に多くのモジュールがあり、便利なモジュールの使い方を覚えれば、高機能なプログラムを簡単に作ることができます。
ちなみに、pythonのモジュールは、定義や文が入った.pyファイルです。
そのため、自分で作ったプログラムをモジュールとしてモジュールとして使うこともできます。
モジュールを使う方法
組み込み関数は特別な操作をしなくても使用することができますが、組み込み関数ではない関数を使うには、その関数の定義を含んだモジュールをインポートする必要があります。
pythonでは、プログラムに必要なモジュールの機能を取り込むことをインポートと呼びます。
モジュールをインポートするには、以下のように行います。
----------
import モジュール名
----------
また、モジュールの機能をする場合は、以下のように行います。
----------
モジュール名 . 関数名 ( )
----------
関数に引数を指定する場合は、以下のように書きます。
----------
モジュール名 . 関数名 ( 引数1 , 引数2 , ... )
----------
モジュールに別名をつけて利用することができます。
----------
import モジュール名 as 名前
----------
randomモジュール
randomモジュールは、乱数を生成する機能を提供するものです。
randomモジュールをインポートするには、以下のように行います。
----------
import random
----------
そして、randomモジュールの機能をする場合は、以下のように行います。
----------
random . random ( )
----------
random関数は、0.0以上1.0未満の乱数を返します。
例➀randomモジュール
random関数を呼び出します。

上記のように何度か繰り返すと、きちんと乱数が生成されている事が分かります。
次に、さいころのような、決められた範囲で乱数を生成します。
A以上、B以下の乱数を生成する場合、以下のように書きます。
----------
random . randint ( A , B )
----------
また、モジュール内の機能をインポートして、モジュール名を無しで使用することができます。
今回は、randomモジュールのrandint機能を使用する場合、以下のように書きます。
----------
from random import randint
----------
例②randient機能
さいころの数字のように1~6の整数を生成します。
今回は、インポートしたrandint機能に「ri」という名前をつけて使用します。

randomモジュールの便利な機能
random関数の便利な機能として、choice関数とshuffle関数があります。
random関数は、シーケンス(文字列、リスト、タプルなど)からランダムに要素を選ぶことができます。
choice関数を使用するには、以下のように使用します。
----------
random . choice ( シーケンス )
----------
例③choice関数
トランプのプログラムを作るため、A,2,3,4,5,6,7,8,9,10,J,Q,Kの文字列を含むリストを作成します。
randomモジュールのchoice関数を用いて、取り出してみましょう。

shuffle関数は、その名の通り、シーケンスが含む要素の位置をランダムに変更します。
shuffle関数は、以下のように使用します。
----------
random . shuffle ( シーケンス )
----------
例➃shuffle関数
先ほど作成したトランプのプログラムを使用し、randomモジュールのchoice関数を用いて、混ぜあわせてみましょう。

終わりに
今回はrandomモジュールについて学んでいきました。
モジュールは様々ありますが、インポートの方法や、使用の仕方は同じですので覚えておきましょう。
【Python】㉓例外処理

始めに
前回までは、オブジェクト指向プログラミングについて学んでいきました。
今回は、例外処理について学んでいきましょう。
前回の記事はこちら
例外とは
例外はプログラムの実行中に起こるエラーです。
例外が発生すると、プログラムはエラーメッセージを表示して終了してしまいます。
ただし、例外処理を記述しておけば、エラー発生後もプログラムの実行を継続をする事ができます。
例外処理の書き方
例外処理は以下のようなtry文で以下のように書きます。
----------
try :
処理A
except 例外名 :
処理B
----------
上記では、最初にtry節の処理Aを行います。
処理Aの実行中にエラーが発生した場合、処理Aの実行を中断し、エラー内容に合わせた例外(例外インスタンス)を発信します。
exceptに続けて、対処したい例外名(例外クラス名)を記述します。
もし発生した例外がexcept節の例外名に一致していたら、処理Bを実行します。
except節は複数並べることができます。
発生した例外がどのexcept節の例外名とも一致しない場合には、エラーメッセージを表示してプログラムは終了します。
例➀例外処理
例外処理を確認するために、リストに格納されたデータの合計を求めることとします。
このリストの中に、'1','2'だけの数値に変換できる文字列だけで無く、'three'という数値に変換できない文字列が混ざっています。
<try1.py>

上記のプログラムを実行すると、以下のような結果が得られます。
ValueError: invelid literal for int() with base 10: 'three'
これは、プログラムの4行目でint関数を用いて、'three'という文字列を数値に変換しようとしたことが例外の原因です。
そのため、以下のように書き換えます。
<try2.py>

except節には何かしらの文を書く必要があるため、pass文を使用します。
このプログラムを実行すると、数値に変換する事ができない'three'以外の1,2,4を合計した7を返します。
else節とfinally節
try節ではexcept節だけではなく、else節やfinally節も書くことが可能です。
else節やfinally節は省略が可能なので、必要なときだけ使うことができ、以下のように表わします。
----------
try :
処理A
except 例外名 :
処理B
else :
処理C
finally :
処理D
----------
例②else節とfinally節
else節やfinally節の動作を確認するため、以下のプログラムを実行します。

上記のプログラムでは、例外が発生しないため、例外は発生しません。
そのため、try、else、finallyの順に実行されます。
最後に
今回は、例外処理について学んでいきました。
少しずつプログラミングを進めていると、エラーについても詳しくなりますよね。
エラーと仲良くなりつつお勉強を頑張りたいと思います。
【Python】㉒オブジェクト指向プログラミング③

始めに
今回は、前回、前々回に引き続き、オブジェクト指向プログラミングについて学んでいきましょう。
前々回の記事はこちら
前回の記事はこちら
クラス属性と定数
前回のプログラム(Pokemon4.py)では、レベルの上限値(100)をif文の中に組み込んでいました。
もしも上限値を変更したくなった場合、以下のプログラムの'100'の部分を2カ所とも書き換える必要があります。
<Pokemon4.py>

こういった場合、変数や定数にすることがおすすめです。
例➀クラス属性と定数
今回もポケモンを例にしようと思います。
ポケモンの名前、レベル、タイプ、特性についてまとめ表示します。
表示するポケモンは、サルノリです。
前回のプログラミング(Pokemon4.py)のレベル上限に対し、定数を組み込みます。
<Pokemon5.py>

上記のように記述する事で、もしもレベル上限を変更したい場合、LEVEL_LIMIT=100の部分を変更するだけでよく、ミスが少なくなります。
継承
既存のクラスを拡張し、新しい機能を定義することができます。
このとき、新しいクラスは、既存のクラスの持つすべてを引き継ぎます。
このことを「継承」といいます。
また、このときの既存のクラスを「基底クラス」、新しいクラスを「派生クラス」といいます。
派生クラスの定義は以下のように行います。
----------
class 派生クラス(基底クラス名) :
メソッドや変数の定義
----------
例➁クラスの継承
Pokemonを基底クラスとして、サルノリ、ヒバニー、メッソンを定義します。
サルノリはレベル5で、「ひっかく(Scratch)」、「なきごえ(Grow!)」を覚えています。
<Pokemon6.py>

基底クラスにあるメソッドを派生クラスで再定義することを「オーバーライド」といいます。
上記のプログラムでは、__init__メソッドとElementsメソッドをオーバーライドしています。
多重継承
派生クラスの定義をする際に、複数の基底クラスを指定することができます。
多重係数は、以下のように表わします。
----------
class 派生クラス(基底クラス名 , 基底クラス名 , ...) :
メソッドや変数の定義
----------
複数の基底クラスから機能を継承する事を「多重継承」といいます。
終わりに
本日は、前回、前々回に引き続き、オブジェクト指向プログラミングについて学んでいきました。
ボリュームの多い分野であったので、自身で工夫して遊びつつ、慣れていきましょう!