3-3 外部ライブラリを使ってみよう
Game_Battle.pyにてimport文でライブラリを呼び出して関数を使いました.Pythonの良さはその拡張性の高さでもあります.別の章で紹介しますが,著名なライブラリであるNumpyやMatplotlibも使用するにはimportでライブラリ使用することを宣言します.ここではimport文を必要とする外部ライブラリを幾つか紹介します.
math
名前から分かるように数学系のライブラリです.例えば,以下のような関数があります.研究レベルでは多用することでしょう.使い方はエクセルの関数と何ら変わりはありません.
math.exp(x)
任意の数値xの指数を返します.
任意の数値xの指数を返します.
math.log(x[, base])
引数が1つの場合、xの (eを底とする)自然対数を返します.
引数が2つの場合、log(x)/log(base) として求められる base を底とした x の対数を返します.
引数が1つの場合、xの (eを底とする)自然対数を返します.
引数が2つの場合、log(x)/log(base) として求められる base を底とした x の対数を返します.
math.pow(x, y)
xのy乗を返します.
xのy乗を返します.
math.sqrt(x)
xの平方根を返します.
xの平方根を返します.
math.acosh(x)
xの逆双曲線余弦を返します.
xの逆双曲線余弦を返します.
math.floor(x)
xの切り下げた値を返す床関数です.
xの切り下げた値を返す床関数です.
math.ceil(x)
xの切り上げた値を返す天井関数です.
xの切り上げた値を返す天井関数です.
random
このライブラリは名前の通り乱数生成を行う際に使用するものです.今流行のAIなどには必須のライブラリになります.さらに,プログラムがいかなる数値でも正しい出力を行うかを確認する際にも活用できます.
random. randrange(start, stop[, step])
半閉区間[start..stop)の範囲で整数を返します.stepを指定すれば,生成範囲における間隔を指定可能です.
半閉区間[start..stop)の範囲で整数を返します.stepを指定すれば,生成範囲における間隔を指定可能です.
randrange の性質
- import random
- for i in range(10):
- print(random.randrange(0,10,2))
- print(random.randrange(0,10))
-
出力
0,2,4,4,4,6,8,8,0,0 6,6,9,4,7,1,8,9,5,9
random.randint(a, b)
[a..b]の範囲でランダムな整数を返します.
[a..b]の範囲でランダムな整数を返します.
random.random( )
[0,1)の範囲でランダムな浮動小数点数を返します.
[0,1)の範囲でランダムな浮動小数点数を返します.
random.uniform(a,b)
[a,b]の範囲でランダムな浮動小数点数を返します.
[a,b]の範囲でランダムな浮動小数点数を返します.
random.seed(a = None [,integer])
aが省略された場合には現在のシステム時刻を基礎に乱数生成器を初期化します.
整数Integerが使用された場合,Integerに沿った乱数が生成されます.
aが省略された場合には現在のシステム時刻を基礎に乱数生成器を初期化します.
整数Integerが使用された場合,Integerに沿った乱数が生成されます.
random.seedの性質
- import random
- random.seed( )
- for i in range(3):
- print(random.randint(1,5))
- for i in range(3):
- print(random.randint(1,5))
-
- random.seed(1)
- for i in range(3):
- print(random.randint(1,5))
-
- random.seed(1)
- for i in range(3):
- print(random.randint(1,5))
-
4,5,2 1,2,4 2,5,1 2,5,1
random.seedは重要なので別途解説しておきます.Seedは名前の通り乱数生成器の種を意味しています.乱数生成器とは言え,乱数列を最初に作成してそこから数字を順番に引っ張り出しているだけのことです.最初のrandom.seedでは,プログラムを実行した時刻を( )に代入した結果として乱数列{4,5,2,1,2,4⋯}が生成され,for文以下によって順次各数値が順番に呼び出されています.一方,random.seed(1)は整数1に沿った乱数列{2,5,1⋯}が生成され,for文以下によって順次各数値が順番に呼び出されています.13行目では再度random.seed(1)が実行されているため,乱数列{2,5,1⋯}が再生成され,for文以下によって順次各数値が順番に呼び出されています.random.seed(1)の再実行が無い場合,{2,5,1⋯}の⋯部分が呼び出されていたことになります.
このseedを設定することで,乱数を用いるアルゴリズム同士の性能を比較したい場合に,「生成される乱数によって性能が変化する」という事象を回避し,同じ乱数列でアルゴリズム同士を比較することが出来ます.具体的には,遺伝的アルゴリズムや粒子群最適化(PSO),カッコウ探索などが相当します.
itertools
これは
iterate tools
の略であり,繰り返し計算を効率的に行う際に便利なライブラリです.この中から幾つか代表的なものを紹介します.
accumulate(p)
配列pの累積値
を返します.
配列pの累積値
を返します.
product(p,repeat = r)
選択肢
があるr個の重複ありの組み合わせを返します.
直積
に相当.
選択肢
があるr個の重複ありの組み合わせを返します.
直積
に相当.
permutations(p,q)
選択肢
があるq個の重複なしの組み合わせを返します(len(p)≥q).
選択肢
があるq個の重複なしの組み合わせを返します(len(p)≥q).
combinations(p,q)
選択肢
があるq個の重複なしの順列組み合わせを返します(len(p)≥q).
選択肢
があるq個の重複なしの順列組み合わせを返します(len(p)≥q).
combinations_with_replacement(p,q)
選択肢
があるq個の重複ありの順列組み合わせを返します(len(p)≥q).
選択肢
があるq個の重複ありの順列組み合わせを返します(len(p)≥q).
p=(0,1)から組み合わせを作る例
| イテレーター | 結果 | 補足 |
|---|---|---|
| product (p, repeat =2) | [(0, 0), (0, 1), (1, 0), (1, 1)] | コインの表=0,裏=1.コインが2枚の時の組み合わせ.2^2=4通り. |
| product (p, repeat =3) | [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)] | コインの表=0,裏=1.コインが3枚の時の組み合わせ.2^3=8通り. |
| permiculations(p,2) | [(0, 1), (1, 0)] | 2P2 =2と同義. |
| permiculations(p,1) | [(0), (1)] | (_2^)P1 =2と同義. |
| combinations(p,2) | [(0, 1)] | (_2^)C2 =1と同義. |
| combinations(p,1) | [(0), (1)] | 2C1 =2と同義. |
| combinations_with_replacement(p,2) | [(0, 0), (0, 1), (1, 1)] | 2⊓2=3と同義. |
| combinations_with_replacement(p,1) | [(0), (1)] | 2⊓1 =2と同義. |
こうした組み合わせ計算を補助するライブラリは確率事象の計算の場面で大きく貢献します.
コラム5.車輪の大発明・巨人の肩の上に立つ・急がば回れ
プログラマーの間で有名な言葉として,車輪の大発明(Reinventing the wheel)があります.車輪は接地面との摩擦を効率的に落としながら移動することができる有効な手段であり,我々の生活に欠かせないものとなっています.由来には諸説ありますが,要は「広く受け入れられ確立されている技術や解決法を知らずに(又は意図的に無視して)、同様のものを再び一から作ること」という意味を持っています.プログラムの話で言えば,「ライブラリや先行事例があるにもかかわらず、様々な理由でそれを利用せず、コードやプログラミング技法を再び一から作ってしまうこと」が相当します.勉強目的なら問題はありませんが,開発目的なら時間の無駄ですし,成果品としての付加価値も生みません.
例えば,第1章に書かれていたプログラムは正に車輪の大発明に相当します.内容としては,整数からなる配列において5以上なら1,5以下なら0と分岐された新たな配列を作るものでした.普通にpythonで書くと7行が必要ですが,既に開発されたライブラリであるNumpyのwhere (JAPAN >= 5, 1 ,0)で記述すれば1行で済みます.しかも,Numpyは速度が早いのです.これをわざわざforやifを使って書いていたら時間の無駄です.
車輪の大発明を避けるためのコツは,「自分が考えつく or やろうとしているものは必ず誰かが既に考えている」と捉えることです.そして,Google先生を活用する.昔と違って今はインターネットによる知識の共有が量と質の両面から高水準で可能となっています.例えば,
Stack Overflow
といったプログラマー向けコミュニティー,知恵袋,ブログなどに先人の知恵が豊富に共有されています.これらを使わない手はありません.自分の書いたプログラムを眺めながら,「ここってもっと効率的に書けないだろうか」,「ここはこう書いたほうがforやifが減って速度が早くなるのではないか」と考えることも大切です.こうして洗練されたプログラムが結局は自分の時間の節約に直結するでしょう.
一方,「巨人の肩の上に立つ」という言葉があります.これは,偉大な先人たちの業績や先行研究などを巨人に喩えて、現在の学術研究の新たな知見や視座、学問の進展といったものもそれらの積み重ねの上に構築され、新しい知の地平線が開かれることを端的に示した言葉とされます.あなたがこれから行う研究はこれまでの膨大な量と質の研究蓄積,すなわち,巨人の肩の上に成り立つはずであり,成り立つべきという信念が込められています.論文検索ツールとして有名なGoogle Scholarもトップページにこの言葉があります.近年の研究者は予算削減や量よりも質(Publish or Perish;出版するか死ぬか)という流れの中で腰を据えて研究を行うことが難しくなっています.しかし,こうした外部環境を理由に論文レビューを怠り,他人が既に結論づけているテーマで研究を行うと,そこには新規性は皆無で,学術の進歩に全く貢献しない論文が生産されるという車輪の大発明が発生します.この結果,論文は査読を通らず,せっかくかけた時間が浪費されてしまいます.急がば回れです.
繰り返しになりますが,プログラム開発も論文も車輪の大発明は避けるべきです.そして,巨人の肩の上に立つこと.急がば回れです.これを怠ると,知らぬが仏,裸の王様,お山の大将となります.実はこうしたお山の大将論文を高額でacceptして荒稼ぎする悪徳雑誌が耐えないのです.したがって,英語論文の本数が必ずしもその研究者の研究力の高さを示さないのです.その研究者の政治力の高さを伺うことが出来ますが…