モデルの定義
これまでに作成したユーザ、アイテム、評価値テーブルと、各推薦リストテーブルに対応したモデルを定義します。モデルクラスは、recsys_django/online/models.py
に記述します。作成した各テーブルのモデルの定義は下記のコマンドで確認できます。
(venv_recsys_django) $ export DB_USER=rsl
(venv_recsys_django) $ export DB_PASSWORD=【パスワード】
(venv_recsys_django) $ python manage.py inspectdb
上記のコマンドを実行した結果、出力される内容を参考にモデルクラスを定義しましょう。online/models.py
に下記のコードを記述してください。
リスト1: recsys_django/online/models.py
from django.db import models
class User(models.Model):
"""ユーザモデル
Attributes
----------
user_id : IntegerField
ユーザID
name : TextField
ユーザ名
age : IntegerField
年齢
sex : CharField
性別
"""
user_id = models.IntegerField(primary_key=True)
name = models.TextField()
age = models.IntegerField(blank=True, null=True)
sex = models.CharField(max_length=1, blank=True, null=True)
class Meta:
managed = False
db_table = 'users'
def __str__(self):
return '{}:{}'.format(self.user_id, self.name)
class Item(models.Model):
"""アイテムモデル
Attributes
----------
item_id : IntegerField
アイテムID
name : TextField
アイテム名
red : IntegerField
赤身の特徴量
white : IntegerField
白身の特徴量
shining : IntegerField
光物の特徴量
"""
item_id = models.IntegerField(primary_key=True)
name = models.TextField()
red = models.IntegerField(blank=True, null=True)
white = models.IntegerField(blank=True, null=True)
shining = models.IntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'items'
def __str__(self):
return '{}:{}'.format(self.item_id, self.name)
class Rating(models.Model):
"""評価値モデル
Attributes
----------
user : ForeignKey[User]
対象ユーザ
item : ForeignKey[Item]
対象アイテム
rating : IntegerField
評価値
"""
user = models.ForeignKey(User, models.CASCADE)
item = models.ForeignKey(Item, models.CASCADE)
rating = models.IntegerField()
class Meta:
managed = False
db_table = 'ratings'
def __str__(self):
return '{}:{}:{}'.format(self.user_id, self.item_id, self.rating)
class ReclistPopularity(models.Model):
"""人気ベース推薦リストモデル
Attributes
----------
rank : FloatField
推薦順位
item : ForeignKey[Item]
推薦アイテム
score : FloatField
推薦スコア
"""
rank = models.FloatField()
item = models.ForeignKey(Item, models.CASCADE)
score = models.FloatField()
class Meta:
managed = False
db_table = 'reclist_popularity'
def __str__(self):
return '{}:{}:{}'.format(self.rank, self.item, self.score)
class ReclistSimilarity(models.Model):
"""アイテム類似度ベース推薦リストモデル
Attributes
----------
base_item : ForeignKey[Item]
ベースアイテム
rank : FloatField
推薦順位
item : ForeignKey[Item]
推薦アイテム
score : FloatField
推薦スコア
"""
base_item = models.ForeignKey(Item, models.CASCADE, related_name='base_item')
rank = models.FloatField()
item = models.ForeignKey(Item, models.CASCADE)
score = models.FloatField()
class Meta:
managed = False
db_table = 'reclist_similarity'
def __str__(self):
return '{}:{}:{}:{}'.format(self.base_item, self.rank, self.item, self.score)
class ReclistItemcf(models.Model):
"""アイテムベース協調フィルタリングに基づく推薦リストモデル
Attributes
----------
user : ForeignKey[User]
対象ユーザ
rank : FloatField
推薦順位
item : ForeignKey[Item]
推薦アイテム
score : FloatField
推薦スコア
"""
user = models.ForeignKey(User, models.CASCADE)
rank = models.FloatField()
item = models.ForeignKey(Item, models.CASCADE)
score = models.FloatField()
class Meta:
managed = False
db_table = 'reclist_itemcf'
def __str__(self):
return '{}:{}:{}:{}'.format(self.user, self.rank, self.item, self.score)
online/models.py
ではdjango.db.models.Model
クラスを継承した各モデルを定義しています。ユーザモデル、アイテムモデル、評価値モデルは、それぞれUser
、Item
、Rating
クラスとして定義しています。また、各推薦リストモデルはReclist*
クラスとして定義しています。
テーブルのカラムはモデルクラスのクラス属性として定義します。例えば、User
クラスにはname
を定義しています。このクラス属性はField
クラスのインスタンスとして定義します。TextField
はテキストフィールドを表します。必要に応じて、blank
やnull
などのField
クラスのフィールドオプションを指定します。なお、ユーザテーブルとアイテムテーブルにおいては、それぞれuser_id
、item_id
のカラムを主キーとして設定しました。これらに対応して、User
モデルとItem
モデルでは、それぞれに対応するフィールドとしてuser_id
、item_id
のフィールドオプションにprimary_key=True
を設定しています。一方で、Rating
モデルやReclist*
モデルにおいては、明示的には主キーに対応するフィールドを定義していません。主キーフィールドの定義を省略すると、自動的にid
という名前で主キーフィールドが追加されます。
モデルについては、文献[1][2]を参照してください。
モデルの準備ができましたので、マイグレーションを実行します。まず、下記のコマンドでマイグレーションファイルを作成します。
(venv_recsys_django) $ python manage.py makemigrations online
Migrations for 'online':
online/migrations/0001_initial.py
- Create model Item
- Create model Rating
- Create model ReclistItemcf
- Create model ReclistPopularity
- Create model ReclistSimilarity
- Create model User
recsys_django/online/migrations/
ディレクトリに0001_initial.py
が作成されました。下記のコマンドでマイグレーションが実行する内容を確認してみましょう。
(venv_recsys_django) $ python manage.py sqlmigrate online 0001
BEGIN;
--
-- Create model Item
--
--
-- Create model Rating
--
--
-- Create model ReclistItemcf
--
--
-- Create model ReclistPopularity
--
--
-- Create model ReclistSimilarity
--
--
-- Create model User
--
COMMIT;
このようにSQLが出力されました。ただし、今回はいずれも既にテーブルを作成済みですので、マイグレーションにより新規にテーブルが作成されることはありません。では、マイグレーションを実行してみましょう。
(venv_recsys_django) $ python manage.py migrate
Operations to perform:
Apply all migrations: accounts, admin, auth, contenttypes, online, sessions
Running migrations:
Applying online.0001_initial... OK
マイグレーションの詳細は文献[2][3]を参照してください。
参考
- はじめての Django アプリ作成、その2 | Django ドキュメント | Django # モデルの作成
- 現場で使える Django の教科書《基礎編》 # 第6章 モデル (Model)
- 現場で使える Django の教科書《基礎編》 # 第11章 データベースのマイグレーション