よくわかる!機械学習やデータ分析でよく使う Python ライブラリ|研修コースに参加してみた
今回参加したコースは よくわかる!機械学習やデータ分析でよく使う Python ライブラリ です。
機械学習やデータ分析が一般的になり、 Kaggle の問題をどのように解くのか、といった記事も見かけるようになりました。
が、その記事を読むと、 Python をちょっと知っていても、コードが全然わかりません。コードの中のコメントと記事の文章を読んで、わかった気になっているような私でしたが、今回のコースで NumPy 、 Matplotlib 、 Pandas のたった 3 つのライブラリを学んだだけでも、「コレ読める!」という感動体験ができました!
データ分析のコード、独特すぎて頭に入ってこない、という方にはとてもオススメです!
では、どのような内容だったのか、レポートします。
コース情報
想定している受講者 | Python について基本的な文法については習得ずみである。 |
---|---|
受講目標 |
|
講師紹介
講師は機械学習やデータ分析でご登場が増えている 植田崇靖 さんです。
IoT / AI から Web までフルスタックな開発経験をもとにした、幅広く実践的な研修コースを開発
以前にも AI 関連のコースでレポートしていますので、ぜひご覧ください。
機械学習 モデル の作り方と必要な基礎知識|研修コースに参加してみた
3 時間で学ぶ!AI・機械学習 入門 研修コースに参加してみた
G検定で学ぶ AI の体系と基礎知識 「オンライン」研修コースに参加してみた
「このコースを実務への一歩にしてもらえるとうれしい」とコメントされ、コースがスタートしました。
数理計算:NumPy
前段として、機械学習で使うライブラリ scikit-learn や、ディープラーニングで使う Tensorflow や pyTorch などを紹介いただきました。
そして、このコースでは数多あるライブラリの中でも、特によく使うものをピックアップし、それぞれ解説いただきながら、実際に触ってみます。なお、実行環境は Colaboratory を使用しました。
まず NumPy の概要です。
- Numerical Python の略
- 公式サイトいわく「 NumPy is the fundamental package for scientific computing in Python. 」
- 数理演算で利用する
- 行列、多次元配列の計算も扱える
- 素の Python でも多次元配列の演算はできたが、遅かった
- これを速くできるようにしたライブラリ
- 数値計算のためのメソッド・関数が豊富で、高速な演算が可能
- 行列演算や画像処理など様々な場面で使える
- 他の Pandas や scikit-learn などからも呼ばれる
主なクラスは「 np.ndarray 」と呼ばれる多次元を扱う配列です。
Python にもリストと配列がありますが、一般に処理速度が Java や C 言語に比べて遅くなります。 NumPy は C 言語で実装されていて、そのバイナリファイルを使って、 Python から呼び出せるようにしているので、高速に動作します。
ここから作成、参照、変更、計算、それぞれで使う様々な関数を試してみました。以降は抜粋しながら紹介します。
配列の作成
まず NumPy をインポートして、配列を作ってみましょう。
import numpy as np
x = np.array([1, 2, 3, 4]) # ndarray インスタンスを生成する
print(x)
print(type(x)) # 型
print(x.ndim) # 配列の次元
print(x.shape) # 配列の形状(各軸方向の大きさ)
# 出力結果
'''
[1 2 3 4]
<class 'numpy.ndarray'>
1
(4,)
'''
x を出力すると、 Python のリストに似た表記で出力されます。型は numpy.ndarray クラスです。
次元はもちろん 1 ですね。 4 要素の 1 次元配列なので、形状としては「 4 」が 1 つ入ったタプルが返ってきます。
続いて、 2 次元配列を作成してみます。
x = np.array([1, 2, 3, 4], ndim = 2) # ndim で次元を指定
print(x)
print(x.shape) # Colaboratory など notebook では変数名だけでも出力できる ex. x.T 。
'''
[[1 2 3 4]]
(1, 4)
'''
データが整数型と浮動小数点数型からなる場合、配列のすべての要素は浮動小数点数型になります。
様々な作成につかう関数
要素を指定して配列を作るだけでなく、その他にも初期化・任意の配列にするなど、様々な作成の関数があります。
- zeros: 値を 0 や 1 で埋める
- full: 任意の値で初期化する
- empty: 任意の配列をつくる
- zeros_like: ある配列に同じ形式の配列を作って、 0, 1 で埋める
- full_like: ある配列に同じ形式の配列を作って、任意の値で埋める
実務でよく使う特別な関数
ここでは、中身の値を初期化しない empty 関数を見てみます。値を初期化しないため、作成時間が短くなります。この例ぐらいではほぼ差はありませんが、巨大な配列を作る場合に有効だそうです。
x = np.empty((4, 3))
print(x)
'''
[[4.65620757e-310 0.00000000e+000 0.00000000e+000]
[0.00000000e+000 0.00000000e+000 0.00000000e+000]
[0.00000000e+000 0.00000000e+000 0.00000000e+000]
[0.00000000e+000 0.00000000e+000 0.00000000e+000]]
'''
要素の参照
続いて、配列の参照です。
NumPy の配列の要素は、 Python のリストなどと同様にスライシングができますが、 Python よりも柔軟に参照ができます。
x = np.arange(10)
x[:4] # : ですべてを指す。 array([0, 1, 2, 3])
# 多次元配列の参照。 カンマで区切って指定
x = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
x[1, 2] # 2 行目 3 列目の値。これだけ 0 スタートになる。 6
x[:, 2] # 3 列目すべての値。 array([3, 6, 9])
参照に配列を指定することもでき、複数の要素を取り出すこともできます。これを ファンシーインデックス といいます。
x = np.array([-1, 2, -3, 4])
print(x[[1, 3]]) # [2 4]
y = np.array([[1, 2, 3],[4, 5, 6]]) # 2 次元配列
print(y[[0, 1],[1, 2]]) # [2 6]
他にも様々な取り出し方があり、これはなかなか便利ですね。
配列の形状や大きさの変更
今度は配列の変更をする関数を見てみます。
reshape
reshape は、配列の形状を変更する関数です。
x = np.array([[1, 2],[3, 4]])
y = x.reshape(4) # 2次元配列 x を 4 要素の 1 次元配列 y に変更
print(y) # array([1, 2, 3, 4])
配列の連結 vstack と hstack
複数の配列を縦や横に 連結 する関数もあります。
- vstack 縦に連結
x = np.arange(4) # arange は Python の range のようなもの np.vstack((x, x, x)) # x を縦に 3 つ連結 ''' array([[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]) '''
- hstack 水平に連結
y = np.arange(4) np.hstack((y, y, y)) # y を水平に 3 つ連結 ''' array([0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]) '''
配列の入れ替え .T 属性
縦軸と横軸を入れ替える 転置 もでき、このとき .T 属性を使います。
x = np.arange(6).reshape(2, 3)
print(x.T)
'''
array([[0, 3],
[1, 4],
[2, 5]])
'''
配列の基本計算
最後に NumPy では配列を 行列 として計算できます。
# 足し算
x = np.array([[1, -1], [ 3, 2]])
y = np.array([[0, 1], [-2, 1]])
print(x + y)
'''
array([[1, 0],
[1, 3]])
'''
# 比較演算
x = np.array([1, 2, 3, 4])
y = np.array([4, 3, 2, 1])
z = x > y
print(z)
'''
array([False, False, True, True])
'''
ブロードキャスティング
配列の形状や型が異なる場合は、小さい方が大きい方の並列の形状に一致するように自動で拡大されます。これを ブロードキャスティング といいます。
x = np.array([[1, 2], [3, 4]])
y = np.array([[5, 6]])
print(x + y) # [5, 6] が行方向に自動で追加される
'''
array([[ 6, 8],
[ 8, 10]])
'''
ユニバーサル関数 ufunc
ユニバーサル関数で配列の要素ごとに処理を行えます。
x = np.arange(5)
# 平方根をとる
np.sqrt(x)
'''
array([0. , 1. , 1.41421356, 1.73205081, 2. ])
'''
行列の積
行列の積には @
演算子を使います。
A = np.array([[1, -2], [ 2, 0]])
B = np.array([[3, 4], [-1, -3]])
A @ B
'''
array([[ 5, 10],
[ 6, 8]])
'''
# Python で積を表す * 演算子は、NumPyでは行列の要素ごとの積となるので注意
A * B
'''
array([[ 3, -8],
[-2, 0]])
'''
その他にも紹介しきれないほど、様々な関数があり、 NumPy を使うとそれだけ様々な演算ができることが実感できました。たぶん NumPy だけで 3 日間ぐらいは研修できるボリュームがあるのでは … 。
グラフ描画:Matplotlib
NumPy に続き、頻出ライブラリの 2 つめは Matplotlib です。グラフを描画するライブラリですね。
- データを見やすく表示するだけでなく、データを処理するステップの一つでもある
- データの意味について直感的な理解が得られることが多い
- データの隠れた部分に光があたり分析者が適切なモデルを選択しやすくなる
- 2 次元のプロットが圧倒的に多い
- pyplot をインポートすることが多い
- グラフは Figure オブジェクトとその中にある 1 つ以上の Axes オブジェクトで構成
- Figure は図全体の描画領域
- Axes は 1 つのグラフを描く領域(座標系)
- Figure の引数でサイズや解像度などを指定できる
グラフなどのデータの可視化( data visualization )の必要性
Matplotlib
では、グラフを描画してみましょう。
import matplotlib.pyplot as plt
import numpy as np
# データ点の x 座標と y 座標の配列を作成
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
# Figureオブジェクトの作成
fig = plt.figure()
# Axis オブジェクトの追加
# 座標(0.15,0.1), 幅70%, 高さ80%
ax = fig.add_axes((0.15, 0.1, 0.7, 0.8))
# 折れ線グラフを描画
ax.plot(x, y)
描画されたグラフです。
その他にも NumPy の様々な配列データから以下のようなグラフが生成できます。
メソッド | 説明 |
---|---|
plot | 折れ線グラフ |
loglog | 両対数グラフ |
scatter | 散布図 |
bar | 縦棒グラフ |
errorbar | エラーバーグラフ |
hist | ヒストグラム |
pie | 円グラフ |
これもコースでは NumPy 同様に様々に作図しました。
データ分析でよく見る図が出てきたのですが、私の場合、それぞれの図がどんな場面で使って、どのような傾向をつかむのか、そこから始めなければなりません( loglog ってなにそれ美味しいの)。
データ処理:Pandas
最後に紹介されたのが Pandas です。データ解析の支援ライブラリです。
- スプレッドシートのようななデータを高速に読み込み、操作、整列、マージなどの処理が可能
- 公式サイトいわく「pandas is a fast, powerful, flexible and easy to use open source data analysis and manipulation tool, built on top of the Python programming language.」
データ処理という意味では NumPy も同じですが、次のような違いがあります。
- NumPy は数値データの多次元配列を処理する時に使用する
- Pandas は数値データ以外に文字列や時系列データなども扱える。データ集約やグループ演算などデータ操作処理に強い
つまり、 Pandas は、スプレッドシートやSQLのようにデータを処理したり表示したりできます。データを統計処理や機械学習にかける前の前処理などによく使われます。
データ型
Pandas には 2 つのデータ型があります。
- 行または列の 1 つを表現
- スプレッドシート全体を表現
- Seriesオブジェクトの辞書またはコレクションとしても取り扱える
Series シリーズ
DataFrame データフレーム
データ構造の作成
シリーズとデータフレームを作ってみます。
import pandas as pd
import numpy as np
# Series の作成
# 1 次元のデータを扱うデータ構造
# ランダムな数値を 5 つ Series に入れる
s = pd.Series(np.random.randn(5))
print(s)
'''
0 -0.858895
1 -0.817926
2 -1.809946
3 -0.820728
4 0.292306
dtype: float64
'''
# DataFrame の作成。シリーズを複数並べたようなもの
# 行と列を持つ表形式のデータ構造
np.random.seed(0)
df = pd.DataFrame(
np.random.randn(5, 3),
index=['a', 'b', 'c', 'd', 'e'], #行ラベルを指定
columns=['X', 'Y', 'Z'] #列ラベルを指定
)
print(df)
X | Y | Z | |
---|---|---|---|
a | 1.764052 | 0.400157 | 0.978738 |
b | 2.240893 | 1.867558 | -0.97728 |
c | 0.950088 | -0.15136 | -0.10322 |
d | 0.410599 | 0.144044 | 1.454274 |
e | 0.761038 | 0.121675 | 0.443863 |
head / tail データの表示
Pandas で大量のデータを用いることが多く、大量の行が表示されても画面が溢れてしまいます。このため、先頭の何行かを取り出す head や、末尾の何行かを取り出す tail があります。
np.random.seed(0)
df = pd.DataFrame(
np.random.randn(6, 3),
index=['a', 'b', 'c', 'd', 'e', 'f'],
columns=['X', 'Y', 'Z']
)
df.head(1) #先頭 1 行分のデータ表示
X | Y | Z | |
---|---|---|---|
a | 1.764052 | 0.400157 | 0.978738 |
統計量の表示
describe を使うと基本的な統計量をまとめて表示できます。
件数、算術平均、標準偏差、最小値、第 1 四分位数、中央値、第 3 四分位、最大値が表示されます。これは便利!
df.describe()
X | Y | Z | |
---|---|---|---|
count | 6.000000 | 6.000000 | 6.000000 |
mean | 1.076724 | 0.646026 | 0.265203 |
std | 0.766714 | 0.828799 | 0.878143 |
min | 0.333674 | -0.15136 | -0.97728 |
25% | 0.498208 | 0.127267 | -0.17967 |
50% | 0.855563 | 0.2721 | 0.170322 |
75% | 1.560561 | 1.220599 | 0.845019 |
max | 2.240893 | 1.867558 | 1.454274 |
DataFrame の参照
DataFrame の要素は、列ラベルや行ラベルを指定して参照できます。このあたりもスプレッシート風ですね。
df['X'] # X の列データを参照
'''
a 1.764052
b 2.240893
c 0.950088
d 0.410599
e 0.761038
f 0.333674
Name: X, dtype: float64
'''
df.at['a', 'X'] # 行と列を指定
'''
1.764052345967664
'''
この他にもソートやフィルタリングといった機能も試してみましたが、このあたりもスプレッドシートと同じような操作ですね。
基本的な演算
DataFrame とスカラ値や、 DataFrame と DataFrame は、NumPy の配列と同じように足し算ができます。ただし、 DataFrame 同士を足すときには、行数と列数が同じである必要があります。
df['X + Y'] = df['X'] + df['Y'] # X 列と Y 列を足した結果を X + Y 列に追加
print(df)
X | Y | Z | X + Y | |
---|---|---|---|---|
a | 1.764052 | 0.400157 | 0.978738 | 2.16421 |
b | 2.240893 | 1.867558 | -0.97728 | 4.108451 |
c | 0.950088 | -0.15136 | -0.10322 | 0.798731 |
d | 0.410599 | 0.144044 | 1.454274 | 0.554642 |
e | 0.761038 | 0.121675 | 0.443863 | 0.882713 |
f | 0.333674 | 1.494079 | -0.20516 | 1.827753 |
DataFrame の結合 concat
concat を使えば DataFrame の結合もできます。デフォルトでは縦方向に結合します。
df1 = pd.DataFrame({'X': [1, 2, 3], 'Y': [-1, -2, -3]},
index=['a', 'b', 'c'])
df2 = pd.DataFrame({'X': [4, 5, 6], 'Y': [-4, -5, -6]},
index=['d', 'e', 'f'])
pd.concat([df1, df2])
X | Y | |
---|---|---|
a | 1 | -1 |
b | 2 | -2 |
c | 3 | -3 |
d | 4 | -4 |
e | 5 | -5 |
f | 6 | -6 |
この他にも横結合や SQL の JOIN のような merge なども試しました。
Matplotlib を組み合わせて使う
もう一つスプレッドシート風な機能として、 DataFrame からグラフを作成します。 Matplotlib を使います。
import matplotlib.pyplot as plt
#正規分布のデータ
df = pd.DataFrame({
'a': np.random.randn(1000),
'b': np.random.normal(2, 0.8, 1000),
'c': np.random.normal(4, 1.0, 1000),
'd': np.random.normal(6, 1.2, 1000)
})
df.plot(kind="hist", alpha=0.5, bins=30) # kindでグラフの種類 ( hist はヒストグラム) を指定できる
そのほか、画像処理のライブラリ pillow や OpenCV についても紹介いただいたところで、このコースは修了しました。
まとめ
このコースでは機械学習やデータ分析でよく使うライブラリ、 NumPy 、 Matplotlib 、 Pandas を実際、使ってみました。
私はそもそもこういった計算処理をプログラミング言語でしてこなかった人生だったので、とても新鮮で、プログラムを書いていると言うより、数学の計算問題を解いている感覚でした。また触ってみると、データサイエンスをする上では便利機能がたくさんあり、これが Python のエコシステムかと実感できました。
今回は機械学習でよく使うライブラリで色々操作しましたが、今度は課題をもとに、どのようにライブラリを使いながら、データサイエンスを行うのか、やってみたいです! … と、思うんだったら、やればいいじゃんと思ったので、試しにググってみると、いいものがありました!
実践データサイエンス─サンプルコードと図表で学ぶ、前処理・モデル評価・パラメータチューニング – エンジニアHub|Webエンジニアのキャリアを考える!
見事に NumPy 、 Matplotlib 、 Pandas を使っていて、コースで学んだことで、実際に行っている処理の流れもある程度、わかりました!
データ分析のコードが読めない、何をしているのかなんとなくでしかわからない、という方にはとてもオススメです!
label SEカレッジを詳しく知りたいという方はこちらから !!
IT専門の定額制研修 月額28,000円 ~/ 1社 で IT研修 制度を導入できます。
年間 670 コースをほぼ毎日開催中!!
SEプラスにしかないコンテンツや、研修サービスの運営情報を発信しています。