isatoの活動日記

管理人isatoが毎日の生活で気になったこと、勉強になったことを書いています。

機械学習はつまり「ゴリ押し」

機械学習は入力と出力の関係を表現することができるものです。

では、なんでそんなものを使うのか。答えは簡単。その入力と出力の関係を人類がまだ知らないからです。

話が大きくなってしまいましたが、実際そうなんです。

人類はこれまでに、数々の自然現象を数式化してきました。数式を知るということはつまり「入力と出力の関係を知る」ということです。

入出力の関係を表す数式が分かっていれば、それを使って簡単に現象を再現できますね。

でもまだ人類は全能ではありません。

そこで、機械のとてつもない計算速度を利用して数式を近似しようとしたのが機械学習です。

例として教師あり学習を考えます。 教師あり学習は、ある現象の入出力の組が多数分かっていて、未知の入力に対する出力が知りたいときに使います。

既知の入出力の組を満たすような数式が得られれば、この現象の近似式とする、ということです。

具体的な方法には触れませんが、ニューラルネットワーク等をpcでゴリゴリに計算してやっと近似式が得られます。

ですので、機械学習自然法則が発見されるまでの代替品とも言えます。

そんななんでもかんでも自然法則としての数式があるのか?という方がいらっしゃるかもしれませんが、ないことが証明できますか?まぁあることも証明できませんが笑

この世の現象はまだまだ未知だということです。

もし機械が本当の数式を導き出せるようになったら、人類はさらに発展するか、機械に支配されるかどちらになるでしょうね。

少なくともその機械を持っていた人が、その時点では世界を支配するでしょうね。

それか、今世界を支配している人はもうこの機械を持っている?

python3 文字列操作:分割

python3での文字列の分割にはsplit関数を使います。 使い方は以下の通りです。

string = "abc.def.ghi"

splist = string.split(".")

print(splist)

# => ['abc', 'def', 'ghi']


split関数の引数に分割文字を指定することで、文字列を分割することができます。 結構使えますので、覚えておきたいですね。

python3 アノテーションについて

アノテーションとは要は注釈のことです。

コメントでつけてもいいんですが、関数の引数と戻り値に関しては正式な書き方があるので、そちらを使ったほうが良いでしょう。

以下のように使います。

def multi(x :int , y :int) -> str:
    return f'{x*y}'


このようにすることで、一目で入出力が分かりますね!

可読性を高めるためにも積極的に使っていきましょう〜

虚二次体とオイラーの素数生成多項式

オイラー素数生成多項式の不思議について以前の記事で紹介しましたが、少し研究されていて、ある性質が見つかっていたようです。

 

以下のページで紹介されています。

 

tsujimotter.hatenablog.com

 

めちゃくちゃ面白いと思いました。

でも、整数論が難しくてなかなか理解できません笑。私の独自研究を進めてくれる情報だと思っているのですが...。

 

まずは整数論から勉強しないとですね。

python3 enumerateについて

pythonではリストの要素と要素番号を同時に取得することができます。

以下のようにします。

list = ['a', 'b', 'c']

for i, cont in enumerate(list):
    print(f'{i} : {cont}')

# => 
0 : a
1 : b
2 : c

enumerateを使わなくても実現できますが、使った方がスマートに書けますね!

python3 アンパックについて

皆さんアンパックってご存知ですか。僕は最近知りました。

アンパックとはリストや辞書を展開して、中身を取り出すことです。

アンパックによって以下のようなことができます。

  1. *によるリストのアンパック
def myprint(a, b, c):
    print(f'a={a} b={b} c={c}')

list = [1, 2, 3]
myprint(*list)

# => a=1 b=2 c=3

このように、リストの中身を関数に渡すことができます。

辞書は以下のようにします。


2. **による辞書のアンパック

def myprint(a, b, c):
    print(f'a={a} b={b} c={c}')

dict = {'a':1, 'c':3, 'b':2}
myprint(**dict)

# => a=1 b=2 c=3

結構使えそうですね!

効率的にプログラムを書くための思考

最近どうやったらもっと効率よくプログラムが書けるかを考えていました。ここで言う「効率がよい」とは、問題を解こうとしてから解くまでにかかる時間についてです。

 

結論から言いますと、「解きたい問題を、自分の能力で解ける問題に素早く分解すること」が重要だと考えました。

 

 

少し話を変えます。

自分の知らない分野の論文の理解が難しいのはなぜでしょう。それは著者が基礎知識を知っている人を対象に書いているからです。そうしないと、膨大な分量になってしまいますからね。

 

人は話すときもこのような「飛躍」をよく使っています。若い人と年配の人で話が通じないのはこれが一つの原因です。

 

今までの話は人同士のコミュニケーションでした。これを人と機械のコミュニケーションに置き換えてみましょう。

 

機械はプログラミング言語という言葉のネイティブスピーカーだと思ってください。

ある問題Aを解いてほしいとき、機械にどう伝えますか?

 

「A解いといて!」

 

これで伝わったら話は早いですね。でもこう返されるかもしれません。

 

「Aって何?」

 

上で述べたようにお互いが、ある情報を同じ意味として共有しているからこそ、話が通じるわけです。

 

ではこうしてみましょう。

 

「BをしてCをしたらAをしたことになるから、お願い!」

 

このようにすれば、機械がBとCを知っていれば、Aを実現できますね。しかし、このように言うためには人側もBとCを知っていなければなりません。

 

人側がBとCを知らなければ、このようにしないといけないかもしれません。

 

「1と2をするとBができるからよろしく。

  あと3、4、5を順にすればCもできるよ。

それができたら、BとCでAを解いてね。」

 

長いからダメと思われるかもしれませんが、Aが解けたことに変わりないので僕は全く問題ないと考えます。問題はこの文章がすぐに思いつくかどうかです。

 

BとCを知っていれば、より早く思いつくかもしれませんね。

 

つまり、「解きたい問題を、自分の能力で解ける簡単な問題に素早く落とし込めるかどうか」がプログラムを書く効率に影響を与えるということです。

 

また、自分で解ける問題が多ければ多いほど、プログラムを書く効率は上がっていくでしょう。

 

まとめるとこのようになります。

・自分の能力を把握しておいて、その能力で解ける問題に素早く分解する。

・常に勉強して自分で解ける問題を増やす。

 

 

まだまだ勉強します。