※ 本記事はnote投稿の転載です。
※ https://note.com/super_crow2005/n/n83e29e68c301
(7)食材情報を参照・設定しやすくする
前回まで、「鰈(カレイ)の唐揚げ」「シャリアピン牛もも肉ステーキ」「パイナップル牛モモ肉アスパラパプリカ」の、3つの料理レシピでタートルファイル形式のファイルを作成したのだが、まったく同じ手順で、また記載項目も同じで作成できた。違いは文言が違い、また材料一覧やステップの数が違うくらいであった。
もはや、形式的な作業である。というか、そもそもデータベースのデータ登録というのは、データの構成を決めてしまい、生データと呼ばれる関連付けなどされていないデータを、所定の構成に変換してデータベースに格納するのである。
今回は、すぐに変換しなかったのであるが、これはIRIの命名規則のことを気にしていたこともあった。しかし、それだけではない。食材の取り扱いが懸念材料であった。実際、前回で食材オントロジーをチェックしながら作業しなければならないことがわかった。
レシピを新たに追加する際に、食材のクラスが定義されているかを確認し、またそれまでの作成したレシピのデータで、食材のインディビデュアルが作成されていないかを確認し、その上で追加すべき食材のインディビデュアルを明らかにする必要がある。特に気になるのは食材クラスの準備の方であって、クラス体系が良いものかどうなのかも、まだ検討する必要があると筆者は考えている。
そこで、まずcookpadのmoritoshが作成したレシピのための食材をすべて調べて、先にfood_material.rdfを完成させてしまう方が良いのではないかと考えた。最終的には食材管理システムみたいなものが必要なのだろうが、今はそのような大がかりなことは考えず、まず利用する食材と体系を確認するあたりの検討が先だろう。
食材のインディビデュアルについても、いままでは使うものだけを作成していたが、全てのクラスに対して、あらかじめ同名のIRIのインディビデュアルを作っておいた方が、今の規模であるなら処理が単純になるので合理的かもしれない。
以上の観点で、cookpadのmoritoshのレシピより、食材オントロジーの拡充を図ることにする。
まず、cookpadにmoritoshが投稿した116レシピの材料一覧をすべてエクセルにコピーし、[データ]-[並べ替えとフィルター]を使ってソートして、食材の部分だけを取り出し、重複は排除して一覧とする。このとき、異なる名前で書いている食材の名称を一つにする。例えば、タマネギ、たまねぎ、玉ねぎ、玉葱は、たまねぎとする、といったことである。
食材の数は230個あった。ここで気が付いたことは、大分類が足りないということだった。これまで伊藤玲子『初めての中華料理 基本とコツ』西東社、1998の巻末についている分類表を参考に大分類をしてきたのだが、食材表にある食材は70個ほどだったのである。
そこで、食材が増えても大丈夫なように、香川芳子『四訂食品成分表2000』女子栄養大学出版部の大分類を参考とすることにした。もちろん食品成分表は直接に「食べ物」となる材料だけの一覧となるので、水や重曹は対象に入っていない。そこで、「水・スープなど」と「食品添加物」という大分類を設けた。
大分類は次のようにした。owl:Thing-食材クラスのサブクラスとなる。
いも及びでん粉類、きのこ類、乳類、卵類、嗜好飲料類、果実類、水・スープなど、油脂類、獣鳥鯨肉類、砂糖及び甘味類、種実類、穀類、菓子類、藻類、調味料及び香辛料類、調理加工食品類、豆類、野菜類、食品添加物、魚介類
この分類は、植物関係を、いも及びでん粉類、きのこ類、穀類、藻類、豆類、野菜類と分けている点が食材をバランスよく分類するのによいのだ。それでいて料理的にも食事的にも役割が対応して、わかりやすい。またスーパーの食品コーナーの分類とも関係している。結構、農産の観点からも妥当な分類なのかもしれない。意識していないと、穀類以外は単に野菜としてしまいたくなるが、それでは野菜がとても大きな集合になってしまうのである。
なお、ごぼう、にんじんは野菜である。スーパーで売り場が近いこんにゃくと豆腐は、それぞれいも類と豆類で違う。さやいんげんは豆類だがさやえんどうは野菜であり、グリーンピースも野菜である。理由はあるのだろうが、これを多くの人が受け入れるかということが問題だろう。オントロジーには人々の共通の概念として、情報の交換を容易とする意味もある。食品成分表は、第一訂は昭和25年(1950)の初版であり、栄養学の基礎資料として、栄養士・調理師、また主婦が主なユーザとなっているようだ。また、ほかの分離としては生物学的な分類となるであろうが、料理向けとして整理されているものは見当たらなかった。さやいんげん、グリーンピースを野菜と分類する理由、根拠はあるのだろうが、豆としても分類できた方が良いのではなかろうか。
幸い、ウェブオントロジー言語OWLは、多重継承を許している。protégéのEntitiesタブの左側Classesタブのツリーで、野菜類クラスの下にさやえんどうクラスを作っておいて、さらに右下のDescription:さやえんどう欄のSubClass Of (+)でオブジェクトプロパティダイアログのClass Hierarchyツリーで豆類のクラスを設定すれば、さやえんどうは豆類でもあり、また野菜類でもあると設定できる。分類体系については根拠を明確にする必要があるが、分類をわかりやすくするような「使い勝手」の工夫はできるだろう。
<!-- http://www.onto.org/life/food/material#さやえんどう -->
<owl:Class rdf:about="http://www.onto.org/life/food/material#さやえんどう">
<rdfs:subClassOf rdf:resource="http://www.onto.org/life/food/material#豆類"/>
<rdfs:subClassOf rdf:resource="http://www.onto.org/life/food/material#野菜類"/>
</owl:Class>
ともかくも、分類は『四訂食品成分表2000』を参照して、既にfood_material.rdfにある食材と、cookpadでmoritoshが材料一覧に挙げた食材を並べて、食材の名称を統一してリストを作ったのだった。オントロジーを記述するには、まずはprotégéで個別にクラスを少し作成して、RDFファイルを出力して、生成された記述をほかのクラスやインディビデュアルにもコピーすると効率的にオントロジーを記述できるのであった。
例えば、XO醤クラスは次のように記述される。
<owl:Class rdf:about="http://www.onto.org/life/food/material#XO醤">
<rdfs:subClassOf rdf:resource="http://www.onto.org/life/food/material#調味料及び香辛料類"/>
</owl:Class>
これを見ると、XO醤という対象のクラスと、XO醤の直接の親クラスの調味料及び香辛料類の組がわかっていればよいのである。したがって、次のような簡単なpythonコードでクラス定義の記述を作れる。[クラス名、親クラス名]というリストlの、すべての食材のリストllを使う。ここでクラス名、親クラス名はIRIのファセット#より右の部分とする。
for l in ll:
txt_l.append('<owl:Class rdf:about="http://www.onto.org/life/food/material#' + l[0] + '">')
txt_l.append(' <rdf:subClassOf rdf:resource="http://www.onto.org/life/food/material#' + l[1] + '"/>')
txt_l.append('</owl:Class>')
with open('t.txt', 'w', encoding='utf-8') as f:
for item in txt_l:
f.write(item + '\n')
テキストファイルt.txtの内容をfood_material.rdfにコピペすればクラスの定義が得られる。
これまで、インディビデュアルについては、料理レシピを作成するときに、材料項目の定義を記述する直前に作成していた。しかし、料理レシピの種類にかかわらず食材のオントロジーは設定れていてもおかしいことではなく、むしろ事前にすべて食材は整えられている方が自然であろう。というのは、料理レシピを考案する以前に食材は存在してるということである。ただし、データベースを実際に作るという観点で、料理レシピ作成の度に、必要なものを追加していくこととしたのであった。
実際、食材のクラスに対し同名のIRIのインディビデュアルが一つ作成されれば良いので、これは食材オントロジーfood_material.rdfに入れておいても、クラスを定義したファイルとして、記述量(ファイルサイズ)をそんなに多くするものでもなく、内容を複雑にするようなことでもないだろう。そこでクラスに対して同名のインディビデュアルもまとめて作成する。
例えば、XO醤クラスに対して、そのインディビデュアルは次のように記述される。
<owl:NamedIndividual rdf:about="http://www.onto.org/life/food/material#XO醤">
<rdf:type rdf:resource="http://www.onto.org/life/food/material#XO醤"/>
</owl:NamedIndividual>
クラス名もインディビデュアル名も同じなので、その名前(IRI)だけがあるとよい。pythonでは次でよい。
for e in l:
txt_l.append('<owl:NamedIndividual rdf:about="http://www.onto.org/life/food/material#' + e + '">')
txt_l.append(' <rdf:type rdf:resource="http://www.onto.org/life/food/material#' + e + '"/>')
txt_l.append('</owl:NamedIndividual>')
with open('t.txt', 'w', encoding='utf-8') as f:
for item in txt_l:
f.write(item + '\n')
作成したファイルを添付する。以降はこのファイルを食材オントロジーfood_material.rdfとする。
ファイル:food_material_new.rdf
https://note.com/api/v2/attachments/download/4cf1868f83eda43c8ab791ed49f36a20
以上で、食材のデータが整った。
