乙Py先生のプログラミング教室
初学者のためのプログラミング学習サイト

プログラミング

さて
最近話題に上がった

食べログ分布

に関して
そんなものが存在するのかどうか
検証してみました。

解説動画はこちら



食べログ分布を手元で見たい方は
まずは
データを集めてください。

食べログさんのサイトへ行って
コピペしていただければ
集まるかなーと思います。

集めるのは大変だと思うので
こちらで集めてみました。

手元のデータは
東京の店舗で
約36千件です。

これを可視化してみましょう。

評点で3-4だけに絞っていますが
全店舗だとこうなりました。

zenken

縦が店舗数
横は評点です

3.0-3.1あたりがボリュームが多いですね

おそらくですが
加盟したばかりの店舗というのは
3.0から始まるのではないかと思います。

有る程度コメントなどが加味されて
評点が決まっていくのではないかな?
と思われます。

ということで
有る程度コメントがある店舗に絞って
みてみましょう。

コメント100より多い店舗だけに
絞って可視化してみると・・・

100ken

どうでしょうか

分布が変わりましたね。

有る程度
コメント数などで
評点が定まってくるのだと思います。

この場合はボリュームゾーンが
3.6あたりになりますね。

自然界のデータを無作為に抽出すると
正規分布を取ることが多いので
正規分布も重ねてみましょう。

seiki

赤線は平均を3.6とした際の正規分布です。

どうでしょう
正規分布と比べると
ややスカスカしてる部分が有りますね!!!!

seiki2

これがそのスカスカ部分を囲ってみたものですが

評点に対する店舗数は
正規分布に収束するという仮定だと

もう少し3.6-3.7と
3.8-3.85くらいまでの店舗が
存在していてもおかしくはないのですが
少ないんですねーーー

このやや
歪な感じの分布というのが
「食べログ分布」
ということになります。

有りましたね!!

正規分布などに比べると
いびつさが際立つ分布になるという
結果になりました。

さて
いかがでしたでしょうか?

あと余談ですが
色々みてみると
食べログさんは

「3.0から5.0までの20段階評価である」

ということが分かりました。

なので
3.5と言っても20段階で見れば
それほどでも無いのです。

ただし、店舗の大半は
3.5に到達しないので

3.5も有れば相対的には
良く見えるよ、ということなのでしょう。

単純にコメント数の大小などでは
この評点は決まらない仕組みなのでしょうね

そもそも仕組みを公開してないと思いますし

この評点を信じるのか
自分の舌を信じるのかは
あなた次第です!!

はいどうも
乙pyです。

久々に
東の方の大学の入試問題を
解いていきたいと思います。

解説動画はこちら





さて
問題はこれです。
スクリーンショット 2019-09-28 16.27.37

さて
こいつを解くには
sympy
を用います。

sympyでは複雑な計算結果を
求めることできます。

ライブラリを読み込みしておきましょう。
import sympy
x = sympy.Symbol('x')

x をシンボル変数として読み込みしておくと
数式を定義する際に使うことができます。

次に数式の打ち込みです。

何かしらの変数に
数式を代入していきます。
f = (x**2+x/sympy.sqrt(1+x**2))*(1+x/((1+x**2)*sympy.sqrt(1+x**2)))

上の問題の数式をプログラムでの数式に置き換えると
こんな感じになります。

()で割り算などの優先順位をつけるのは
数学の書き方と一緒です。
ルートはsqrt関数を用いて表します。

最後に積分の計算です。
sympyでは

sympy.integrate(数式 , (x , 0 , 1 ))

となります。

最後に計算結果を表示です。

変数に計算結果を代入してプリントするだけですね。

まとめると

f = (x**2+x/sympy.sqrt(1+x**2))*(1+x/((1+x**2)*sympy.sqrt(1+x**2)))
F = sympy.integrate(f , (x,0,1))
print(F)

-35/12 + pi/8 + 5*sqrt(2)/2

はい答え出ました。

計算結果がプログラム上での表記で出力されます。

通常の数式表示と違うので
これだと分かりづらいかも知れませんね

そんな時は
Latexという数式を表示させるための
言語があるので
その形式で出力し直すことができます。

print(sympy.latex(F))

- \frac{35}{12} + \frac{\pi}{8} + \frac{5 \sqrt{2}}{2}

はいこいつを
JupyterNotebookなどのマークダウンセルに打ち込みすれば
通常の数式表示されます。

答えを数式表示させると
スクリーンショット 2019-09-28 16.43.22

はいこれで
分かりやすくなりましたね。


さて
いかがでしたでしょうか?
Sympyを使うと
結構大変な計算もすぐに
解けるし助かるんじゃないかと思います。

そもそもの
数式を入力するのに
30秒以上掛かってるって?

気のせいです!!!

今回はこれまでです。
それでは。

 

先日作った
顔交換アプリケーションで
まあまた遊んでみました。

先日作ったやつの解説は
コレ



今回の
解説動画はこちら

 

はい
opencvと顔認識を使って
顔の特徴点から
顔の抽出して互いの顔を交換していきます。

結果はコレ
matukototatibana

右側の立花さんにマツコさんを被せたのは
すごく異質な感じしますねーーー

化粧もしているしね

左側の
マツコさんに立花さんの顔を被せたのは
そこまでの違和感がないですねーーー

すっぴんの顔だって言っても
何人か信じてしまうような感じに仕上がってますwww


はい
このような顔交換も
opencvを使えば
簡単にできてしまいますので

是非試してみてくださいね

それでは


はいどうもこんばんわ
乙pyです

さて、今回は
Googleの入社問題を解いてみたいと思います。

解説動画はこちら





さて、
どのような問題かというと

2 Eggs and 100 floor Google Classic question
100階建てのビルのある階から卵を落とします。
卵はある階よりも低ければ割れることはなく
ある階よりも高いと割れてしまう。

今、あなたは卵を2つ持っています。
卵が何階で割れるかを調べるもっとも効率のよい方法は何ですか?
そして、その方法で必要な卵を落とす回数は最大で何回ですか?

こんな問題です。

まずは素直に一回から落として行くと
最大でその階数分だけの試行回数になります。

なので100階まであるので
最大で100回でしょうね。

次に10階刻みで増やしていき
割れたら手前の階層に戻って1づつ増やして行く方法


これだと
10階 、 20階 ぺちゃる 
11,12,13,14 ペチャる 
14階で割れるとしたら6回落とした、となります。

さて、これを全階層分試行するには面倒くさいですよね
プログラムで一気に解いてしまいましょう。

def check_egg(x):
    c,n=0,10
    while True:
        c+=1
        if x<=n:
            break
        n+=10

    n = n-9
    while True:
        c+=1
        if x<=n or '{:02}'.format(n)[1]=='9':
            break
        n+=1
    return c,x

results = {}
for x in range(1,101):
    answer,key = check_egg(x)
    results[key] = answer

for k,v in results.items():
    print(k,v)

これで実行してみると
最大試行回数は99階と100階がそれぞれ
19回落とすことになります。

さて
もっと効率の良い方法はないでしょうか?

それは
刻む階層を減らして行くやり方です。

まず最初に刻む分をNとすると

N , N-1 , N-2 ・・・

という感じで
刻むのを減らせます。

そして、この刻みが100階を超えるには
Nが14であるということになります。

1 + 2 + 3 + 4 ・・・ で
100を超えるのは14の時ですね

さて刻み方がわかったら
これをプログラムにしてみましょう。

こんな感じですね

def check_egg(x):
    c=0
    steps=[14, 27, 39, 50, 60, 69, 77, 84, 90, 95, 99, 100]
    for i,n in enumerate(steps):
        c+=1
        if x<=n:
            break

    n = steps[i-1]+1 if i!=0 else 1
    while True:
        if n in steps:
            break
        c+=1
        if x<=n:
            break
        n+=1
    return c,x

results = {}
for x in range(1,101):
    answer,key = check_egg(x)
    results[key] = answer

for k,v in results.items():
    print(k,v)

これで実行してみると
最大試行回数は
14回まで減らすことができます。

落とす時のイメージとしてはこんな感じ

1	2	3	4	5	6	7	8	9	10	11	12	13	14	
15	16	17	18	19	20	21	22	23	24	25	26	27	
28	29	30	31	32	33	34	35	36	37	38	39	
40	41	42	43	44	45	46	47	48	49	50	
51	52	53	54	55	56	57	58	59	60	
61	62	63	64	65	66	67	68	69	
70	71	72	73	74	75	76	77	
78	79	80	81	82	83	84	
85	86	87	88	89	90	
91	92	93	94	95	
96	97	98	99	
98	99	100	

どこでたまごが潰れても
最大で14回で答えにたどり着ける感じになってますね。


今回は
Googleの入社問題を考えてみました。

よく考えれば意外と
解けそうな問題ですね〜〜

入社できませんかねwwwwww

今回はこれまでです
それでは。






 

はいどうも
乙pyです。

今回はみんな大好き黒川先輩を
世界旅行に連れて行ってあげましょう
という企画です。

動画はこちら




さて今回は
OpenCVというのを使います。

OpenCVは画像加工のための
ライブラリでPython以外の言語にも
対応しているものです。

これを用いると
画像を使っていろいろ遊ぶことができます。

インストール方法は
pip install opencv-python

でインストールすることができます。

Pythonでの使い方:

まずはじめにライブラリを読み込みます。
import cv2
import numpy as np 
import matplotlib.pyplot as plt
%matplotlib inline

これでライブラリを使う準備は完了です。

画像をうまく合成するには
1.背景画像
2.上に載せる画像
3.載せる画像のマスク画像

この3つが必要になります。

背景は良いとして
マスク画像というのは
kurochan6

こんな感じで、載せたい部分を白
それ以外の部分を黒く塗りつぶした画像を
マスク画像として使えます。

マスク画像なしでも
画像を合成することはできますが
スムーズな合成をするには
マスク画像が必要です。

コードはこんな感じになります。

file_dir = 'img/'
kurochan = 'kurochan.jpg'
bg_name = 'roma.jpg'
msk_name = 'kurochan6.png'
src = cv2.imread(file_dir + kurochan)
dst = cv2.imread(file_dir + bg_name)
msk = cv2.imread(file_dir + msk_name)

size_rate = 0.8
src2 = cv2.resize(src , (int(src.shape[1]*size_rate), int(src.shape[0]*size_rate)))

r_msk = cv2.resize(msk , (int(msk.shape[0]*size_rate), int(msk.shape[1]*size_rate)))

output = cv2.seamlessClone(src2, dst, r_msk, 
(src2.shape[0]//2,dst.shape[0]-src2.shape[0]//2), cv2.NORMAL_CLONE)

fig = plt.figure(figsize=(16,9))
plt.imshow(cv2.cvtColor(output, cv2.COLOR_BGR2RGB))
plt.show()

合成する画像をsrc
背景をdst
マスク画像をmsk
として読み込み
outputを生成しています。

cv2.seamlessCloneメソッドで
合成ができます。


さて合成してみると
こんな感じになります。

96

マスクの白い部分だけが合成に用いられ
黒い部分は背景とうまく合うように演算処理され
画像が合成される仕組みになっているようです。

cv2.seamlessCloneメソッドで
配置も決めるので
画像の大きさを超えるような場所に指定すると
エラーになります。

雑な合成ですが
元の画像とマスクの調整をうまくやれば
それっぽい画像ができるのではないかと思います。

これを用いると
まるで旅行に行ってきたような
画像を作ることができたりするので

アリバイ作りなんかも
できちゃったりするかもしれませんねwww


OpenCVは
他にもいろーーんなことができるので
また試していきたいと思います。

今回はここまでです。

それでは。


このページのトップヘ