↓ メインコンテンツへスキップ
  1. 第09講 機械学習(2/3; 教師あり学習)/

第09講 週次課題

課題09-1 2024年度12月の気温予測
#

難易度 ⭐

december_data.csv は、1900〜2023年の12月の平均気温のデータです(1 行目はヘッダ、2 行目以降が「年,平均気温」)。 このデータを使って、2024年12月の平均気温を予測してください。 ファイル名は predict_december_temp.py とし、気温データのファイル名は直接プログラム中に書かずに、コマンドライン引数(sys.argv[1])で受け取るようにしてください。

📥 december_data.csvのダウンロード

def read_csv(filename):
    x, y = ([], [])
    with open(filename, "r") as f:
        f.readline()    # ヘッダ行を読み飛ばす。
        for line in f:
            pass
    return x, y

x, y = read_csv(sys.argv[1]) # ファイル名はコマンドライン引数で指定する。
# モデル(LinearRegression)のインスタンスを構築する。
# 読み取ったデータを使ってモデルを学習する。
y_pred = model.predict([[2024]]) # x_test を 2024 にして、2024年12月の気温を予測する。

assert len(x) == 124 and len(y) == 124, "1900〜2023 年の 124 年分を読み込めているはず"
assert x[0] == [1900] and y[0] == 4.3, "1 行目は 1900 年、4.3 度"
assert 6.0 < y_pred[0] < 9.0, "予測値は 12 月の京都の平均気温として妥当な範囲(6〜9 度)に収まるはず"

print(f"2024年12月の平均気温は {y_pred[0]} 度(予測)です。")

課題09-2 犬猫画像判定
#

難易度 ⭐⭐

犬と猫の画像を学習し、与えられた画像に写っているのが犬か猫かを判定するプログラムを作成してください。 ファイル名は、cats_or_dogs.py としてください。 犬猫の学習画像は、Kaggleからダウンロードしてください。 Moodleにも同じデータをおいています。

ダウンロードしたzipファイルを展開すると catsとdogsが含まれるディレクトリが得られます。 それで得られたディレクトリをコマンドラインの最初の引数としてプログラムを実行してください。 加えて、適当な犬や猫の画像をコマンドラインの2つ目以降の引数としてプログラムを実行してください。

以下のプログラムの learn_data 関数の中に、決定木(DecisionTree)のモデルを構築するコードを書いてください。 また、適当な犬や猫の画像を与えて、犬か猫かを判定するプログラムを完成させてください。

📥 ダウンロード(Moodle)(Kaggleのページ)

from PIL import Image
from sklearn import tree # 決定木を用いるには、tree モジュールをインポートする。
import numpy as np
import os
import sys

# basepath 直下の cats と dogs 以下に猫、犬の画像があるとする。
def read_image(basepath): # 画像を読み込む。
    x = []
    y = []
    for file in os.listdir(os.path.join(basepath, "cats")):
        if file.endswith(".jpg"): # jpgファイルのみを対象とする。
            img = Image.open(os.path.join(basepath, "cats", file))
            img2 = img.resize((128, 128))      # 画像の大きさを 128x128に統一する。
            x.append(np.array(img2).flatten()) # 画像を1次元配列に変換し、xに追加する。
            y.append("cats")
    for file in os.listdir(os.path.join(basepath, "dogs")):
        if file.endswith(".jpg"): # jpgファイルのみを対象とする。
            img = Image.open(os.path.join(basepath, "dogs", file))
            img2 = img.resize((128, 128))      # 画像の大きさを 128x128に統一する。
            x.append(np.array(img2).flatten()) # 画像を1次元配列に変換し、xに追加する。
            y.append("dogs")
    return x, y

def learn_data(x, y):
    model = # 決定木(DecisionTree)のモデルを構築する。
    # 構築したモデルを使って、学習する。
    return model

x, y = read_image(sys.argv[1])
model = learn_data(x, y)
for file in sys.argv[2:]:
    img = Image.open(file)
    img2 = img.resize((128, 128)) # 画像の大きさを 128x128に統一する。
    x = np.array(img2).flatten()  # 画像を1次元配列に変換する。
    print(f"{file}: {model.predict([x])}")

これらは、Wikimediaにある画像です。 これらの画像や、お持ちの犬猫画像を引数に与えてみて、判定できるかを確認してみてください。 判定が間違っていた場合、DecisionTreeClassifier のパラメータを変更してみてください。

学習済みモデルの保存と読み込み

なお、学習したモデル(model)をファイルに保存しておくことも可能です。 毎回学習すると、128x128程度の画像であっても1〜5分程度時間がかかります。 学習したモデルをファイルに保存しておき、必要な時に読み込むことで、実行時間を短縮できます。

import pickle
with open("cats_or_dogs_model.pickle", "wb") as f:
    pickle.dump(model, f)

以下のファイル(cats_or_dogs_from_model.py)で学習済みのモデルを利用して判定します。

from PIL import Image
import numpy as np
import sys

import pickle
with open(sys.argv[1], "rb") as f:
    model = pickle.load(f)

for file in sys.argv[2:]:
    img = Image.open(file)
    img2 = img.resize((128, 128))
    x = np.array(img2).flatten()
    print(f"{file}: {model.predict([x])}")