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

python

今回はまじめに
最近のPythonの文法をまとめてみました。

解説動画はこちら


 
さて最近のPythonの文法について
しばらく触れていなかったので
少し解説していきたいと思います。

今回はGoogle Colabを使用しているので
そのバージョンである3.10までの内容です。




文字列のフォーマット指定

f"文字列{変数}"
で文字列にデータを差し込みすることができます。
# 昔のフォーマット
name = "フリーザ"
hourly = 530000
text = "{0} : 私の時給は{1}円です。".format(name, hourly)
print(text)

# Fフォーマット
name = "フリーザ"
hourly = 530000
text = f"{name} : 私の時給は{hourly}円です。"
print(text)
フリーザ : 私の時給は530000円です。

フォーマットの指定もできます

{変数:指定文字列}
{変数:,} : 3桁区切り
{変数:.2f} : 小数点以下の指定(この場合は2桁)

# Fフォーマット
name = "フリーザ"
name2 = "ザーボン"
hourly = 530000
hourly2 = 2980.2983
text = f"{name} : 私の時給は{hourly:,}円です。"
print(text)
text2 = f"{name2} : 私の時給は{hourly2:.3f}円です。"
print(text2)


defaultdict

存在しないキーのデフォルト値を指定できます

通常の辞書型では最初にキーが存在しないと値を操作できません
# キーを初期化代入する必要がある
d = {}
for key in "aabbbc":
    if key not in d:
        d[key] = 0
    d[key] += 1

print(d)

defaultdictの場合は初期値を決められるので
コードを省略できます。

# defaultdictの場合
from collections import defaultdict
d = defaultdict(int)

for key in "aabbbc":
    d[key] += 1

#print(d)
print(d["a"])
2



関数の結果をキャッシュ

functools.lru_cacheを用いると
同じ引数の関数の結果をキャッシュでき
再帰の計算などが早く行えるようになります。

# キャッシュ無し
def fibonacci_old(n):
    if n < 2:
        return n
    return fibonacci_old(n-1) + fibonacci_old(n-2)
print(fibonacci_old(30))
msレベル

# キャッシュあり
from functools import lru_cache
@lru_cache(maxsize=None)
def fibonacci_cache(n):
    if n < 2:
        return n
    return fibonacci_cache(n-1) + fibonacci_cache(n-2)
print(fibonacci_cache(100))
usレベル

圧倒的に早くなります。


アンパック演算子

*を用いて変数への複数代入を行う

a, *b, c = [1,2,3,4,5,6]
print(a, b, c)

a, b, *c = [1,2,3,4,5,6]
print(a, b, c)
1 , [2,3,4,5] , 6
1 , 2 , [3,4,5,6]



ウォルラス演算子

:= で変数への代入と評価を同時にできるようになります

(a:=2) >= 2
True


WITH構文で複数ファイルのコンテキスト

with open(ファイル名) as 変数, open(ファイル名) as 変数 ... :

# ファイルを作っておく
import random
import string

for name in ["a","b","c"]:
  with open(name+".txt","w") as _w:
    text = ''.join([random.choice(string.ascii_lowercase) for i in range(10)])
    _w.write(text)

# with構文
with open("a.txt") as _a, open("b.txt") as _b, open("c.txt") as _c:
  print(_a.read())
  print(_b.read())
  print(_c.read())


match文

3.10でmatch文が導入された
他の言語でいうcase文ですね

match 条件:
  case パターン:
    return 戻り値
  case パターン:
    return 戻り値


# match文
def http_error(status):
    match status:
        case 400:
            return "ダメっすねー"
        case 404:
            return "見つからねっす"
        case 418:
            return "なんでしょね"
        case _:
            return "何言ってるか分かんねっす"

http_error(404)
見つからねっす


いつの間にか便利な機能が追加されていて
業務でも捗っている感じになっていました。

文法の知識は定期的にアップデートしていかないと
もったいないですね

今回は最近のPython文法についてでした
それでは。


今回は先日公開されたジブリ映画に関する
ジブリ公式ツイッターさんの投稿に関するものです

解説動画はこちら


ジブリ公式Twitterの投稿が
まるでモールス信号のようだと
話題になっていたので解読してみました

対象のツイートはこちら

ジブリ公式ツイッター


宮崎駿監督の最新作「君たちはどう生きるか」の
ポスターに描かれた謎の鳥のイラストとともに
「カカヘカ・・・」と暗号文ぽいものが
書かれています

鳥の鳴き声のようにも見えるますが・・・
モールス信号に変換する事で
解読する事ができる様です

 

書かれている文字

ツイートされていたのはこの文章
カカヘカヘッカヘヘッヘカヘカヘッカカッヘカヘカカッヘカヘカヘッカヘカヘカッヘカカヘッカヘッヘカヘカッカカヘカッヘカヘカカッカヘッカヘカヘヘッヘカヘヘカッヘヘッ

「カ」は「・」
「ヘ」は「-」
「ッ」は区切り
として和文モールス符号に
変換することが出来るみたいです

早速解読するコードを作っていきましょう

モールス暗号解読コード
md = {
'カヘ': 'イ','カヘカヘ': 'ロ','ヘカカカ': 'ハ','ヘカヘカ': 'ニ',
'ヘカカ': 'ホ','カ': 'ヘ','カカヘカカ': 'ト','カカヘカ': 'チ',
'ヘヘカ': 'リ','カカカカ': 'ヌ','ヘカヘヘカ': 'ル','カヘヘヘ': 'ヲ',
'ヘカヘ': 'ワ','カヘカカ': 'カ','ヘヘ': 'ヨ','ヘカ': 'タ',
'ヘヘヘ': 'レ','ヘヘヘカ': 'ソ','カヘヘカ': 'ツ','ヘヘカヘ': 'ネ',
'カヘカ': 'ナ','カカカ': 'ラ','ヘ': 'ム','カカヘ': 'ウ','カカヘヘ': 'ノ',
'カヘカカカ': 'オ','カカカヘ': 'ク','カヘヘ': 'ヤ','ヘカカヘ': 'マ',
'ヘカヘヘ': 'ケ','ヘヘカカ': 'フ','ヘヘヘヘ': 'コ','ヘカヘヘヘ': 'エ',
'カヘカヘヘ': 'テ','ヘヘカヘヘ': 'ア','ヘカヘカヘ': 'サ','ヘカヘカカ': 'キ',
'ヘカカヘヘ': 'ユ','ヘカカカヘ': 'メ','カカヘカヘ': 'ミ','ヘヘカヘカ': 'シ',
'カヘヘカカ': 'ヱ','ヘヘカカヘ': 'ヒ','ヘカカヘカ': 'モ','カヘヘヘカ': 'セ',
'ヘヘヘカヘ': 'ス','カヘカヘカ': 'ン','カカ': '゛','カカヘヘカ': '゜'
}

def morus_decode(text):
    texts = text.replace("\n","").split("ッ")
    result_text = ''.join([md[tx] for tx in texts if tx in md])
    print(result_text)

辞書を使って対象の文字列を
変換してつなげるだけのシンプルで簡単なコードです

これを使って先ほどの文章を入力すると
text  = """
カカヘカヘッカヘヘッ
ヘカヘカヘッカカッヘカヘカカッ
ヘカヘカヘッカヘカヘカッヘカカヘッカヘッ
ヘカヘカッカカヘカッヘカヘカカッカヘッ
カヘカヘヘッヘカヘヘカッヘヘッ
"""

morus_decode(text)

答えが出ます!!!!!!!

答えを知りたい方は
動画を見るかコード試してみて下さいね




平文をモールス暗号に変換するコード
md2 = {v:k for k,v in md.items()}
def morus_code(text):
    result_text = 'ッ'.join([md2[tx] for tx in text if tx in md2])
    print(result_text)
    
text = "ココニテキストヲ"
morus_code(text)

逆でテキストをモールス暗号化するのも
辞書変換で出来ます

Python言語を使えば
こういった暗号解読も簡単に行えます

文法がまだの方は
是非この機会に
色々動画見てみて下さいね

それでは

乙py式5時間で学ぶプログラミング基礎(python編)


乙py3

短時間でプログラミングを学ぶ事ができる動画講座を作りました。

YOUTUBEの動画と資料を載せておきますので
ぜひ参考にしてくださいませ。


なおPythonチートシートを作成しています。


コーディングに迷った際に役に立ち

WEB検索する時間を無くして

作業時間を効率化できます。

note
Pythonチートシート

目次




1.この講座について
2.プログラミング言語について
3.プログラミング言語の学習方法について
4.プログラミングの学習環境について
5.目標設定について
6.Jupyterの使い方
7.演算
8.文字
9.インデックス
10.変数
11.予約語
12.データ型
13.文字列
14.文字列のフォーマット
15.算術演算子
16.代入演算子
17.関係演算子
18.論理演算子
19.基礎演習1
20.リスト1
20.リスト2
21.タプル
22.辞書型
23.if文
24.for文
25.while文
26.組み込み関数について
27.enumerate関数
28.zip関数
29.ソート
30.内包表記
31.基礎演習2
32.関数
33.global変数とスコープ
34.無名関数
35.オブジェクト指向の話
36.クラスについて
37.例外処理
38.ライブラリの利用
39.基礎演習3
40.まとめ
付録.その先、仕事とか、研究にどう使えるの?

今回はたった2行で
機械学習の精度検証が出来ちゃう
Lazypredictを試してみました

解説動画はこちら


このライブラリは
機械学習用のモデルを自動作成して
複数のモデルを比較してくれます

これがgithubです
Lazypredict

ドキュメントとしては
それほど情報量が多くないようです

コードなどもシンプルで
かなり使いやすい印象ですね


GoogleColabで動かせるので
使いたい方はコードを参考にしてみてください。

まず最初はライブラリのインストールです
# ライブラリのインストール
pip install lazypredict
30秒くらいでインストールも終わります。

GoogleColabなら追加のインストールが
無くても動くと思います。

このライブラリは
数値を予測する回帰モデルと
種別を予測する判別モデル
2種類の機械学習モデルの比較を行えます



最初は判別モデルをみてみましょう
データはscikit-learnのデータセットを使います

load_wine
ワインの品種に関するデータセットで
14列178個のデータがあり
3クラス分類で予測します


説明変数
alcohol アルコール濃度
malic_acid リンゴ酸
ash 灰
alcalinity_of_ash 灰のアルカリ成分
magnesium マグネシウム
total_phenols 総フェノール類量
flavanoids フラボノイド(ポリフェノールらしい)
nonflavanoid_phenols 非フラボノイドフェノール類
proanthocyanins プロアントシアニジン(ポリフェノールの一種らしい)
color_intensity 色の強さ
hue 色合い
od280/od315_of_diluted_wines ワインの希釈度合い
proline プロリン(アミノ酸の一種らしい)

目的変数
ワインの品種

こんな感じのデータです
読み込みのコードはこちら
from sklearn import datasets
import pandas as pd
df = datasets.load_wine(as_frame=True).frame

print('行列数 : ' , df.shape)
print('ターゲットの種別数 : ' , df['target'].nunique())
df.head()

これでデータが用意できたので
次は学習データの分割です
トレーニング7 , テストサイズ3で分割します
# 学習データの分割
from sklearn.model_selection import train_test_split
X = df.iloc[0: , 0:-1]
Y = df['target']

# トレーニング7 , テストサイズ3で分割
x_train, x_test, y_train, y_test = train_test_split(X , Y , test_size=0.3 , random_state=0)
x_train.shape, x_test.shape, y_train.shape, y_test.shape
((124, 13), (54, 13), (124,), (54,))


最後にlazypredictで
予測モデルの作成です

分類モデルを複数自動で生成し
その精度検証の結果と
予測結果を出してくれます

モデルの作成、検証部分は2行でいけます
分類モデルの検証はLazyClassifierを使います
# lazypredictのインポート
import lazypredict
# 回帰予測
#from lazypredict.Supervised import LazyRegressor
# 分類問題
from lazypredict.Supervised import LazyClassifier

# 予測モデルの作成(たったの2行だけ)
clf = LazyClassifier(verbose=1,ignore_warnings=True,predictions=True)
models , predictions = clf.fit(x_train , x_test , y_train , y_test)

最後の行の変数
models , predictions
に精度検証の結果と
予測結果が格納される仕組みです


作成した予測モデルの比較を見てみましょう

# モデルの比較
models
スクリーンショット 2022-10-01 16.01.17

こんな感じで予測モデルを一気に検証してくれます


テストデータの予測結果も見てみましょう
# テストデータ で予測
predictions
スクリーンショット 2022-10-01 16.02.36

列方向は各モデルで
行がテストデータです


回帰モデルも同様に試してみましょう

load_boston
ボストン住宅価格のデータです
from sklearn import datasets
import pandas as pd

data = datasets.load_boston()
boston_df = pd.DataFrame(data=data["data"] , columns=data["feature_names"])
boston_df['MEDV'] = data["target"]

print('行列数 : ' , boston_df.shape)
print('ターゲットの平均値 : ' , boston_df['MEDV'].mean())
boston_df.head()

学習データの分割も同様です
# 学習データの分割
from sklearn.model_selection import train_test_split
X = boston_df.iloc[0: , 0:-1]
Y = boston_df['MEDV']

# トレーニング7 , テストサイズ3で分割
x_train, x_test, y_train, y_test = train_test_split(X , Y , test_size=0.3 , random_state=0)
x_train.shape, x_test.shape, y_train.shape, y_test.shape
回帰モデルの検証も2行でいけますが
回帰の場合はLazyRegressorを使用します

# lazypredictのインポート
import lazypredict
# 回帰予測
from lazypredict.Supervised import LazyRegressor
# 分類問題
#from lazypredict.Supervised import LazyClassifier

# 予測モデルの作成(たったの2行だけ)
reg = LazyRegressor(verbose=1,ignore_warnings=True,predictions=True)
models , predictions = reg.fit(x_train , x_test , y_train , y_test)
# モデルの比較
models
スクリーンショット 2022-10-01 15.42.01

こんな感じの結果になりました



まとめ


データを突っ込めばどの手法の精度が高くなるのかを
結構な速さで出してくれるので
初めて予測モデルを作るデータには
最適かもしれません


AutoMLで似たようなものに
PyCaretというのが有りますが
Lazypredictの方がバグが出なくて
良いかもしれないなーと思いました

検証をパパッとやりたい方には
かなり良いライブラリかと思いますので
試したい方はコードを参考にしていただければと思います

それでは

水曜日のダウンタウンに出てきた
「じゃねーよカルタ」

このカルタに出てきた人の顔
誰が一番春菜さんの顔と近いのかを
調べてみました。


解説動画はこちら



今回は「じゃねーよカルタ」に出てきた人の
顔の画像と近藤春菜さんの顔の画像を
比べて、誰が一番近いのかを検証しました。

画像の類似度の判定には
opencvのAKAZE特徴量を用いて
判定することとします。

さて今回の比較対象はこの5名

download-2

ハロネン元大統領
角野卓造
森永卓郎
和泉節子
マイケル・ムーア監督
です。

どんな感じに比較しているのか
AKAZEを使って特徴点を見てみましょう。

import matplotlib.pyplot as plt
import cv2
import os
%matplotlib inline

img1 = cv2.imread('画像パス') 
img2 = cv2.imread('画像パス') 
gray1 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY) 
gray2 = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY) 
akaze = cv2.AKAZE_create() 
kp1, des1 = akaze.detectAndCompute(gray1,None) 
kp2, des2 = akaze.detectAndCompute(gray2,None) 
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key = lambda x:x.distance)
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[0:10], None, 
                       flags = cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
plt.figure(figsize=(10,10))
plt.imshow(cv2.cvtColor(img3, cv2.COLOR_BGR2RGB))
plt.axis("off")
plt.show()
download

こんな感じで似ている点を出しています。

今回比較する春菜さんの顔はこちら

download-1

先ほどの5名と
和泉節子さん風に変装した春菜さんの
6名で比較して、一番近い顔の人を出してみます。

対象の人の顔画像は
画像ディレクトリに入れています。

判定に使ったコードはこちら
dir_path = '画像ディレクトリ'
img_size = (300,300)
target_img_path = '画像パス'
target_img = cv2.imread(target_img_path, cv2.IMREAD_GRAYSCALE)
target_img = cv2.resize(target_img, img_size)
bf = cv2.BFMatcher(cv2.NORM_HAMMING)
detector = cv2.AKAZE_create()
(target_kp, target_des) = detector.detectAndCompute(target_img, None)

files = os.listdir(dir_path)
result = {}
for file in files:
    img_path = dir_path + file
    try:
        img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
        img = cv2.resize(img, img_size)
        (kp, des) = detector.detectAndCompute(img, None)
        matches = bf.match(target_des, des)
        dist = [m.distance for m in matches]
        ret = sum(dist) / len(dist)
        result[file.replace('.png','')] = ret
    except cv2.error:
        ret = 999999

for k,v in sorted(result.items(),reverse=True,key=lambda x:x[1]):
    img = cv2.imread('img/{0}.png'.format(k)) 
    plt.figure(figsize=(8,8))
    plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    plt.title('{0} : {1:.06}'.format(k , v),fontsize=20)
    plt.axis("off")
    plt.show()


結果は動画の方で
お楽しみくださいませ。

結構意外な結果が出ましたね!!!

opencvを使うと
画像の特徴量を比較して
似ているかどうかを数値化する事ができます。

面白いので試してみてくださいね。
今回はこれまでで
それでは。


このページのトップヘ