覚え書きブログ

scikit-learnを用いた機械学習(Pythonの基礎 2/4)

<< scikit-learnを用いた機械学習(Pythonの基礎 1/4)

参考書

本ブログの内容の詳細は、「機械学習スタートアップシリーズ ゼロからつくるPython機械学習プログラミング入門」に掲載されています。
機械学習に必要な数学の復習から、機械学習アルゴリズムの導出およびPythonの基本ライブラリのみを用いた実装方法まで学びたい方は、本書籍をご活用ください。
bookclub.kodansha.co.jp

変数と標準出力

Pythonでは,型宣言をせずに任意の名前の変数に値を代入することができます.代入された値に基づき,Python側で自動的に変数の型を決めます.

num = 10
string = "Hello world"

また,標準出力は,print関数を用います.以下のようにf文字列(f-strings)を用いて簡単に変数の値や数式の結果を文字列の中に挿入することができます.
具体的には、文字列の前にfを置き(f"xxx")、文字列中の中かっこのなかに変数や数式を置きます。

print(f"文字列{変数、計算式}文字列")

それでは,変数を設定し,print関数を用いて変数の値と型を標準出力してみましょう.以下のコードをjupyter notebookのフォームにコピーペーストして,Ctrl+Eneterで実行してみましょう.

num = 10
string = "Hello world"
print(f"num={num}, type(num)={type(num)}")
print(f"string={string}, type(string)={type(string)}")

実行結果は以下のようになります.変数numはint型,変数stringはstr型に設定されていることがわかります.

num=10, type(num)=<class 'int'>
string=Hello world, type(string)=<class 'str'>

Jupyter notebookの画面上では以下のようになります.
f:id:hirotaka_hachiya:20190821095506p:plain

データ構造

次にPythonの代表的なデータ構造について解説します。
Pythonには,多次元配列データを格納するためのデータ構造がいくつかあります。

リストPython 標準)

各要素をオブジェクト(数値、文字列、リスト自身など)として格納する変数。型を気にせず配列操作が簡単にできます。
以下のように、角括弧[オブジェクト1, オブジェクト2...]を用いて定義します。jupyter notebookのフォームに入力しCtrl+Eneterで実行してみましょう。

price = [120,180,300,150]
fruit =["apple", "orange","pineapple","banana"]
all = [price, fruit]
all
[[120,180,300,150], ['apple', 'orange','pineapple','banana']]
リストの大きさ

len関数を用いると、以下のようにリストの大きさを求めることができます。

len(price)
4



要素へのアクセス

リストの要素にアクセスするためには、以下のように角括弧で要素のインデックスを指定します。要素のインデックスは、0から始まります。

print(price[0])
print(all[1])
print(all[1][1])
120
['apple', 'orange', 'pinnaple', 'banana']
orange

numpy array

各要素を統一の型(float32, int, u32など)で格納する変数。厳密に型を意識して、行列やベクトルとして演算ができます。
以下のように、numpyライブラリをnpとしてインポートして、np.array(リスト)関数を用いて定義します。

import numpy as np
price = np.array([120,180,300,150])
fruit = np.array(["apple", "orange","pineapple","banana"])
all = np.array([price, fruit])

numpyで自動的に選択された型を、dtypeを用いて表示します。

print(price.dtype)
print(fruit.dtype)
print(all.dtype)
int32
<U9
<U11
numpy.arrayの大きさ

shapeを用いると、以下のようにnumpy.araryの形および大きさを求めることができます。

all.shape
(2, 4)

allは2行4列の配列になっているのがわかります.

スライス

numpy.arrayでは、スライスと呼ばれる操作で、 部分的に要素を抜き出すことができます。

price[0]  % 最初(0番目)の要素 120
price[-1] % 最後の要素 150
price[1:3] % 1番目から2番目までの要素 [180, 300]
price[:2] % 最初(0番目)から1番目までの要素 [120, 180]
数値演算

numpyのsum、mean、varおよびstd関数を用いると、和、平均、分散および標準偏差の計算ができます。

print(f"和={np.sum(price)}")
print(f"平均={np.mean(price)}")
print(f"分散={np.var(price)}")
print(f"標準偏差={np.std(price)}")
和=750
平均=187.5
分散=4668.75
標準偏差=68.32825184358224

なお、print関数では、以下のようにf文字列(f-strings)を用いて簡単に変数の値や数式の結果を文字列の中に挿入することができます。
具体的には、文字列の前にfを置き(f"xxx")、文字列中の中かっこのなかに変数や数式を置きます。

print(f"文字列{変数、計算式}文字列")

ソート

numpyのsort関数を用いると、データを昇順にソートすることができます。

np.sort(price)
array([120, 150, 180, 300])



pandas.DataFrame

データベース(またはエクセル)のテーブルのように、カラム名(列)とインデックスを割り振って各要素を格納する変数。エクセル(csv形式)のデータの読み書きが簡単にできるため、データ解析でよく使われます。
以下のように、pandasライブラリをpdとしてインポートして利用します。

import pandas as pd

Kaggleにより公開されているボストンの物件価格に関するデータ「House Prices: Advanced Regression Techniques」の訓練データhouse_prices_train.csvを、
jupyter notebookを起動したフォルダーにダウンロードし、DataFrameとして読み込んでみましょう。

data = pd.read_csv('house_prices_train.csv')

DataFrameのhead関数を用いて、読み込んだテーブルの5行目までを観てみましょう。

data.head()

f:id:hirotaka_hachiya:20190527095339p:plain

MSSubClass: 建物の等級
Street:道路へのアクセスの種類
LotFrontage: 間口の広さ
LotArea:敷地面積
PoolArea:プールの面積
MiscVal:その他の価値
MoSold:売れた月
YrSold:売れた年
SalePrice:販売価格(米ドル)

などに関するデータが表示されているのがわかります。

次にDataFrameのdesribe関数を用いて、販売価格SalePriceに関する基本的な統計量を計算してみましょう。

data['SalePrice'].describe()

f:id:hirotaka_hachiya:20190527101212p:plain

各統計量の定義は以下のようになっています。

count:データ総数
mean:平均値
std:標準偏差
min:最小値
25%:降順にソートし、下からデータ総数の25%の所にある値(25%点)
50%:同じく、下からデータ総数の50%の所にある値(中央値)
75%:同じく、下からデータ総数の75%の所にある値(75%点)
max:最大値

この基本統計量から、平均価格が約18万ドル(=約1900万円)、最低価格34900ドル(=約380万円)、最高価格が755000ドル(=約8200万円)および標準偏差が約8000ドル(=約870万円)となっており、様々な種類の物件(等級、敷地面積など)があるため、比較的バラツキが大きいことがわかります。

なお、建物の等級MSSubClassは、以下のように定義されています。

20 1-STORY 1946 & NEWER ALL STYLES
30 1-STORY 1945 & OLDER
40 1-STORY W/FINISHED ATTIC ALL AGES
45 1-1/2 STORY - UNFINISHED ALL AGES
50 1-1/2 STORY FINISHED ALL AGES
60 2-STORY 1946 & NEWER
70 2-STORY 1945 & OLDER
75 2-1/2 STORY ALL AGES
80 SPLIT OR MULTI-LEVEL
85 SPLIT FOYER
90 DUPLEX - ALL STYLES AND AGES
120 1-STORY PUD (Planned Unit Development) - 1946 & NEWER
150 1-1/2 STORY PUD - ALL AGES
160 2-STORY PUD - 1946 & NEWER
180 PUD - MULTILEVEL - INCL SPLIT LEV/FOYER
190 2 FAMILY CONVERSION - ALL STYLES AND AGES

今度は、MSSubClassが30(1階建て、1945年以前建設)の建物に限定してから、基本統計量を求めてみます。

data[data['MSSubClass']==30]['SalePrice'].describe()

f:id:hirotaka_hachiya:20190527111524p:plain
そうすると、平均価格は約9万ドル(=約980万円)まで半減し、標準偏差は約2500ドル(=約270万円)となりバラツキも減っていることがわかります。

DataFrameからnumpy.arrayへの変換

valuesを用いることにより、DataFrameのテーブルをnumpy.arrayに変換することができます。

data[['LotArea','SalePrice']].values

f:id:hirotaka_hachiya:20190527115622p:plain

演習1

1)建物の等級MSSubClassが60(2階建て、1946年以降)の建物の販売価格SalePriceの基本統計量を求めて、全体の統計量と比較してみましょう。
2)建物の等級MSSubClassが60(2階建て、1946年以降)の建物の販売価格SalePriceをnumpy.arrayに変換し、変数dataArrayに代入しましょう。
3)販売価格dataArrayの平均値、標準偏差を求め、1)の値と一致するか否か確認しましょう。
4)販売価格dataArrayを昇順にソートし、10番目(0番目から数えた場合)に高い物件の価格を求めましょう。
5)販売価格dataArrayのうち、30万ドル以上の物件の数を求めましょう。

scikit-learnを用いた機械学習(Pythonの基礎 3/4)>>