
Estimar el costo de una comparación de duplicados
Source:R/duplicados-aproximados.R
estimar_costo.RdConstruye las firmas y calcula el pronóstico de candidatos sin recorrer las
cubetas ni comparar los pares. Es una operación deliberada: la medición del
reloj queda en el resultado de esta función y no es necesaria para obtener
alcance reproducible en detectar_duplicados_aproximados().
Usage
estimar_costo(
datos,
columnas = NULL,
metodo = "jw",
umbral = 0.1,
p = 0.1,
muestra = Inf,
max_pares = 50000000L,
max_resultados = 100L,
normalizar = NULL,
perfil = NULL,
proteger_datos_personales = TRUE,
bloque = 1000L,
estrategia = "auto",
lsh_bandas = 12L,
lsh_filas = 3L,
lsh_q = 3L,
lsh_max_cubeta = 1000L,
lsh_muestra_estimacion = 400000L,
presupuesto_pares = Inf,
bloquear_por = NULL,
lotes = FALSE,
tamano_lote = 1000L,
directorio_lotes = NULL,
nucleos = getOption("lupa.nucleos", 2L),
max_largo_valor = .MAX_LARGO_VALOR_CASI_DUPLICADOS
)Arguments
- datos
Tabla con una fila por entidad observada.
- columnas
Columnas atomicas a combinar.
NULLaplica la seleccion automatica descrita arriba; no se incluyen matrices ni listas. El orden forma parte de la comparación: los valores de cada fila se miden concatenados en el orden declarado, así quec("nombre", "domicilio")yc("domicilio", "nombre")son dos comparaciones distintas y pueden publicar pares distintos con el mismo umbral —medido: 6 pares contra 10 sobre las mismas cinco filas—. ConNULL, el orden es el que tienen las columnas endatos. El objeto publica encolumnasel vector que usó, en ese orden, así que el resultado se puede rehacer; declararlo a mano lo vuelve independiente de cómo estén ordenadas las columnas del archivo.Cómo se concatena, para poder rehacer la distancia. Los valores se unen con
" | "y cada|que haya dentro de un valor se escribe\|. El escape no es cosmético: sin él,c1 = "x | y", c2 = "z"yc1 = "x", c2 = "y | z"producían la misma cadena y dos filas que no comparten ningún valor salíanexacto_normalizadoa distancia0. Con el escape, la distancia publicada de una comparación de varias columnas se rehace así:escapar <- function(v) gsub("|", "\\|", v, fixed = TRUE) fila <- function(i) paste(escapar(datos$c1[i]), escapar(datos$c2[i]), sep = " | ") stringdist::stringdist(fila(1), fila(2), method = "jw", p = 0.1)Si la columna es un factor o tiene marca
bytes, la cadena comparada es la clave de bytes del valor —lo que distingue un valor no textual del literal de su escape—; para texto corriente esa clave es el valor tal cual.Si dos columnas de texto tienen el mismo nombre, la comparación no corre: identifica las columnas por nombre y no podría decir cuál compara. No se compara un subconjunto —sacar una columna cambia el significado de la comparación—: el objeto sale sin pares, con el motivo en
razon.- metodo
Medida admitida por
stringdist::stringdistmatrix(). Por defecto,"jw".- umbral
Distancia maxima para informar un par. Por defecto
0.10.- p
Factor de prefijo de Jaro–Winkler, entre 0 y 0.25. Por defecto
0.1; sólo tiene efecto conmetodo = "jw".- muestra
Máximo de filas candidatas. En el camino exacto queda sujeto a
max_pares; con LSH,Infusa todas las filas.- max_pares
Máximo de pares comparados en el camino exacto. Por defecto
50000000, que permite recorrer exhaustivamente hasta 10.000 filas con el método y el bloque predeterminados; se puede reducir para limitar el tiempo. En LSH el alcance se expresa con candidatos y cubetas, por lo que este límite no se usa para recortar filas; el resultado lo marca explícitamente.- max_resultados
Maximo de pares devueltos. Por defecto
100. Se conservan los mas cercanos; entre pares empatados en distancia, el desempate usa el orden canonico de los valores y no la posicion de las filas, de modo que reordenar la tabla no cambia que pares sobreviven. Un corte que cae dentro de un empate deja afuera pares igual de cercanos, y eso se declara enalcance$corte_en_empate.- normalizar
Perfil de comparación.
TRUEconserva el perfil predeterminado,FALSEdesactiva sus pasos configurables,"amplio"activa puntuación, ligaduras y ancho, ynormalizacion()permite declarar cada paso. Una lista nombrada puede resolver perfiles por columna.NULLhereda el perfil guardado enperfil; si no se recibe uno, usaTRUE. La normalización cambia sólo la representación usada para comparar, no los datos guardados. El umbral se aplica sobre esa cadena normalizada. La descomposición canónica no es un paso configurable: corre también conFALSE, y es lo que hace que dos escrituras del mismo texto —caféprecompuesto ycafécon acento combinante— sean el mismo texto. Como la distancia se mide sobre esa forma, un acento cuenta como un carácter aparte: connormalizar = FALSE,caféycafedistan0.04—y entran en un umbral de0.1—, mientras la misma distancia sobre las cadenas tal como se guardaron daría0.117. Para reproducir un número publicado hay que descomponer primero.Hasta dónde llega esa descomposición. La tabla que usa
lupacubre el subconjunto latino —el mismo límite que declaranormalizacion()—, así que fuera de él dos escrituras canónicamente equivalentes no colapsan: medido, el mismo nombre griego en NFC y en NFD saleaproximadoa0.124dondecaféprecompuesto y descompuesto salenexacto_normalizadoa0. No es un descuido de la comparación: es el alcance de la tabla, y se dice acá porque afecta la receta de reproducción. Para un texto fuera del subconjunto latino, el número publicado se rehace sin descomponer, sobre los valores tal como están guardados. Si necesita que colapsen, normalice la entrada a una sola forma antes de comparar —por ejemplo constringi::stri_trans_nfc()—. El informe de fusiones sólo se calcula cuando algún paso configurable está activo; conFALSEse omite. Si se entregaperfil, se reutiliza su informe ya calculado.- perfil
Perfil de los mismos datos para reutilizar su clasificacion de datos personales y no volver a inferirla.
- proteger_datos_personales
Si la evidencia de columnas protegidas se reemplaza por
[valor protegido]. La supresion queda indicada en cada par.- bloque
Cantidad de filas por tesela de comparación. Por defecto
1000; controla la memoria temporal, no el número de pares comparados.- estrategia
Estrategia de comparación:
"auto"(por omisión),"teselas","muestra"o"lsh". MinHash/LSH sólo se activa automáticamente por encima del tope exhaustivo; se puede forzar con"lsh".- lsh_bandas
Número de bandas del esquema LSH. Por defecto, 12.
- lsh_filas
Número de filas de firma por banda. Por defecto, 3.
- lsh_q
Longitud de los q-gramas usados para MinHash. Por defecto, 3.
- lsh_max_cubeta
Umbral a partir del cual una cubeta se considera grande y se procesa por el mismo troceo acotado del camino exhaustivo. No se descartan pares por este umbral; el alcance informa cuántas cubetas y cuántos pares se procesaron de esta forma. Por defecto, 1000.
- lsh_muestra_estimacion
Cantidad máxima de pares de filas usados para estimar la proporción de candidatos, el tiempo del camino LSH y, si hay
bloquear_por, la pérdida de candidatos del bloqueo. La muestra es interna, reproducible y su tamaño efectivo queda enalcance. Por defecto se intentan 400.000 pares.- presupuesto_pares
Se acepta por simetría de la firma y no aborta aquí: estimar el costo es justamente lo que se hace antes de fijar un presupuesto, así que interrumpir la estimación por superarlo dejaría sin respuesta la pregunta que motivó la llamada. Quien aborta es
detectar_duplicados_aproximados(), con el número que devuelve esta función.- bloquear_por
Nombre de una columna declarada por el usuario para restringir la comparación a filas con la misma clave. La clave no tiene significado incorporado en
lupa; sus tamaños, ausentes y pares que quedan fuera se registran enalcance. LosNAforman un bloque propio.- lotes
Se acepta por simetría de la firma, pero la estimación no escribe parciales ni modifica el directorio indicado.
- tamano_lote
Se acepta por simetría; no cambia el pronóstico.
- directorio_lotes
Se acepta por simetría y no se crea ni se usa al estimar.
- nucleos
Cantidad máxima de hilos que
stringdistpuede usar. Por defecto esgetOption("lupa.nucleos", 2L);NULLusa esa misma opción y un valor mayor que los núcleos disponibles se limita de forma segura. El resultado no depende de esta cantidad, pero el tiempo sí. El valor efectivo queda declarado enalcance$nucleos_usados.- max_largo_valor
Maximo de caracteres permitido en cada valor de las columnas combinadas, medido sobre la cadena que de verdad se compara: las columnas ya unidas y ya normalizadas. Las dos mitades importan. Dos columnas de 9.000 caracteres estan las dos por debajo de un tope de 10.000 y llegan a 18.003 una vez unidas; y la normalizacion
amplioexpande ligaduras tipograficas -la de f-f-l es un solo caracter que se convierte en tres-, asi que un valor puede estar por debajo del tope guardado y por encima del comparado. Por defecto es10000, umbral elegido porque la distancia normalizada deja de distinguir de forma estable una diferencia local de muchas diferencias en textos largos. Si una columna supera el tope, la combinacion completa se declara fuera de alcance enalcance$columnas_excluidas_largo, yalcance$largo_maximopublica el largo comparado; no se recortan valores en silencio. Con el tope enInfno se mide ningun largo ylargo_maximovaleNA, no cero.Infrecupera explicitamente el comportamiento anterior sin tope.
Value
Lista de clase estimacion_costo_lupa con los campos de la
estimación, alcance, disponible y razon. En el camino exacto,
alcance declara además la corrida que se está estimando:
modo_comparacion es el mismo que publicará
detectar_duplicados_aproximados() con esos argumentos —exhaustiva_por_bloques
o muestreada_por_bloques—, y filas_previstas, filas_totales y
estrategia_prevista dicen sobre cuántas filas se va a comparar y con qué
selección. Una estimación que anunciara un recorrido exhaustivo sobre una
corrida que va a muestrear no serviría para decidir.
Details
En el camino LSH, candidatos_previstos es una estimación reproducible a
partir de una muestra de firmas. tiempo_estimado_segundos es un piso de la
medida aislada y no incluye firmas, cubetas ni troceo; sus campos de reloj
tienen tiempo_determinista = FALSE. Con bloquear_por, los pares entre
bloques no entran en el pronóstico y la pérdida estructural y estimada queda
en alcance. En el camino exacto, candidatos_previstos es la cantidad de
pares que se compararán, sujeta a muestra, max_pares y bloquear_por.
La función no escribe archivos ni modifica el estado del generador de R.
Examples
datos <- data.frame(
nombre = c("Ana Perez", "Ana Peres", "Luis Diaz"),
grupo = c("A", "A", "B")
)
if (requireNamespace("stringdist", quietly = TRUE)) {
costo <- estimar_costo(datos, columnas = "nombre", estrategia = "lsh")
costo$candidatos_previstos
}
#> [1] 1