官网:GitHub - openfoodfacts/robotoff: 🤖 Real-time and batch prediction service for Open Food Facts
Robotoff是一个由Open Food Facts社区开发的实时和批量预测服务,旨在提升食品数据的准确性和完整性。以下是对Robotoff的详细介绍:
- 项目背景与目的:
- Robotoff是Open Food Facts项目的一部分,后者是一个开放的数据库,包含全球食品产品的营养成分、过敏原信息、添加剂等数据。
- Robotoff利用机器学习技术,自动化地识别和纠正食品数据中的错误,帮助用户更快更准确地找到他们需要的产品信息。
- 技术特点:
- 实时预测服务:Robotoff能够实时分析新提交的数据,预测潜在的错误或缺失的信息。
- 批量处理:除了实时处理外,Robotoff还支持批量处理已有的数据,帮助清理和更新整个数据库。
- 机器学习驱动:通过训练模型,Robotoff能够学习如何识别数据中的模式,从而做出更准确的预测。
- 应用场景:
- 消费者保护:提供准确的产品信息,帮助消费者做出更健康的饮食选择。
- 商家支持:为食品生产商提供数据清理工具,确保他们的产品信息在市场上的准确性。
- 科学研究:为营养学、食品科学等领域的研究提供可靠的数据基础。
- 开源与协作:
- Robotoff是开源项目,欢迎任何人贡献代码、数据和想法。
- 通过GitHub等平台,Robotoff社区成员可以共同改进项目,确保数据的持续更新和准确性。
- AGPL-3.0许可:
- Robotoff遵循AGPL-3.0许可证,这意味着任何人都可以自由地使用、修改和分发项目,但必须遵守一定的条件和限制。
- 安全性:
- Robotoff团队重视数据安全和隐私保护,制定有相应的安全政策来确保用户数据的安全。
- 社区与贡献:
- Open Food Facts和Robotoff拥有庞大的全球用户社区,他们积极参与数据的收集、验证和更新工作。
- 鼓励用户通过报告错误、提供反馈或参与项目开发等方式为Robotoff做出贡献。
Robotoff是一种高效管理潜在开放食品数据更新(亦称见解)与预测的服务,这些预测经过整合后能够生成深入的见解。这些见解涵盖了多元化的关键事实,包括但不限于产品类别、重量、品牌信息、包装商代码以及有效期等详细资料。此外,Robotoff还关注于处理特定类型的标签内容、识别不适宜的照片(如非产品相关的自拍)、以及优化图像展示(如自动旋转图片)。
Robotoff提供了功能强大的API接口,允许用户执行以下操作:
- 获取见解:轻松获取由系统生成的最新、最全面的食品数据见解。
- 注释见解:支持用户直接通过API对见解进行审核,选择接受或拒绝,确保数据的准确性与可靠性。
生成的见解可自动应用于系统,或根据需求在经过人工仔细验证后应用,以确保数据质量的严格把控。同时,内置的调度器会定期将见解标记为待审核状态,以促进自动化的注释流程,并将核准后的更新无缝推送到Open Food Facts数据库,进一步丰富和完善全球食品信息库。
安装
看来需要python3.11版本
apt install python3.11
然后安装包
python3.11 -m pip install openfoodfacts robotoff
安装的时候matplotlib有可能会卡住,这时候使用apt安装
apt install python3-matplotlib
在安装robotoff的时候,很容易卡住,现在还没找到解决办法。
在AIStudio 卡在numpy,手工安装apt install python3-numpy,然后再安装特定的numpy版本,过不去。
在Kaggle卡在peewee,过不去。
测试
首先下载数据集
First, download the dataset: python -m robotoff download-dataset
python3.11 -m robotoff download-dataset
下载数据集的时候报错。。。。
测试代码:
from robotoff.products import ProductDataset
ds = ProductDataset.load()
product_iter = (ds.stream()
.filter_by_country_tag('en:france')
.filter_nonempty_text_field('ingredients_text_fr')
.filter_by_state_tag('en:complete')
.iter())
for product in product_iter:
print(product['product_name'])
总结
目前没有测试成功,有些环境下是一些依赖库装不上,有些是下载数据集的时候报错。。。
调试
执行报错No such file or directory: '.local/lib/python3.11/site-packages/datasets/products.jsonl.gz'
>>> for product in product_iter:
... print(product['product_name'])
... break
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/skywalk/.local/lib/python3.11/site-packages/robotoff/products.py", line 253, in __iter__
yield from self.iterator
File "/home/skywalk/.local/lib/python3.11/site-packages/robotoff/products.py", line 264, in <genexpr>
filtered = (
^
File "/home/skywalk/.local/lib/python3.11/site-packages/robotoff/products.py", line 293, in <genexpr>
filtered = (
^
File "/home/skywalk/.local/lib/python3.11/site-packages/robotoff/products.py", line 256, in <genexpr>
filtered = (
^
File "/home/skywalk/.local/lib/python3.11/site-packages/robotoff/utils/__init__.py", line 77, in gzip_jsonl_iter
with gzip.open(jsonl_path, "rt", encoding="utf-8") as f:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/gzip.py", line 58, in open
binary_file = GzipFile(filename, gz_mode, compresslevel)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/gzip.py", line 174, in __init__
fileobj = self.myfileobj = builtins.open(filename, mode or 'rb')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/home/skywalk/.local/lib/python3.11/site-packages/datasets/products.jsonl.gz'
下载数据集报错
python3.11 -m robotoff download-dataset
2024-09-16 08:32:19,267 :: MainProcess :: MainThread :: ERROR :: Exception raised during dataset iteration
Traceback (most recent call last):
File "/home/skywalk/.local/lib/python3.11/site-packages/robotoff/products.py", line 190, in is_valid_dataset
count = dataset.count()
^^^^^^^^^^^^^^^
File "/home/skywalk/.local/lib/python3.11/site-packages/robotoff/products.py", line 392, in count
for _ in self.stream():
File "/home/skywalk/.local/lib/python3.11/site-packages/robotoff/products.py", line 253, in __iter__
yield from self.iterator
File "/home/skywalk/.local/lib/python3.11/site-packages/robotoff/utils/__init__.py", line 78, in gzip_jsonl_iter
yield from jsonl_iter_fp(f)
File "/home/skywalk/.local/lib/python3.11/site-packages/robotoff/utils/__init__.py", line 82, in jsonl_iter_fp
for line in fp:
File "/usr/lib/python3.11/gzip.py", line 314, in read1
return self._buffer.read1(size)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/_compression.py", line 68, in readinto
data = self.read(len(byte_view))
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/gzip.py", line 499, in read
if not self._read_gzip_header():
^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/gzip.py", line 468, in _read_gzip_header
last_mtime = _read_gzip_header(self._fp)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/gzip.py", line 428, in _read_gzip_header
raise BadGzipFile('Not a gzipped file (%r)' % magic)
gzip.BadGzipFile: Not a gzipped file (b'<h')
下载代码的源码是:
@app.command()
def download_dataset(minify: bool = False) -> None:
"""Download Open Food Facts dataset and save it in `datasets` directory."""
from robotoff.products import fetch_dataset, has_dataset_changed
from robotoff.utils import get_logger
get_logger()
if has_dataset_changed():
fetch_dataset(minify)
def fetch_dataset(minify: bool = True) -> bool:
with tempfile.TemporaryDirectory() as tmp_dir:
output_dir = Path(tmp_dir)
output_path = output_dir / "products.jsonl.gz"
etag = download_dataset(output_path)
logger.info("Checking dataset file integrity")
if not is_valid_dataset(output_path):
return False
if minify:
minify_path = output_dir / "products-min.jsonl.gz"
logger.info("Minifying product JSONL")
minify_product_dataset(output_path, minify_path)
logger.info("Moving file(s) to dataset directory")
shutil.copy(str(output_path), settings.JSONL_DATASET_PATH)
def minify_product_dataset(dataset_path: Path, output_path: Path):
if dataset_path.suffix == ".gz":
jsonl_iter_func = gzip_jsonl_iter
else:
jsonl_iter_func = jsonl_iter
with gzip.open(output_path, "wt", encoding="utf-8") as output_:
for item in jsonl_iter_func(dataset_path):
available_fields = Product.get_fields()
minified_item = dict(
(
(field, value)
for (field, value) in item.items()
if field in available_fields
)
)
output_.write(json.dumps(minified_item) + "\n")
后面查到文件相关
地址:settings.JSONL_DATASET_PATH JSONL_DATASET_PATH = DATASET_DIR / "products.jsonl.gz"
URL
JSONL_DATASET_URL = (
BaseURLProvider.static(ServerType.off) + "/data/openfoodfacts-products.jsonl.gz"
)