Capítulo 28 — Governança de dados: implementação I
Mapa da aula
Aula 28 publicada. Mapa, exemplo, EX082.
flowchart TD
N0["28.1 A biblioteca de regras"]
N1["Laboratório — Taxas de aprovação de três regras de l"]
N2["28.2 Executando as regras"]
N3["28.3 Interpretando as falhas"]
N4["28.4 Em relação aos limiares"]
N0 --> N1 --> N2 --> N3 --> N4
N4 --> EX["Exemplo resolvido"]
EX --> Q["Exercício EX082"]
Desenho lógico
flowchart LR
N0["28.1 A biblioteca de regras"]
N1["Laboratório — Taxas de aprovação de três regras de l"]
N2["28.2 Executando as regras"]
N3["28.3 Interpretando as falhas"]
N4["28.4 Em relação aos limiares"]
N0 --> N1 --> N2 --> N3 --> N4 --> Q["EX082"]
[28.1 A biblioteca de regras]
|
v
[Laboratório — Taxas de aprovação de três regras de l]
|
v
[28.2 Executando as regras]
|
v
[28.3 Interpretando as falhas]
|
v
[28.4 Em relação aos limiares]
|
v
[Exemplo resolvido] --> [Exercício EX082]
Objetivos de aprendizagem
Você vai (1) implementar regras de qualidade de dados em código; (2) medir taxas de aprovação; (3) interpretar resultados combinados.
28.1 A biblioteca de regras
Kofi implementa as primeiras regras de qualidade em uma biblioteca compartilhada, usada por todos os pipelines. Cada regra é uma função com identificador, descrição, dono e limiar lido da configuração. As três primeiras regras verificam se o identificador do medidor está presente, se a leitura não é menor que a anterior do mesmo medidor e se o consumo diário é inferior a 300 metros cúbicos, quantidade implausível para qualquer cliente residencial ou pequeno comércio da área da Tidewater. Cada regra também está documentada no catálogo.
Laboratório — Taxas de aprovação de três regras de leitura em 10.000 linhas sintéticas
"""Run validation rules on synthetic meter readings and report pass rates (stdlib only)."""
import random
random.seed(8)
rows = []
for i in range(10000):
prev = random.uniform(100, 5000); cur = prev + random.uniform(0, 60)
if random.random() < 0.02: cur = prev - random.uniform(1, 50) # rollback
if random.random() < 0.01: cur = prev + random.uniform(500, 2000) # spike
mid = f"M{i:06d}" if random.random() > 0.005 else ""
rows.append((mid, prev, cur))
rules = {
"meter id present": lambda r: bool(r[0]),
"reading not below previous": lambda r: r[2] >= r[1],
"daily use under 300 m3": lambda r: r[2] - r[1] < 300,
}
for name, f in rules.items():
ok = sum(1 for r in rows if f(r)); print(f"{name:28s} pass {ok/len(rows):.3f}")
allok = sum(1 for r in rows if all(f(r) for f in rules.values()))
print(f"rows passing all rules {allok} of {len(rows)} ({100*allok/len(rows):.1f}%)")
Execute com python3 lab_rules.py. Saída verificada:
meter id present pass 0.995
reading not below previous pass 0.980
daily use under 300 m3 pass 0.990
rows passing all rules 9650 of 10000 (96.5%)
28.2 Executando as regras
O laboratório aplica as regras a 10.000 leituras sintéticas. A regra do identificador do medidor aprova 99,5 por cento das linhas; a regra de não ser menor que a anterior, 98,0 por cento; e a regra do consumo diário, 99,0 por cento. As linhas aprovadas nas três regras somam 9.650, ou 96,5 por cento. Kofi observa que a taxa combinada é menor que qualquer taxa isolada, porque as falhas caem em linhas diferentes. Os donos veem as taxas de suas próprias regras, mas o número combinado é o que o faturamento de fato recebe. Por isso, Kofi pede que o painel mostre com destaque o número de todas as regras, com as taxas individuais logo abaixo para os donos que precisam investigar suas próprias falhas.
28.3 Interpretando as falhas
Kofi examina as falhas. As leituras menores que a anterior vêm principalmente de trocas de medidor, em que o novo medidor começa do zero. Não se trata de erro na leitura, mas da falta de vínculo entre o medidor antigo e o novo. Ele trabalha com a medição para registrar as trocas, de modo que a regra compare apenas leituras do mesmo medidor. Os identificadores ausentes vêm de leituras manuais digitadas sem leitura do código, o que o aplicativo de campo passará a impedir ao exigir a leitura. As duas correções entram na próxima versão.
28.4 Em relação aos limiares
Em comparação com os limiares acordados no capítulo 24, a validade de 96,5 por cento fica abaixo da meta de 98 por cento. Kofi relata isso com honestidade ao conselho de governança, com as causas encontradas e as correções planejadas, e estima que só a correção das trocas já elevaria a taxa combinada acima da meta. A Profa. Varga observa que relatar uma meta não atingida com um plano crível gera mais confiança do que baixar os limiares para que os números pareçam aceitáveis. O conselho aceita o plano e pede uma atualização depois da próxima versão, com as taxas recalculadas sobre dados novos.
Exemplo resolvido
Kofi implementa uma biblioteca de regras compartilhada, aplica três regras a 10.000 linhas, com taxas de aprovação de 99,5, 98,0 e 99,0 por cento e 96,5 por cento aprovadas em todas, rastreia as causas e relata o não atingimento da meta.
Caso sintético. Os dados são sintéticos; as saídas vêm de lab_rules.py.
Erros e limites
A média das taxas por regra superestima a qualidade; informe a taxa de todas as regras.
Exercícios
- EX082 — Taxa de todas as regras. Que proporção das linhas passou em todas as regras? Rubrica: 3 = 96,5% (9.650 de 10.000);; 2 = parcialmente correto;; 1 = parcial;; 0 = nenhuma.
- EX083 — Causa das leituras menores. O que causou principalmente as leituras menores que a anterior? Rubrica: 3 = trocas de medidor começando do zero;; 2 = parcialmente correto;; 1 = vago;; 0 = nenhuma.
- EX084 — Tratamento da meta. Como Kofi lidou com a meta não atingida? Rubrica: 3 = relatou com honestidade, com causas e correções;; 2 = parcialmente correto;; 1 = vago;; 0 = nenhuma.
Continue estudando — aula 28 (capítulo 28 de 50)
← Capítulo 27 · Índice das aulas · Capítulo 29 →
Continue para a próxima aula já escrita.