その他

【初心者向け】新入社員がAIでAIを勉強!! | ゴミ判別プログラム その5

その他
この記事は約12分で読めます。

はじめに

みなさん、こんにちは。GWはいかがお過ごしでしたでしょうか?
本社がある札幌も徐々に暖かくなってきており、もう冬の寒さは来ないでほしいなと願うばかりです・・・。

さて、前回までは、2回を通して機械学習させてきた内容をwebアプリ化しました。まだご覧になっていない方、ぜひご覧ください。

データベースを作ってみる

今回つくるもの

前回のwebアプリ編では、位置情報から捨てたいゴミが何ゴミに当たるかをやってきました。その際は、テストとして3都市だけ記載されたjsonファイルをデータとして読み込ませていましたが、それではデータを変更するときや新たに追加するときに、実用的ではありません。

編集や新規追加ができるような、実用的な環境にするためには、データベースというものがあります。今回は、このデータベースにゴミについての情報を載せられるようにしてみました。

今回使用する技術

今回は、DjangoSQLiteの二つを使用して、データベースを作っていきます。

Djangoは、Webアプリケーションフレームワークで、前回まで使用していたStreamlitと同様のものです。データベースなど大規模なデータを扱う際には、こちらのDjangoの方が向いているので、今回はこちらを使用しました。データベースをグラフィカルに操作させるために必要なフレームワークです。

Django
The web framework for perfectionists with deadlines.

SQLiteは、今回作りたいテーマでもあるデータベースの役割を担ってくれます。データを保存してくれる倉庫の役割を担ってくれます。データベースと聞くと、難しそうなイメージがありますが、Djangoからグラフィカルに登録できるので、今回は直接操作する心配はないです!

SQLite Home Page

作成してみよう

Django・SQLiteの準備

まずは環境を構築していきます。これは以前作ったこともあるので、復習のような形になりますね!

python3 -m venv venv # 仮想環境の作成

source venv/bin/activate  # Mac/Linux の仮想環境の起動
venv\Scripts\activate     # Windows の仮想環境の起動

pip install django torch torchvision pillow # djangoのインストール

続いて、Djangoプロジェクトの作成をしていきます。次のコマンドを入力すると、勝手にファイルが作成されます。データベースなど必要なものが揃ってますね。

django-admin startproject garbage_project

出来上がったのが確認できたら、続けて以下のコマンドを入力していきましょう!

cd garbage_project # 先ほどできたgarbage_projectのファイルの中に入ります

python manage.py startapp garbage # garbage_project内のmanage.pyを起動させます

そうすると、garbageというファイルができたでしょうか。ここまでできた人は、順調です!

続けて、モデル定義をしていきます。
garbageファイルの中に、models.pyというファイルがあると思います。それをエディターで開き、下記のプログラムを書いていきましょう!

from django.db import models

class Region(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

class GarbageRule(models.Model):
    region = models.ForeignKey(Region, on_delete=models.CASCADE)
    garbage_name = models.CharField(max_length=100)
    category = models.CharField(max_length=100)

    def __str__(self):
        return f"{self.garbage_name} ({self.category})"

モデル定義とは、データベースに保存する情報の設計図を作る作業のことです。class 〇〇で、ルールを保存する表(テーブル)を作っています。

続けて、管理画面でデータ管理ができるよう、設計していきます。
先ほどと同じくgarbageファイルの中に、admin.pyというファイルがあると思います。こちらもエディターで開いて、下記のプログラムを書いていきましょう!

from django.contrib import admin
from .models import Region, GarbageRule

admin.site.register(Region)
admin.site.register(GarbageRule)

ここでは、先ほど作ったmodels.pyを管理画面に表示させたり、操作できるようにしています。これを記述しないと、先ほど作ったものが管理画面には表示されなくなってしまうので、忘れないようにしましょう!

続いて、初期設定をしていきます。以下のコマンドをターミナルに入力していきましょう。

# 初期設定

python manage.py makemigrations  # モデルの変更点をマイグレーションファイルとして保存

python manage.py migrate  # 管理画面にログインする「管理者アカウント」を作成

python manage.py createsuperuser # Django開発用サーバーの起動

すると、ターミナルに3回入力する項目が出てきます。ここでは、管理画面にログインするためのログイン情報を作っていきます。次のように入力していきましょう。

Username (leave blank to use 'user_PC'):  # EnterでOK
Email address: # test@example.comと適当なアドレスでOK
Password  # 2回聞かれます。見えませんが、同じものを入力しましょう。

これで準備は完了です!
最後に、次のコマンドを入力して実行しましょう。Starting development server at… の部分に、URLが表示されますから、それをブラウザで起動してみてください。

python manage.py runserver

すると、Usernameとpasswordを求められますので、先ほどログイン情報を作った時の情報を入力しましょう。(Usernameを空欄でEnterした人は、パソコンの名前になると思います。この場合、user_PCですね。)

ログインできたら、下記のような画面が表示されます。ここまでできたら、管理画面の初期状態まで完成です!

管理画面にゴミの情報を登録できるようにする

さて、先ほどの画面まで順調に進められた!と喜んでいたのですが、実はこれではうまくいっていなかったようです。というのも、先ほどの画面はユーザー管理まではできているのですが、肝心なゴミ出しの管理ができていないようです・・・。

chatGPTに聞いてみたところ、次のような原因が考えられました。

これを元に原因を調べてみると、【原因②】 INSTALLED_APPS にアプリ名が記載されていないが怪しそうです。settings.pyを開いてみると、garbageがありませんでした。そこで、これを追加してみます!

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'garbage',  # ← 追加!
]

しかし、それでもうまく動かず、エラーが出てきてしまいます・・・。
さらに調べてみたところ、admin.pyとmodels.pyで、モデルの定義が合っていないことが原因でした。そこで、models.pyに定義されていないGarbageCategoryを定義することにしました。新たに以下のように書き換えます。

from django.db import models

class GarbageCategory(models.Model):
    name = models.CharField(max_length=50)  # 例:燃えるゴミ、プラスチック、紙など

    def __str__(self):
        return self.name


class City(models.Model):
    name = models.CharField(max_length=100)  # 例:札幌市、渋谷区

    def __str__(self):
        return self.name


class CityCategoryName(models.Model):
    city = models.ForeignKey(City, on_delete=models.CASCADE)
    category = models.ForeignKey(GarbageCategory, on_delete=models.CASCADE)
    display_name = models.CharField(max_length=100)  # 地域での呼び名(例:プラゴミ)

    def __str__(self):
        return f"{self.city.name} - {self.display_name}"

また、admin.pyも次のように書き換えました。

from django.contrib import admin
from .models import GarbageCategory, City, CityCategoryName

admin.site.register(GarbageCategory)
admin.site.register(City)
admin.site.register(CityCategoryName)

ここまでできたら、作ってきたプログラムを保存して、データベースに登録していきます。ターミナルで以下のコマンドを実行していきましょう。

python manage.py makemigrations

python manage.py migrate

登録が無事に完了したら、以下のコマンドを実行してサーバーを起動します。表示されたURLに/adminを追加し、管理画面を開いてみましょう。すると、先ほどのユーザー管理の項目の下に、Garbage categoriesができいることがわかります。無事に成功です!

ここまでできれば、手動でグラフィカルにゴミの情報を登録できます!

実行してみよう

ゴミの情報を登録する

データベースがしっかりと動作するか確認するために、ゴミ情報を登録してみましょう。今回は、前回試したように、3通りの燃えるゴミの言い方を登録してみます。

Garbage categorysには、画像のゴミのカテゴリを登録していきます。今は初めて機械学習させたモデルを使いまわしているので4種類で大きく分けていますが、今後、これがゴミ単位ごとに分類するとき(例えば、ちり紙や卵の殻など)に必要になってきます。
登録したら、SAVEを押して緑のチェックマークが出れば成功です。

Citysには、都市の名前が入ります。ここは、登録したい都市の名前を入れていきましょう。今回はお試しで、前回同様に札幌市・千代田区・北九州市を追加していきます。登録したら、Save and add anotherを追加して、3つの都市を追加していきましょう。追加ができると、Citysの項目は次のようになります。

City category namesは、先ほどまで登録してきた都市とカテゴリーから、捨てたいゴミがその地域では何ゴミになるのか、判定を作っていきます。都市の名前とカテゴリーを選択して、その都市ではそのカテゴリーが何ゴミになるのかをDisplay nameに登録していきましょう。三都市登録できたら、データベースの登録は以上です!


登録したデータが正しく動作するか確認してみる

それでは、登録した内容が正しく呼び出せるか、やってみましょう。garbageファイルの中に、新しくutils.pyというファイルを作り、以下のようなプログラムを作ります。

# garbage/utils.py

from .models import City, GarbageCategory, CityCategoryName

def get_local_garbage_name(city_name, common_category_name):
    try:
        city = City.objects.get(name=city_name)
    except City.DoesNotExist:
        return f"{city_name} は登録されていません。"

    try:
        category = GarbageCategory.objects.get(name=common_category_name)
    except GarbageCategory.DoesNotExist:
        return f"{common_category_name} は共通分類として登録されていません。"

    try:
        mapping = CityCategoryName.objects.get(city=city, category=category)
        return mapping.display_name
    except CityCategoryName.DoesNotExist:
        return f"{city_name} に {common_category_name} の分類名は登録されていません。"

その後、Djangoのシェルを開き、関数をインポートさせて実行させてみましょう。今回はこれを3都市分やってみます。すると・・・。

python manage.py shell  # シェルを開く

from garbage.utils import get_local_garbage_name  # 関数をインポート
get_local_garbage_name("札幌市", "燃えるゴミ")  # ”都市”では”燃えるゴミ”が何ゴミか聞く

しっかりと登録した実行結果が返ってきました!

さいごに

今回は、データベースをつかってゴミについてのデータを登録してみました。これをいままで作ってきたwebアプリと合体できれば、データベースの部分はこれで賄えそうです。よければGitHubにも内容をまとめていますので、ご覧ください。

GitHub - iwasakiterukazuimpl/gomi-app at database
ゴミ出しアプリのフォルダ. Contribute to iwasakiterukazuimpl/gomi-app development by creating an account on GitHub.

今後、さらにゴミの種類を増やしたり、LINEなどの身近なSNSに連携できたりしたら、さらに実用的なゴミ出しアプリになりそうです。もう少しでそこまで達成できそうですね!

今回もご覧いただき、ありがとうございました!