cpilens: Thai CPI item classifier (XLM-R, fine-tuned)

Assigns a product text to one of the 28 in-scope items of the Thai consumer price index (base 2566 / 2023) or to OOS (out of scope). The input is the product's name, brand and quantity joined as name | brand | quantity; names are usually in Thai, sometimes in English.

This is the fine-tuned encoder of the paper How much does product classification cost in basis points?, trained on all official labels. The paper's purpose is to measure what a classifier's errors do to measured inflation, so the numbers below include that, not accuracy alone.

Scores, and why you should read the second column

On 3,910 held-out official price-collection specifications published by Thailand's Ministry of Commerce (2,410 of them in scope), scored with CPI expenditure weights:

Metric This model For comparison
Expenditure-weighted accuracy 69.5% 97.9% (Claude Opus 5.5 prompted)
Accuracy over the whole held-out list 87.1% 93.8% (Claude Opus 5.5)
Macro-F1 59.7% 94.4% (Claude Opus 5.5)
Headline year-on-year inflation error (RMSE, basis points) 8.3 1.9 (Claude Opus 5.5)
Food year-on-year inflation error (RMSE, basis points) 22.3 3.2 (Claude Opus 5.5)

A frontier LLM is far better at this task. The paper's finding is that prompting Claude Opus 5.5 reaches 97.9% of the evaluated CPI weight against 69.5% here, and that this model would understate Thai food inflation in every simulated month. This encoder is published for reproducibility and as a cheap local baseline (about USD 0.09 per million products against USD 2,014.73 for the LLM), not as the recommended classifier.

It also misses whole items: every held-out specification of fresh meat, freshwater fish, processed fish and tobacco is misclassified (each a small item, with 1 to 17 held-out specifications), and most personal-care specifications go to OOS.

Use

from transformers import pipeline

clf = pipeline("text-classification", model="thanatchon36/cpilens-xlmr-thcpi")
clf("นมสดรสจืด | โฟร์โมสต์ | 200 มล.")  # -> [{'label': '11320', 'score': ...}]

Labels are TPSO item codes (11320 is milk and dairy products) plus OOS. labels.csv in this repository gives each code's English name and its COICOP 2018 class. The scores from pipeline are raw softmax; the paper calibrates them with one temperature fitted on a validation split, which cpilens applies (https://github.com/thanatchon36/cpilens).

Training

Fine-tuned from FacebookAI/xlm-roberta-base with a classification head on all official labels: at most 4 epochs, batch 64, AdamW at $3\times 10^{-5}$ with linear warm-up and decay, inputs truncated to 64 tokens, class weights proportional to the inverse square root of class frequency, early stopping on validation loss. The official-label pool holds 24,456 specifications; whole sub-items are held out, so no test specification's sub-item is seen in training. One training run, one seed (20261027).

Intended use, and what this is not for

For research on the measurement error that product classification adds to price statistics, and as a baseline for Thai or other non-English product text. Not for producing official statistics without validation on your own data, and not for any decision about a person or a firm. The reference text is the statistical office's own short specifications; shop and database listings are longer and noisier, and accuracy on them will be lower. The specifications are public and may have been seen in pre-training by other models the paper compares against.

Training data, licences and attribution

  • Product text and weak labels: Open Food Facts and Open Beauty Facts, © Open Food Facts contributors, under the Open Database License (ODbL) 1.0. A model trained on an ODbL database is a Produced Work: this notice is the attribution ODbL asks for. If you extract a derived database from this work, ODbL's share-alike terms apply to it.
  • Official labels: price-collection specifications published as open data by the Ministry of Commerce, Thailand, compiled by the Trade Policy and Strategy Office (TPSO); CPI indices and weights from TPSO.
  • Base model FacebookAI/xlm-roberta-base: MIT.

Every source, with its URL, retrieval date, licence and checksum, is listed in data/SOURCES.md.

No training corpus is published here. The Thai government source pages state no licence, so this project does not redistribute their files; the repository publishes the held-out labels as item codes without the official text (data/reference_set.csv in the repository), and make data rebuilds the full corpus from the sources with checksums.

Citation

@misc{chongmankhong2026cpilens,
  author = {Chongmankhong, Thanatchon},
  title  = {How much does product classification cost in basis points?
            Multilingual classification of Thai product text for consumer price measurement},
  year   = {2026},
  doi    = {10.5281/zenodo.23686886},
  url    = {https://thanatchon36.github.io/cpilens/paper/}
}

Code, data and the paper: https://github.com/thanatchon36/cpilens. Every number above is generated by code from results/; nothing is typed by hand.

The views expressed are the author's own and do not necessarily reflect those of the Bank of Thailand. This work uses only publicly available data. This is independent work, not a BIS, ECB or Bank of Thailand publication, and its numbers are not directly comparable with the BIS Innovation Hub's Project Spectrum.

Downloads last month
45
Safetensors
Model size
0.3B params
Tensor type
F32
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for thanatchon36/cpilens-xlmr-thcpi

Finetuned
(4,308)
this model

Dataset used to train thanatchon36/cpilens-xlmr-thcpi