Text Classification
Scikit-learn
Portuguese
ncm
classificacao-fiscal
agronegocio
scikit-learn
skops
tfidf
Instructions to use AmandaGondra/ncm-classifier with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Scikit-learn
How to use AmandaGondra/ncm-classifier with Scikit-learn:
# ⚠️ Model filename not specified in config.json
- Notebooks
- Google Colab
- Kaggle
|
Download README.md from AmandaGondra/ncm-classifier: direct link, hf CLI and curl.
- Browser
- Download file 10.4 kB
-
https://huggingface.co/AmandaGondra/ncm-classifier/resolve/main/README.md
- Command line
-
hf download hf://AmandaGondra/ncm-classifier/README.md
-
curl -L -o README.md https://huggingface.co/AmandaGondra/ncm-classifier/resolve/main/README.md
10.4 kB
| language: pt | |
| license: mit | |
| library_name: sklearn | |
| pipeline_tag: text-classification | |
| tags: | |
| - ncm | |
| - classificacao-fiscal | |
| - agronegocio | |
| - scikit-learn | |
| - skops | |
| - tfidf | |
| datasets: | |
| - AmandaGondra/ncm-classifier-dataset | |
| # NCM Classifier — sugestão de posição NCM para produtos do agro | |
| > **Aviso.** Este modelo dá **sugestões**, não decisões fiscais. A responsabilidade pela | |
| > classificação fiscal permanece com quem emite a nota. Na dúvida, consulte um profissional | |
| > habilitado. | |
| ## Identificação | |
| | | | | |
| |---|---| | |
| | Modelo | `AmandaGondra/ncm-classifier` | | |
| | Versão | v0.1.0 (publicado em 2026-11-03) | | |
| | Autora | Amanda Gondra | | |
| | Arquitetura | TF-IDF (palavras 1–2 e caracteres 3–5) + regressão logística com classes balanceadas, calibração por temperatura e regra legal da posição 31.05 | | |
| | Modelo pré-treinado | nenhum (treinado do zero com scikit-learn 1.9.1) | | |
| | Código | [https://github.com/amanda-gondra/ncm-classifier](https://github.com/amanda-gondra/ncm-classifier), commit `a03a54f1d0973966b0babc8fb846e681197b07e2` | | |
| | Formato | `model.skops` (sem pickle) | | |
| ## Descrição | |
| A partir da descrição comercial de um produto agropecuário ("Ureia agrícola saco 50 kg", | |
| "Arame farpado 500 m"), o modelo sugere as **três posições NCM mais prováveis** (4 dígitos), | |
| com a confiança calibrada da primeira. Quando a confiança fica abaixo de um limiar, marca a | |
| sugestão para **revisão manual**. | |
| O problema: quem vende para o produtor rural precisa informar a NCM na nota fiscal, e as | |
| descrições comerciais raramente usam a linguagem da tabela. | |
| Etapas da inferência, iguais às da avaliação: | |
| 1. **Normalização do texto:** minúsculas, sem acentos, fórmulas NPK, unidades e abreviações | |
| padronizadas. | |
| 2. **Probabilidades** da regressão logística. | |
| 3. **Calibração por temperatura:** `softmax(log p / T)`, com T = 0.4012. | |
| 4. **Regra 31.05**, do texto legal da posição: mercadorias do Capítulo 31 em embalagens de até | |
| 10 kg vão para a 31.05. | |
| 5. **Três sugestões e revisão:** volta o top-3; a sugestão vai para revisão quando a confiança | |
| final for menor que 0.6525. | |
| ## Uso pretendido | |
| - **Público:** quem emite nota de produtos agropecuários (lojas, revendas, cooperativas) e quer | |
| um ponto de partida para a classificação. Também serve como exemplo de engenharia de ML. | |
| - **Cenários:** sugerir a NCM numa tela de cadastro de produtos; triar descrições para revisão. | |
| - **Fora do uso pretendido:** decidir a NCM sem revisão humana; produtos fora das posições | |
| abaixo; classificação em 8 dígitos (subitem). | |
| Posições cobertas (nível de posição, 4 dígitos): | |
| | Grupo | Posições | | |
| |---|---| | |
| | Animais e produtos de origem animal | 01.02, 01.03, 01.04, 01.05, 04.07, 05.11 | | |
| | Sementes, grãos e forragens | 07.13, 10.05, 10.06, 10.07, 12.01, 12.09, 12.13, 12.14 | | |
| | Rações, suplementos e sal | 23.02, 23.04, 23.09, 25.01 | | |
| | Adubos | 31.01, 31.02, 31.03, 31.04, 31.05 | | |
| | Defensivos agrícolas | 38.08 | | |
| | Ferramentas, arames e cercas | 72.17, 73.13, 73.14, 73.17, 82.01, 85.43 | | |
| | Máquinas e implementos agrícolas | 84.24, 84.32, 84.33, 84.34, 84.36, 87.01, 87.16 | | |
| 37 posições no total. | |
| ## Dados de treinamento | |
| - **Linhas:** 900 (marketplace: 241, ncm_official: 359, public_reference: 1, synthetic: 299). | |
| - **Fontes:** | |
| - descrições comerciais reais de anúncios e catálogos; | |
| - descrições da própria tabela NCM oficial; | |
| - descrições sintéticas, geradas com um LLM e revisadas uma a uma. | |
| - **Rotulagem:** feita à mão, com a regra legal anotada em cada linha. A fonte comprova a | |
| descrição, não a classificação. | |
| - **Pré-processamento:** a normalização descrita acima. Quase-duplicatas dos testes foram | |
| removidas do treino (Jaccard de 5-gramas de caracteres ≥ 0,8), e nenhuma fonte do treino | |
| coincide com uma fonte de teste. | |
| - **Dados sintéticos:** foram escritos depois do primeiro teste (test_v1) existir. Por isso foi | |
| criado um segundo teste independente (test_v2); nele, o ganho dos sintéticos foi menor, mas | |
| se manteve. | |
| - **Versão dos dados:** SHA-256 do arquivo de treino `2c075ec49ffcbba81b6e324c36e9bf9d06439d54c603cbe2dc790622b3f85a18`. | |
| - **Parte publicada:** só as linhas oficiais e sintéticas estão em | |
| [`AmandaGondra/ncm-classifier-dataset`](https://huggingface.co/datasets/AmandaGondra/ncm-classifier-dataset). As descrições de anúncios | |
| não são redistribuídas. | |
| ## Avaliação | |
| ### Protocolo | |
| - **Escolha do C:** validação cruzada estratificada em 5 dobras no treino (impressão digital | |
| das dobras: `59611f6771f10d2c601009368dd868d2f83dcc91e3353a3340e1c2803f438cd0`). C = 3.0, macro F1 médio de 0.8638. | |
| - **Calibração:** temperatura e limiar de revisão ajustados nas probabilidades fora da dobra do | |
| treino. Fora da dobra: 0.1489 [0.1267–0.1722] enviado para revisão e 0.9504 [0.9347–0.9648] de top-1 nos aceitos. | |
| - **Testes:** dois testes **congelados** e escritos à mão antes do treino, com checksum, | |
| nunca usados para treino ou escolha: | |
| - `test_v1`: 146 linhas, todas as 37 posições; | |
| - `test_v2`: 74 linhas, de fontes novas. | |
| - **Intervalos:** bootstrap com 1000 reamostragens, intervalo percentil de 95%, semente 0. | |
| ### Resultados (calibrado + regra 31.05) | |
| | Métrica | test_v1 | test_v2 | | |
| |---|---|---| | |
| | top-1 | 0.9452 [0.9041–0.9795] | 0.9459 [0.8919–0.9865] | | |
| | top-3 | 0.9932 [0.9795–1.0000] | 1.0000 [1.0000–1.0000] | | |
| | macro F1 | 0.9447 [0.8942–0.9782] | 0.9198 [0.8621–0.9867] | | |
| | macro precisão | 0.9588 [0.9032–0.9858] | 0.9219 [0.8533–0.9929] | | |
| | macro recall | 0.9488 [0.9122–0.9804] | 0.9271 [0.8822–0.9881] | | |
| | ECE bruto → calibrado | 0.4502 → 0.0753 | 0.4554 → 0.0624 | | |
| | Enviado para revisão | 0.1096 [0.0616–0.1644] | 0.1351 [0.0676–0.2162] | | |
| | top-1 dos aceitos | 0.9846 [0.9615–1.0000] | 1.0000 [1.0000–1.0000] | | |
| | Linhas | 146 | 74 | | |
| As métricas macro tiram a média sobre as posições presentes em cada teste. ECE é o erro de | |
| calibração da confiança do top-1, em 10 faixas. | |
| ### Por capítulo | |
| Linhas, acerto da posição e acerto do capítulo (os dois primeiros dígitos): | |
| | Capítulo | test_v1: linhas / posição / capítulo | test_v2: linhas / posição / capítulo | | |
| |---|---|---| | |
| | 01 | 15 / 0.933 / 1.000 | 12 / 1.000 / 1.000 | | |
| | 04 | 3 / 1.000 / 1.000 | 2 / 1.000 / 1.000 | | |
| | 05 | 4 / 1.000 / 1.000 | — | | |
| | 07 | 4 / 0.750 / 0.750 | 1 / 1.000 / 1.000 | | |
| | 10 | 11 / 0.818 / 0.818 | 2 / 1.000 / 1.000 | | |
| | 12 | 15 / 1.000 / 1.000 | 6 / 1.000 / 1.000 | | |
| | 23 | 14 / 0.857 / 1.000 | 7 / 0.857 / 0.857 | | |
| | 25 | 4 / 1.000 / 1.000 | 2 / 0.500 / 0.500 | | |
| | 31 | 21 / 0.905 / 0.952 | 13 / 1.000 / 1.000 | | |
| | 38 | 6 / 1.000 / 1.000 | 1 / 0.000 / 0.000 | | |
| | 72 | 4 / 1.000 / 1.000 | — | | |
| | 73 | 11 / 1.000 / 1.000 | 7 / 0.857 / 1.000 | | |
| | 82 | 3 / 1.000 / 1.000 | 1 / 1.000 / 1.000 | | |
| | 84 | 20 / 1.000 / 1.000 | 12 / 1.000 / 1.000 | | |
| | 85 | 4 / 1.000 / 1.000 | 3 / 1.000 / 1.000 | | |
| | 87 | 7 / 1.000 / 1.000 | 5 / 1.000 / 1.000 | | |
| ### Comparação com BERTimbau | |
| Um fine-tuning do BERTimbau, com os mesmos dados, dobras, calibração e regra, empatou na | |
| qualidade: o top-1 dos dois testes juntos foi igual, e o intervalo da diferença pareada vai de | |
| −3,6 a +4,1 pontos. Ele custa ~50× mais por previsão em CPU. Os detalhes e o modelo estão em | |
| [`AmandaGondra/ncm-classifier-bertimbau`](https://huggingface.co/AmandaGondra/ncm-classifier-bertimbau). | |
| ## Como usar | |
| ```bash | |
| pip install -r requirements.txt # instala o pacote ncm-classifier na versão v0.1.0 | |
| ``` | |
| ```python | |
| from huggingface_hub import snapshot_download | |
| from ncm_classifier.inference.predictor import NcmPredictor | |
| path = snapshot_download("AmandaGondra/ncm-classifier", revision="v0.1.0") | |
| predictor = NcmPredictor.from_directory(path) | |
| for prediction in predictor.predict(["Ureia agrícola, pacote 1 kg"]): | |
| print(prediction.to_dict()) | |
| ``` | |
| Cada resultado traz: | |
| - `suggestions`: três posições, da mais provável para a menos provável, com a probabilidade | |
| calibrada de cada uma. Leia como "provavelmente a primeira; confira as outras duas se a | |
| descrição for ambígua". | |
| - `confidence`: probabilidade calibrada da primeira sugestão. | |
| - `needs_review`: `true` quando a confiança está abaixo do limiar. Nesse caso, a sugestão deve | |
| ser conferida por uma pessoa. | |
| - `rule_31_05`: `true` quando a regra da embalagem de até 10 kg mudou a sugestão. | |
| O carregador só aceita, além do scikit-learn e do NumPy, a função de normalização do próprio | |
| projeto. Qualquer outro tipo no arquivo faz o carregamento falhar. | |
| ## Limitações e riscos | |
| - **O modelo dá sugestões, não decisões fiscais.** Ele pode errar, inclusive com confiança alta. | |
| - **A responsabilidade pela classificação fiscal permanece com quem emite a nota.** A revisão | |
| por um profissional habilitado pode ser necessária. | |
| - **A qualidade depende da descrição.** Textos curtos ("Chocadeira"), siglas ("TSP") e marcas | |
| sem contexto erram mais. | |
| - **Composição e aplicação mudam a NCM.** Por exemplo, sal mineral é 23.09 e sal comum é 25.01; | |
| adubos dependem da composição e da embalagem. Produtos assim podem exigir análise técnica. | |
| - **Embalagem não declarada:** quando o texto não diz o peso, o rótulo segue a convenção de | |
| granel (mais de 10 kg). A regra 31.05 só lê pesos escritos em grafias reconhecidas ("5 kg", | |
| "500 g"); grafias como "5k" passam sem a regra. | |
| - **A tabela NCM muda.** O escopo segue a tabela vigente em 30/10/2026 (Resolução Gecex | |
| nº 926/2026). | |
| - **Testes pequenos.** Com 220 linhas, os intervalos de confiança são largos. | |
| - **Escopo restrito:** 37 posições, nível de 4 dígitos. Fora delas, o modelo sempre sugere uma | |
| das 37, mesmo que nenhuma sirva. | |
| ## Licença | |
| - **Código e modelo:** MIT. | |
| - **Dados:** o treino inclui descrições de anúncios de terceiros, que não são redistribuídas. | |
| O modelo guarda delas apenas estatísticas de palavras e trechos curtos. A parte publicada dos | |
| dados tem licença própria, descrita no | |
| [dataset card](https://huggingface.co/datasets/AmandaGondra/ncm-classifier-dataset). | |
| - Este documento não é parecer jurídico. | |