Kaggle Dataset ”Open Food Facts”の探索的解析(EDA)(2)
ーどん兵衛の栄養成分類似の海外商品の探索ー
カテゴリー: データサイエンス
作成日: 2023-02-15
Kaggleは世界最大級のデータサイエンスコンペティションプラットホームです。Kaggleは企業や行政などの組織とデータサイエンティスト/機械学習エンジニアを結びつけるプラットホームとなっていて、コンペティションの他に、約20万弱のdatasetとそれらdatasetの解析や機械学習モデルのプログラムcodeが投稿されています。どのようなデータが公開されているかを知ることができ、さらにデータ解析や機械学習モデル作成するためのアルゴリズムの知識を深め、そのプログラミングをトレーニングすることができます。
前報告Kaggle Dataset ”Open Food Facts”の探索的解析(EDA)(1)ではKaggleのdatasetOpen Food Factsのデータから日本の食品の「日清のどん兵衛 きつねうどん」を見つけました。
今回は、「日清のどん兵衛 きつねうどん」の栄養成分に類似の海外の食品をこのOpen Food Factsのdatasetで探索しました。
dataset "Open Food Facts"と解析手順
Open Food Factsは、非営利団体による世界中の食品の成分、アレルゲン、栄養成分、製品ラベルに記載されているあらゆる情報を含む、フリーでオープンなデータベースです。Android、iPhonなどのアプリやカメラを使ってバーコードスキャンし、商品やラベルの画像をアップロードすることで、5000人以上の協力者が150カ国から600,000以上の商品を追加しています。
Open Food Factsのdatasetへのアクティビティ
非常に多くのアクセスとダウンロードがされていて、500を超えるデータ解析プログラムのNotebookも投稿されています。
- Votes(いいね): 1,108
- Views: 398,079
- Downloads: 56,919
- Notebooks(プログラムコード): 504
Open Food Factsのdatasetの構成
datasetには、1 つの表がtsv形式で格納されています。ファイル容量は約1GBです。
- ファイル形式: tsv
- ファイル容量: 1.0 GB
- 列数(データ項目): 163
- 行数(データ数): 356,027
今回のデータ解析手順
Pythonで作成したプログラムにて下記の手順で解析しました。
- ダウンロードしたzipファイルの解凍
- データファイルの読み込み
- 'product_name'が欠損してない行を抽出
- 'fat_100g', 'carbohydrates_100g', 'proteins_100g', 'salt_100g'のどれかが欠損のデータを削除
- 'fat_100g', 'carbohydrates_100g', 'proteins_100g', 'salt_100g'の値でcosign simirality*とノルム値*を計算
*cosign_simiralityはベクトルの方向性の類似度を表します。
*ノルム値はベクトルの長さを表します。
「日清のどん兵衛 きつねうどん」に各栄養成分量(cosign-simiralityとノルム値がともに)が近い食品
フランスと米国のインスタント麺が抽出されました。なお、商品名の和訳は、英語名は筆者が、フランス語名はdeepl翻訳で和訳しました。
product_name | 商品名(和訳) | countries | fat _100g |
carbo hydrates _100g |
proteins _100g |
salt _100g |
---|---|---|---|---|---|---|
日清のどん兵衛 きつねうどん | 日本 | 16.2 | 56.0 | 9.2 | 5.8 | |
Nouilles instantanées arôme de végétable | 野菜風味のインスタント麺 | France | 18.6 | 61.2 | 9.1 | 6.5 |
Cup Noodles Chicken Flavor | カップヌードルチキン風味 | United States | 17.2 | 62.5 | 10.9 | 9.3 |
Bowl Noodle Soup, Hot & Spicy | ボウルヌードル、ホット & スパイシー | France | 18.6 | 61.2 | 9.1 | 6.5 |
Nouilles chinoises arôme de porc | 豚肉風味の中華麺 | France | 17.8 | 63.4 | 9.5 | 6.0 |
「日清のどん兵衛 きつねうどん」の栄養成分比(cosign-simirality)が近い食品を抽出
偶然か、必然なのか面白いことに、パスタソースが多く抽出されました。美味しさや嗜好性に関係があるかもしれません。フランスの育児用粉ミルクも栄養成分比が近いです。
product_name | 商品名(和訳) | countries | fat _100g |
carbo hydrates _100g |
proteins _100g |
salt _100g |
cos _simirality |
---|---|---|---|---|---|---|---|
日清のどん兵衛 きつねうどん | 日本 | 16.2 | 56.0 | 9.2 | 5.8 | 1.0 | |
Premium Pasta Sauce | プレミアム パスタ ソース | US | 2.8 | 9.6 | 1.6 | 0.95 | 0.99998 |
Pasta Sauce, Roasted Garlic | パスタソース、ローストガーリック | US | 2.82 | 9.68 | 1.61 | 0.92 | 0.99996 |
Lait De Croissance En Poudre | 成長期粉ミルク | France | 2.48 | 8.49 | 1.52 | 0.88 | 0.99990 |
Sauce spaghetti cuisinée | 調理済みスパゲティソース | France | 2.5 | 9.2 | 1.5 | 0.92 | 0.99987 |
Mouliné de tomates oignons et pointe d'herbes | トマト、オニオン、ハーブのピューレ | France | 4.5 | 15.0 | 2.3 | 1.7 | 0.99986 |
Pythonによるプログラムのコード
実際に解析に用いたプログラムのコードです。あくまで参考です。自己責任で適当に編集して試してください。
開発・実行環境:Google Colaboratory
ダウンロードしたzipファイルの解凍
datasetのあるサイトページからダウンロードするとzipファイルでダウンロードされますので、解凍します。tsvファイルが保存されます。
# Import
import shutil
# unpack
filename = 'en.openfoodfacts.org.products.tsv.zip'
shutil.unpack_archive(filename, 'unzip')
データの読み込みと抽出
# Import
import pandas as pd
import numpy as np
from tqdm import tqdm
# tsvデータの読み込み
filename = 'en.openfoodfacts.org.products.tsv'
df = pd.read_csv(filename, delimiter='\t', encoding='utf-8')
# 列'product_name'のデータ型を文字型に変換
df.product_name = df.product_name.astype(str)
# 'product_name'がnan(欠損値)の行を除く
df_02 = df[df['product_name'] !='nan']
# 'fat_100g', 'carbohydrates_100g', 'proteins_100g', 'salt_100g', 'sodium_100g' のどれかが欠損値または0の行を削除
df_03 = df_02.dropna(subset=['fat_100g', 'carbohydrates_100g', 'proteins_100g', 'salt_100g'])
df_04 = df_03.query('fat_100g > 0 & carbohydrates_100g > 0 & proteins_100g > 0 & salt_100g > 0')
# cosign simiralityを計算
cs_l = []
for i in tqdm(range(169994)):
fat = float(df_04['fat_100g'][i:i+1])
carb = float(df_04['carbohydrates_100g'][i:i+1])
pro = float(df_04['proteins_100g'][i:i+1])
salt = float(df_04['salt_100g'][i:i+1])
b = np.array([fat, carb, pro, salt])
cos = np.dot(donbe, b)/(np.sqrt(np.dot(donbe, donbe)) * np.sqrt(np.dot(b, b)))
cs_l.append(cos)
# 降順にソート
df_05sort = df_05.sort_values('cos_sim', ascending=False)
df_05sort.head()
# cos-simランク20でノルム値(ベクトルの長さ)が近い商品
norm_l = []
for i in tqdm(range(20)):
fat = float(df_05sort['fat_100g'][i:i+1])
carb = float(df_05sort['carbohydrates_100g'][i:i+1])
pro = float(df_05sort['proteins_100g'][i:i+1])
salt = float(df_05sort['salt_100g'][i:i+1])
b = np.array([fat, carb, pro, salt])
norm = np.sqrt(np.dot(b, b))
norm_l.append(norm)
df_06 = df_05sort.head(20)
df_06['norm'] = norm_l
norm_dobe = 59.306062
dif_norm = []
for norm in df_06['norm']:
dif = abs(norm_dobe - norm)
dif_norm.append(dif)
df_06['dif_norm'] = dif_norm
df_06sort_normdif = df_06.sort_values('dif_norm')
df_06sort_normdif.head(10)