kakakakakku blog

Weekly Tech Blog: Keep on Learning!

Jamboard のフレーム背景にテンプレート画像を設定して効率的に描く Tips

Jamboard でホワイトボードを描くときによく使っている Tips を紹介する.と言っても本当に「ちょっとした Tips」で,簡単に言うと「Jamboard のフレーム背景にテンプレート画像を設定して効率的に描く」という Tips 🎨 以上!

f:id:kakku22:20210609112939p:plain

テンプレート画像とは 🎨

もう少し整理しておく.例えば「リモート研修」を何度も担当していると「毎回同じ構成で」ホワイトボードを描くことがある.例えば「比較表」「アーキテクチャ図」を書く場合で,最初から書くのは面倒だし,その場で書く時間も無駄になるけど,重要なところは描きながら説明したいこともある.まぁホワイトボードに描かずに PowerPoint のアニメーションを使えば十分なこともある.それはそれとして!

そこで💡PowerPoint や Keynote などを使って「テンプレート画像」を作って Jamboard のフレーム背景に設定しておくと,重要なところを効率的に描けるし,描き直すときは「フレームを消去」ボタンを押せば解決する.以下はブログ用のサンプルとして載せておく.

f:id:kakku22:20210609122328p:plain
サンプル : A と B と C の機能比較をする

f:id:kakku22:20210609122348p:plain
サンプル : A と B の関係性を整理する

iPad Air + Apple Pencil + Jamboard 🎨

実際に描くと以下のようになる.便利!なお,最近 iPad AirApple Pencil を買って快適にホワイトボードを描けるようになった.

f:id:kakku22:20210610085200j:plain

まとめ 🎨

ホワイトボードを効率的に描くために「Jamboard のフレーム背景にテンプレート画像を設定する」という Tips を紹介した.あまりに普通すぎて今までブログに書いてなかったけど,最近社内で紹介する機会があり,まとめておくことにした.Public URL-ize!

なお iPad AirApple Pencil を買うまでは安く買える Elemiya を使ってて満足していたけど,やはり Apple Pencil はレベルが違った!

kakakakakku.hatenablog.com

NumPy / Pandas / Matplotlib / scikit-learn などの理解度確認ができる「Python 3 エンジニア認定データ分析試験」に合格した

先週末に「Python 3 エンジニア認定データ分析試験」を受験して合格した🎉とても良い試験で,特に試験勉強をする過程で知識の幅が広がった.試験の認知度向上のためにも紹介したいと思う.当然ながら試験問題に関しては何も書かず,基本的に公開情報をベースにまとめていく!

www.pythonic-exam.com

試験概要 : Python 3 エンジニア認定データ分析試験 📊

試験名にもある通り「Python 3 エンジニア認定データ分析試験」は Python を使った「データ分析」に関する理解を問う試験で「数学」「Python ライブラリ」に関する出題が多くある.詳しくは以下に出題範囲を載せる.

セクション 出題数 出題率
データエンジニアの役割 2 5.0%
Python と環境 : 実行環境構築 1 2.5%
Python と環境 : Python の基礎 3 7.5%
Python と環境 : Jupyter Notebook 1 2.5%
数学の基礎 : 数式を読むための基礎知識 1 2.5%
数学の基礎 : 線形代数 2 5.0%
数学の基礎 : 基礎解析 1 2.5%
数学の基礎 : 確率と統計 2 5.0%
ライブラリによる分析実践 : NumPy 6 15.0%
ライブラリによる分析実践 : pandas 7 17.5%
ライブラリによる分析実践 : Matplotlib 6 15.0%
ライブラリによる分析実践 : scikit-learn 8 20.0%
応用 : データ収集と加工 0 0.0%

出題は「40問」で合格ラインは「70%」なので,単純計算で「28問」以上で合格になる.上記の通り「出題数」も明確なので対策自体はしやすいと思う.出題範囲をザッと分割すると以下のようになる.とにかく「ライブラリによる分析実践」の比重が高く,確実に理解を深めておく必要がある.とは言え,本質的に重要なのは試験に合格することよりも「学んだ知識を実務に活かすこと」であるため,バランス良く全体を勉強することを意識した.

  • データエンジニアの役割 : 2問(5.0%)
  • Python と環境 : 5問(12.5%)
  • 数学の基礎 : 6問(15.0%)
  • ライブラリによる分析実践 : 27問(67.5%)

関連試験 : Python 3 エンジニア認定基礎試験 📊

なお,関連する試験に「Python 3 エンジニア認定基礎試験」もある.同じく「一般社団法人 Python エンジニア育成推進協会」から提供されている.僕自身は2019年に合格して以下の記事にまとめている.「Python 3 エンジニア認定データ分析試験」の受験前提にはなっていないと思うけど,そもそも Python 自体に慣れていない場合は理解度確認も兼ねて,先に「Python 3 エンジニア認定基礎試験」を受験すると良さそう.

kakakakakku.hatenablog.com

受験結果 📊

僕自身の受験結果としては「900点(1000点満点)」だった.4問も間違えてしまった!楽勝だと思っていた「Python と環境」を間違えてしまったのは逆に笑ってしまった😇逆に「数学の基礎」「ライブラリによる分析実践」は自信を持って回答できてほぼ満点だったため,結果としては満足している!なお,時間配分としては「1周目 : 30分」「2周目 : 20分」で,十分に見直しもできたため,少し時間を残して退出した.特に計算用紙などは配布されないため,各種計算は頭で考える必要がある点は注意が必要かも!

主教材 : Python によるあたらしいデータ分析の教科書 📊

本試験は主教材として「Python によるあたらしいデータ分析の教科書」が指定されていて,本書の構成通りに出題されるため,基本的に本書をベースに勉強をしていく形になる.とは言え,教科書ではなく「主教材」なので,本試験を受験しないとしても,機械学習や機械学習に関連する Python ライブラリに興味があれば「Python によるあたらしいデータ分析の教科書」を読んでみると良いと思う.具体例や図解やコードサンプルもあり,専門用語も多くなく,非常に読みやすく書かれている.目次も載せておくけど出題範囲と同じで,例えば「第5章」など,試験には出題されない範囲の内容も載っている.

  • 第1章「データ分析エンジニアの役割」
    • 1.1 データ分析の世界
    • 1.2 機械学習の位置づけと流れ
    • 1.3 データ分析に使う主なパッケージ
  • 第2章「Pythonと環境」
    • 2.1 実行環境構築
    • 2.2 Pythonの基礎
    • 2.3 Jupyter Notebook
  • 第3章「数学の基礎」
    • 3.1 数式を読むための基礎知識
    • 3.2 線形代数
    • 3.3 基礎解析
    • 3.4 確率と統計
  • 第4章「ライブラリによる分析の実践」
    • 4.1 NumPy
    • 4.2 pandas
    • 4.3 Matplotlib
    • 4.4 scikit-learn
  • 第5章「応用 : データ収集と加工」
    • 5.1 スクレイピング
    • 5.2 自然言語の処理
    • 5.3 画像データの処理

なお,本書の正誤表は以下に載っている.現在は「5刷」まで出ている.

www.shoeisha.co.jp

数学の基礎 📊

数学に関しては「Python によるあたらしいデータ分析の教科書」の内容を細かく整理すると,例えば「ベクトル計算(内積/ユークリッド距離/マンハッタン距離)」「基礎解析(微分/積分/偏微分)」「確率」などを理解しておく必要がある.特に勉強をしなくても大丈夫な人もいるだろうし,基本的なところから勉強をし直す必要がある人もいると思う.僕自身は学生時代に学んだはずではあるものの,最近使うことも少なく,パッと計算できないものもあったため,「Python によるあたらしいデータ分析の教科書」を読みつつ,YouTube や Cognicull などを使って勉強をし直した.

cognicull.com

ライブラリによる分析実践 (NumPy / Pandas / Matplotlib) 📊

NumPy / Pandas / Matplotlib に関しては,多種多様な関数(パラメータやデフォルトの挙動など)を理解しておく必要があり,出題範囲は多いと思う.無理に暗記をするのではなく,何度も実装をしたり,ドキュメントを読んだり,納得できるまで理解を深めていく必要があると思う.今回は Jupyter Notebook を使って,気になる関数を試した.特に Numpy「配列計算」「行列計算」をするため,数学的な基礎知識も必要になる.実際に以下の記事は理解を深めるために書いた.

また Pandas に関しては「Pandas ライブラリ活用入門」も読んで書評記事を書いた.関連書籍も併読するとより理解が深まる.

kakakakakku.hatenablog.com

ライブラリによる分析実践 (scikit-learn) 📊

scikit-learn に関しては,ライブラリを使う前に「数学的な基礎知識」「機械学習アルゴリズムの知識」「機械学習プロセスの知識」も必要になる.「Python によるあたらしいデータ分析の教科書」にはコードやアルゴリズムの図解も載っていてわかりやすいけど,それでも理解しにくいところもあった(実際に僕自身がそう感じた).なお,以下に目次「4.4 scikit-learn」の詳細をまとめる.理解するべき知識の幅広さが伝わると思う.

  • 4.4 scikit-learn
    • 4.1.1 前処理
      • 欠損値への対応
      • カテゴリ変数のエンコーディング
      • 特徴量の正規化
    • 4.1.2 分類
      • サポートベクタマシン
      • 決定木
      • ランダムフォレスト
    • 4.1.3 回帰
      • 線形回帰
    • 4.1.4 次元削減
      • 主成分分析
    • 4.1.5 モデルの評価
      • 混同行列(適合率/再現率/F値/正解率)
      • 交差検証
    • 4.1.6 ハイパーパラメータの最適化
      • グリッドサーチ
      • ランダムサーチ
    • 4.1.7 クラスタリング
      • k-means
      • 階層的クラスタリング

そこで今回は「機械学習図鑑」を併読した.数式をあまり使わずに scikit-learn のコードと図解で「機械学習アルゴリズム」を理解できるため,とても役立った.「Python 3 エンジニア認定データ分析試験」を受験する人には併読をおすすめする.

模擬問題(無料)📊

「Python 3 エンジニア認定データ分析試験」には大きく模擬試験が2種類あり「PRIME STUDY」「DIVE INTO EXAM」から提供されている.無料で何度でも繰り返し受験できるため,理解度確認の意味も兼ねて定期的に受験してみると良いと思う.個人的なアドバイスとしては「全ての選択肢まで細かく理解できるように」しておくと良いと思う.

  • PRIME STUDY
    • Python 3 エンジニア認定データ分析 模擬試験 第1回
    • Python 3 エンジニア認定データ分析 模擬試験 第2回(第1回と選択肢が少し異なる)
    • Python 3 エンジニア認定データ分析 模擬試験 第3回(第1回と選択肢が少し異なる)
  • DIVE INTO EXAM
    • Python3 エンジニア認定データ分析 模擬試験

まとめ 📊

前から気になっていた「Python 3 エンジニア認定データ分析試験」を受験して合格した🎉もともと機械学習領域に詳しくなかったため,本を読んだり,e-Learning を受講したり,Jupyter Notebook を使って何度も繰り返し実装したりして,試験勉強をする過程で知識の幅を広げることができた.特に Python ライブラリ(NumPy / Pandas / Matplotlib / scikit-learn)には詳しくなった.とても良い試験なので,興味がある人は受けてみると良いのではないでしょうか!

Numpy の dot() 関数は引数によって「ドット積(内積)」や「行列積」の計算になる

Numpydot() 関数を使うと配列同士の「ドット積(内積)」を計算できる.詳しくはドキュメントに載っているけど,dot() 関数は引数 ab に指定する値(1次元配列/2次元配列)によって挙動が異なる.個人的にわかりにくかったため,具体的に実装しながら整理することにした.またドキュメントには dot() 関数以外を使うべきシナリオもあり代替案も載っている.

numpy.org

1. ドット積(内積)🔡

まず,ab のどちらにも「1次元配列(ベクトル)」を指定すると,ベクトルの「ドット積(内積)」を計算できる.ドキュメントには以下のように載っている.

If both a and b are 1-D arrays, it is inner product of vectors (without complex conjugation).

なお,そもそも「ドット積(内積)」とはザッと表現するなら以下のような計算式になり,各ベクトルの要素を掛け算した総和となる.詳しくは Cognicull などの参考サイトを見てもらえればと!


  \sum\limits_{i=1}^n a_i b_i \

さっそく dot() 関数を試す.以下のように「1次元配列」「1次元配列」を指定すると,期待通りに「ドット積(内積)」を計算できる.それぞれ (1x3) + (2x4) = 11(1x4) + (2x5) + (3x6) = 32 となる.

a = np.array([1, 2])
b = np.array([3, 4])
np.dot(a, b)
# 11

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
np.dot(a, b)
# 32

f:id:kakku22:20210531092812p:plain

なお,以下のように要素数(ベクトルの次元数)が異なるとエラーになる.

a = np.array([1, 2, 3])
b = np.array([4, 5, 6, 7])
np.dot(a, b)
# ValueError: shapes (3,) and (4,) not aligned: 3 (dim 0) != 4 (dim 0)

f:id:kakku22:20210531092837p:plain

2. 行列積 🔡

次に ab のどちらにも「2次元配列(行列)」を指定すると「ドット積(内積)」ではなく「行列積」を計算できる.ドキュメントには以下のように載っている.そして「行列積」を計算するなら dot() 関数よりも matmul() 関数や Numpy@ 演算子を使うべし!とも載っている.

If both a and b are 2-D arrays, it is matrix multiplication, but using matmul or a @ b is preferred.

「行列積」とはザッと表現するなら以下のような計算式になり,行列同士を掛け算した結果となる.詳しくは Cognicull などの参考サイトに載っている「行列積」の図解を見てもらえればと!


  \begin{pmatrix}
    a & b \\
    c & d
  \end{pmatrix}
  \begin{pmatrix}
    e & f \\
    g & h
  \end{pmatrix}
  =
  \begin{pmatrix}
    ae + bg & af + bh \\
    ce + dg & cf + dh
  \end{pmatrix}

さっそく dot() 関数と matmul() 関数と @ 演算子 を試す.以下のように「2次元配列」「2次元配列」を指定すると,期待通りに「行列積」を計算できる.以下には (2, 2) x (2, 2)(3, 3) x (3, 3) の例を載せた.また列数(横)と行数(縦)が一致していれば「行列積」を計算できるため (3, 2) x (2, 2) の例も載せた.そして mutmul() 関数や @ 演算子を使っても同じ結果になっている.

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
np.dot(a, b)
# array([[19, 22],
#        [43, 50]])

np.matmul(a, b)
# array([[19, 22],
#        [43, 50]])

a@b
# array([[19, 22],
#        [43, 50]])

a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
b = np.array([[10, 11, 12], [13, 14, 15], [16, 17, 18]])
np.dot(a, b)
# array([[ 84,  90,  96],
#        [201, 216, 231],
#        [318, 342, 366]])

np.matmul(a, b)
# array([[ 84,  90,  96],
#        [201, 216, 231],
#        [318, 342, 366]])

a@b
# array([[ 84,  90,  96],
#        [201, 216, 231],
#        [318, 342, 366]])

a = np.array([[1, 2], [3, 4], [5, 6]])
b = np.array([[7, 8], [9, 10]])
np.dot(a, b)
# array([[ 25,  28],
#        [ 57,  64],
#        [ 89, 100]])

np.matmul(a, b)
# array([[ 25,  28],
#        [ 57,  64],
#        [ 89, 100]])

a@b
# array([[ 25,  28],
#        [ 57,  64],
#        [ 89, 100]])

f:id:kakku22:20210531092950p:plain

なお,以下の (2, 3) x (2, 2) のように,列数(横)と行数(縦)が一致していない場合はエラーになる.

a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([[7, 8], [9, 10]])
np.dot(a, b)
# ValueError: shapes (2,3) and (2,2) not aligned: 3 (dim 1) != 2 (dim 0)

np.matmul(a, b)
# ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 2 is different from 3)

a@b
# ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 2 is different from 3)

f:id:kakku22:20210531093115p:plain

まとめ 🔡

Numpydot() 関数の挙動を整理するために試した.引数 ab に指定する値(1次元配列/2次元配列)によって「ドット積(内積)」「行列積」の計算になることを確認できた(正確には他の計算パターンもある).またドキュメントには dot() 関数以外を使うべきシナリオもあり代替案も載っているため,特に「行列積」の場合は matmul() 関数や Numpy@ 演算子を使うことを覚えておこう!

numpy.org

関連記事

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

Pandas で時系列データをグループ化して集計できる「Grouper」

Pandasgroupby() 関数を使うと,データセットをグループ化して集計できる.さらに Grouper オブジェクトと組み合わせると,より高機能なグループ化を実現できる.今回は groupby() 関数と Grouper オブジェクトを組み合わせて「時系列データの集計」を試す.最後に関連する resample() 関数も試す.

データセット 🪢

今回使うサンプルデータセットを準備する.まず,Pandas の date_range() 関数を使って 2020/1/1 ~ 2020/12/31 の範囲で1年間の DatetimeIndex を作る.そして DatetimeIndex をインデックス値とした DataFrame を作る.今回は count カラムとして 1 ~ 99 の範囲で乱数を含めておく.乱数は Numpyrandom.randint() 関数を使う.結果的に以下のような DataFrame になる.

dates = pd.date_range(start='2020-01-01', end='2020-12-31')
dates
# DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04',
#                '2020-01-05', '2020-01-06', '2020-01-07', '2020-01-08',
#                '2020-01-09', '2020-01-10',
#                ...
#                '2020-12-22', '2020-12-23', '2020-12-24', '2020-12-25',
#                '2020-12-26', '2020-12-27', '2020-12-28', '2020-12-29',
#                '2020-12-30', '2020-12-31'],
#               dtype='datetime64[ns]', length=366, freq='D')

df = pd.DataFrame(np.random.randint(1, 100, 366), index=dates, columns=['count'])
df
# 2020-01-01   13
# 2020-01-02   50
# 2020-01-03   44
# 2020-01-04   12
# 2020-01-05   25
# 2020-01-06   82
# 2020-01-07   4
# 2020-01-08   2
# 2020-01-09   27
# 2020-01-10   38
# (中略)

f:id:kakku22:20210511124750p:plain

groupby() 関数と Grouper オブジェクトを組み合わせる 🪢

以下のように DataFrame に対して groupby() 関数と Grouper オブジェクトを組み合わせる.まず pd.Grouper(freq='M')pd.Grouper(freq='Q') を試す.M「月末集計」Q「四半期集計」となる.そして今回は mean() 関数を使って「平均値」を取得する.このように Grouper オブジェクト を使うと簡単に「時系列データの集計」を実現できる.

  • M : month end frequency
  • Q : quarter end frequency
# month end frequency
df.groupby(pd.Grouper(freq='M')).mean()
# 2020-01-31   40.096774
# 2020-02-29   47.655172
# 2020-03-31   46.064516
# 2020-04-30   54.766667
# 2020-05-31   54.354839
# 2020-06-30   49.100000
# 2020-07-31   57.000000
# 2020-08-31   46.387097
# 2020-09-30   41.333333
# 2020-10-31   36.967742
# 2020-11-30   40.266667
# 2020-12-31   57.645161

# quarter end frequency
df.groupby(pd.Grouper(freq='Q')).mean()
# 2020-03-31   44.538462
# 2020-06-30   52.758242
# 2020-09-30   48.315217
# 2020-12-31   45.010870

f:id:kakku22:20210511125429p:plain

また以下のドキュメント(DateOffset objectsOffset aliasesAnchored offsets)を読むと freq に指定できる識別子は他にも多くある.代表的な例を以下に抜粋した.

  • W : weekly frequency
  • SM : semi-month end frequency (15th and end of month)
  • H : hourly frequency
  • W-SUN : weekly frequency (Sundays). Same as ‘W’
  • W-MON : weekly frequency (Mondays)
  • W-TUE : weekly frequency (Tuesdays)
  • etc

pandas.pydata.org

例えば pd.Grouper(freq='W-MON') を指定すると「週次集計」で軸にする「曜日(ここでは月曜日)」を指定できる.デフォルトでは WW-SUN となる.正確に値を計算すると 2020/1/13 (月)32.4285712020/1/7 (火) ~ 2020/1/13 (月) の期間での平均値となるため,計算式としては (4 + 2 + 27 + 38 + 23 + 62 + 71) / 7 = 32.428571 として確認できる.

# weekly frequency (Mondays)
df.groupby(pd.Grouper(freq='W-MON')).mean()
# 2020-01-06   37.666667
# 2020-01-13   32.428571
# 2020-01-20   47.142857
# 2020-01-27   35.714286
# 2020-02-03   37.571429
# 2020-02-10   66.000000
# 2020-02-17   43.285714
# 2020-02-24   48.000000
# (中略)

f:id:kakku22:20210511130035p:plain

Grouper オブジェクトの key パラメータ 🪢

デフォルトの挙動では DataFrame のインデックス値が DatetimeIndexTimedeltaIndex である必要があるため,それ以外の DataFrame だと TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex, but got an instance of 'RangeIndex' というエラーが出る.その場合は Grouper オブジェクトの key パラメータを使ってカラムを指定する.

動作確認をするために以下のようなサンプルデータセットを準備する.DataFrame のインデックス値は 0,1,2 ... という数値とし,date カラムに日付を含める.そして pd.Grouper(key='date', freq='M') のように key パラメータを指定すると,期待した平均値となった.

df = pd.DataFrame(
    [
        {'date': pd.Timestamp('2020-01-01'), 'counter': 1},
        {'date': pd.Timestamp('2020-01-02'), 'counter': 2},
        {'date': pd.Timestamp('2020-01-03'), 'counter': 3},
        {'date': pd.Timestamp('2020-02-01'), 'counter': 4},
        {'date': pd.Timestamp('2020-02-02'), 'counter': 5},
        {'date': pd.Timestamp('2020-02-03'), 'counter': 6}
    ]
)
df
# 0    2020-01-01  1
# 1    2020-01-02  2
# 2    2020-01-03  3
# 3    2020-02-01  4
# 4    2020-02-02  5
# 5    2020-02-03  6

df.groupby(pd.Grouper(key='date', freq='M')).mean()
# 2020-01-31   2
# 2020-02-29   5

f:id:kakku22:20210511132345p:plain

関連する resample() 関数も試す 🪢

Pandas のドキュメントを読むと,resample() 関数を使った「時系列データの集計」の例も載っていた.最近読んだ「Pandas ライブラリ活用入門」にも resample() 関数の例が載っていた.

実際に試したところ,Grouper オブジェクトと同じような集計ができた.例えば,以下は同じデータセットに対して「月末集計」をした結果で,平均値は完全に一致していた.また on パラメータを使ってカラムを指定することもできる.今回試した範囲だと Grouper オブジェクトと resample() 関数の機能面での差は確認できなかった.どう使い分けるんだろう?

df.resample('M').mean()
# 2020-01-31   40.096774
# 2020-02-29   47.655172
# 2020-03-31   46.064516
# 2020-04-30   54.766667
# 2020-05-31   54.354839
# 2020-06-30   49.100000
# 2020-07-31   57.000000
# 2020-08-31   46.387097
# 2020-09-30   41.333333
# 2020-10-31   36.967742
# 2020-11-30   40.266667
# 2020-12-31   57.645161

df.resample('Q').mean()
df.resample('W-MON').mean()
df.resample(on='date', rule='M').mean()

f:id:kakku22:20210511132840p:plain

まとめ 🪢

今回は Pandasgroupby() 関数と Grouper オブジェクトを組み合わせて「時系列データの集計」を試した.「月末集計」「四半期集計」そして「週集計」など高機能なグループ化を実現できる.引き続き気になった機能はどんどん試していくぞー👏

関連記事

kakakakakku.hatenablog.com

NumPy で「単位行列」を生成できる identity() 関数と eye() 関数の違い

NumPy「単位行列」を生成するときに identity() 関数と eye() 関数がサポートされている.それぞれの違いを整理するためにドキュメントを読みながら試してみた.今回は Numpy 1.20.2 を前提にする.ドキュメントには (almost) equivalent function と書いてあってほぼ同じ機能だけど,簡単に言えば identity() 関数はとてもシンプルで eye() 関数では一部パラメータを指定できる自由度がある.

なお「単位行列」とは,以下のように斜めの値(対角成分)が全て 1 の行列のことで,どんな行列との内積も行列の値が変化しないため,数字の 1 のような性質を持った行列と言える.行列は「はてな記法一覧」の TeX 記法 [tex:] を使っている.


  \left(
    \begin{array}{ccc}
      1 & 0 & 0 \\
      0 & 1 & 0 \\
      0 & 0 & 1
    \end{array}
  \right)

identity 関数を試す 🔢

まず,identity() 関数を試す.identity() 関数はシンプルで,引数に指定したサイズの「正方行列」「単位行列」を生成する.サンプルとして identity(3)identity(5) を載せておく.

import numpy as np

np.identity(3)
# array([[1., 0., 0.],
#        [0., 1., 0.],
#        [0., 0., 1.]])

np.identity(5)
# array([[1., 0., 0., 0., 0.],
#        [0., 1., 0., 0., 0.],
#        [0., 0., 1., 0., 0.],
#        [0., 0., 0., 1., 0.],
#        [0., 0., 0., 0., 1.]])

f:id:kakku22:20210510150823p:plain

配列の中に含まれている数値はデフォルトでは float64 型になる.identity() 関数に dtype パラメータを指定すると型を変えられるため,以下は int を指定した.実際には int64 型になった.

np.identity(3).dtype
# dtype('float64')

np.identity(5, dtype=int)
# array([[1, 0, 0, 0, 0],
#        [0, 1, 0, 0, 0],
#        [0, 0, 1, 0, 0],
#        [0, 0, 0, 1, 0],
#        [0, 0, 0, 0, 1]])

np.identity(5, dtype=int).dtype
# dtype('int64')

f:id:kakku22:20210510151151p:plain

eye() 関数を試す 🔢

次に eye() 関数を試す.基本的には identity() 関数と同じで,引数に指定したサイズの「正方行列」「単位行列」を生成する.サンプルとして eye(3)eye(5) を載せておく.

np.eye(3)
# array([[1., 0., 0.],
#        [0., 1., 0.],
#        [0., 0., 1.]])

np.eye(5)
# array([[1., 0., 0., 0., 0.],
#        [0., 1., 0., 0., 0.],
#        [0., 0., 1., 0., 0.],
#        [0., 0., 0., 1., 0.],
#        [0., 0., 0., 0., 1.]])

f:id:kakku22:20210510151543p:plain

配列の中に含まれている数値もデフォルトでは float64 型で同じ.eye() 関数の dtype パラメータに int を指定すると,同じく int64 型になる.ここまでは特に違いはなかった.

np.eye(3).dtype
# dtype('float64')

np.eye(3, dtype=int)
# array([[1, 0, 0],
#        [0, 1, 0],
#        [0, 0, 1]])

np.eye(3, dtype=int).dtype
# dtype('int64')

f:id:kakku22:20210510151647p:plain

identity() 関数との違いとして,eye() 関数では k プロパティがサポートされている.k プロパティを指定すると,以下のように値が 1 になる軸を上下にズラすことができる.以下はサンプルとして k=1k=-1 の例を載せている.実務上だと k プロパティをどういう場面で使うんだろう?

他にも eye() 関数には M プロパティ(列数を指定して正方行列ではない単位行列を生成する)など,いくつかのプロパティがある.

np.eye(5, k=1)
# array([[0., 1., 0., 0., 0.],
#        [0., 0., 1., 0., 0.],
#        [0., 0., 0., 1., 0.],
#        [0., 0., 0., 0., 1.],
#        [0., 0., 0., 0., 0.]])

np.eye(5, k=-1)
# array([[0., 0., 0., 0., 0.],
#        [1., 0., 0., 0., 0.],
#        [0., 1., 0., 0., 0.],
#        [0., 0., 1., 0., 0.],
#        [0., 0., 0., 1., 0.]])

f:id:kakku22:20210510151956p:plain

まとめ 🔢

最近は NumPy を学んでいる.今回は NumPy「単位行列」を生成できる identity() 関数と eye() 関数を試しつつ,機能の違いも確認した.ドキュメントには (almost) equivalent function と書いてあるけど,eye() 関数の方が指定できるパラメータが多くある.

関連記事 🔢

kakakakakku.hatenablog.com