Clasificación de datos explicada
Antecedentes y descargo de responsabilidad: en la empresa en la que trabajo, hemos segmentado a nuestros clientes en cuatro clases según su comportamiento de pago. Por lo general, cuando se segmenta a los clientes en un entorno comercial, se utilizan tres parámetros: Actualidad (cuánto tiempo hace que un cliente realizó una compra), Frecuencia (con qué frecuencia realiza compras un cliente) y Monetario (cuánto gasta un cliente en cada compra). Sin embargo, en este caso, solo usaré Frecuencia para explicar el concepto de binning. En el futuro, proporcionaré una explicación más completa de la segmentación de clientes.
Pero, ¿qué es el binning?
El agrupamiento de datos es el proceso de organizar sus datos en un rango finito de intervalos. Esa gama de intervalos se denominan "contenedores".
El agrupamiento de datos, también conocido como " agrupamiento de datos ", es una técnica de preprocesamiento de datos utilizada en el aprendizaje automático y la minería de datos para agrupar valores de datos continuos en intervalos discretos o "contenedores". El agrupamiento puede servir para múltiples propósitos, incluida la reducción de errores de datos al suavizar las fluctuaciones en los datos, obtener información sobre la distribución de datos y convertir características de valor real en intervalos discretos, también conocida como codificación one-hot.
Hay dos tipos principales de métodos de agrupamiento: agrupamiento de frecuencia y agrupamiento de ancho igual. Existen variaciones de estos métodos, pero todas se basan esencialmente en uno de estos dos enfoques. En este tutorial, la atención se centra en la implementación de un algoritmo básico de binning de igual longitud. El agrupamiento de ancho igual implica dividir el rango de valores en un conjunto de datos en un número específico de intervalos igualmente espaciados entre los valores mínimo y máximo.
const width = (max - min) / number_of_bins
const bins_values = [min, min + width, min + 2 * width, ..., min + number_of_bins * width]
Para ilustrar el concepto de agrupación de datos, consideremos un ejemplo práctico utilizando Typescript. Supongamos que tenemos un conjunto de datos que registra la cantidad de compras realizadas por los clientes dentro de un período de tiempo específico. El conjunto de datos se representa en la siguiente matriz:
const trxFreq = [229, 293, 394, 39, 39, 49, 93, 100, 29, 48, 188]
Para analizar el conjunto de datos de la frecuencia de compra del cliente, es necesario dividir los datos en cuatro contenedores distintos etiquetados como "Clientes D" a "Clientes A". Para lograr esto, primero crearemos una estructura de datos simple para almacenar nuestros contenedores.
/**
* Structure of each bin
*/
export interface Bin {
/**
* Bucket.
*/
item: {
value: number
label?: string
}
/**
* Values in a bin
*/
values: number[]
}
/**
* Array type of bins
*/
export type Bins = Bin[]
El código de la toBinfunción podría verse así:
/**
* Convert input dataset array of numbers into bins.
*
* @param data dataset array
* @param binSize Number of bins
* @param labels Optional labels for the bins
*/
export function toBins(data: number[], binSize: number, labels?: string[]) {
// Implementation
}
- Bin 1: Compras de frecuencia más baja / Clientes afortunados
- Bin 2: Compras de baja frecuencia / Clientes poco interesados
- Bin 3: Compras de frecuencia moderada / Clientes aceptables
- Bin 4: Compras de alta frecuencia / Buenos clientes
const sampleCount = data.length
// Sort data in descending order
const sortedData = data.sort((lhs, rhs) => lhs - rhs)
// Find min and max samples
const minSample = sortedData[0]
const maxSample = sortedData[sampleCount - 1]
// Create equal spaced bins
const binWidth = (maxSample - minSample) / binSize
const bins: Bins = Array(binSize)
.fill({ values: [] })
.map((bin, i) => ({
item: {
value: minSample + binWidth * i,
label: labels?.[i]
},
...bin
}))
El ancho del contenedor se calcula tomando la diferencia entre los valores máximo y mínimo y dividiéndola por el número de contenedores deseados. Este ancho se usará para agrupar valores en sus contenedores apropiados.
Finalmente, creamos una matriz vacía para contener nuestros contenedores, que completaremos con datos en el siguiente paso del algoritmo. Al crear estos contenedores vacíos, establecemos el marco para la posterior agrupación de datos en contenedores.
// Search for the next chunk from the sorted array to add into the bin values
let minIndex = 0
let maxIndex = sampleCount - 1
for (let i = 0; i < binSize; i++) {
while (
minIndex < sampleCount &&
sortedData[minIndex] < bins[i].item.value
) {
minIndex++
}
while (
maxIndex >= 0 &&
sortedData[maxIndex] > bins[i].item.value + binWidth
) {
maxIndex--
}
for (let j = minIndex; j <= maxIndex; j++) {
bins[i].values.push(sortedData[j])
}
// Slice item from the sorted array into the bin
bins[i].values = sortedData.slice(minIndex, maxIndex + 1)
// Get the maxIndex ready for the next iteration.
maxIndex = sampleCount - 1
}
Es importante tener en cuenta que este paso requiere que el conjunto de datos se clasifique en orden ascendente para ubicar los índices apropiados. Si no se ordena el conjunto de datos de antemano, se generará una clasificación incorrecta.
Para ver el algoritmo en acción, a continuación se proporciona un ejemplo completamente funcional.
export interface Bin {
item: {
value: number
label?: string
}
values: number[]
}
export type Bins = Bin[]
export function toBins(data: number[], binSize: number, labels?: string[]) {
const sampleCount = data.length
if (binSize >= sampleCount) {
throw new RangeError(
`Bin size ${binSize} should be less than sample size: ${sampleCount}`
)
}
// Sort data in descending order
const sortedData = data.sort((lhs, rhs) => lhs - rhs)
// Find min and max samples
const minSample = sortedData[0]
const maxSample = sortedData[sampleCount - 1]
// Create equal spaced bins
const binWidth = (maxSample - minSample) / binSize
const bins: Bins = Array(binSize)
.fill({ values: [] })
.map((bin, i) => ({
item: {
value: minSample + binWidth * i,
label: labels?.[i]
},
...bin
}))
let minIndex = 0
let maxIndex = sampleCount - 1
for (let i = 0; i < binSize; i++) {
while (
minIndex < sampleCount &&
sortedData[minIndex] < bins[i].item.value
) {
minIndex++
}
while (
maxIndex >= 0 &&
sortedData[maxIndex] > bins[i].item.value + binWidth
) {
maxIndex--
}
// Slice a bucket
bins[i].values = sortedData.slice(minIndex, maxIndex + 1)
// Get the maxIndex ready for the next iteration.
maxIndex = sampleCount - 1
}
return bins
}
Una vez que se ha implementado la toBinfunción, el código del cliente puede invocarla para producir una matriz de Binobjetos que representan los datos agrupados. Para hacerlo, el código del cliente debe pasar el conjunto de datos de entrada, la cantidad deseada de contenedores y, opcionalmente, una matriz de etiquetas a la toBinfunción.
Como ejemplo, podemos proporcionar transacciones de muestra e invocar la toBinfunción en este conjunto de datos para producir una matriz de Binobjetos que representan los datos agrupados.
const trxFreq = [229, 293, 394, 39, 39, 49, 93, 100, 29, 48, 188]
const labels = ['D-Customers', 'C-Customers', 'B-Customers', 'A-Customers']
const bins = toBins(trxFreq, labels.length, labels)
console.log(bins)
// Prints
// [
// {
// "item": { "value": 29, "label": "D-Customers" },
// "item": [29, 39, 39, 48, 49, 93, 100 ]
// },
// {
// "iem": { "value": 120.25, "label": "C-Customers" },
// "values": [ 188 ]
// },
// {
// "item": { "value": 211.5, "label": "B-Customers" },
// "values": [ 229, 293 ]
// },
// {
// "item": { "value": 302.75, "label": "A-Customers" },
// "values": [ 394 ]
// }
// ]
Vale la pena señalar que el algoritmo que hemos implementado tiene una complejidad temporal de O(n log n) debido a la necesidad de ordenar el conjunto de datos de entrada. Además, la complejidad espacial del algoritmo es O(k) , donde k es el número de contenedores.
Notas de cierre y conclusiones:
Para resumir, en este tutorial hemos cubierto un algoritmo simple de binning de igual ancho y brindamos un ejemplo de cómo se puede usar para agrupar a los clientes según su frecuencia de compra. El agrupamiento es una técnica común de preprocesamiento de datos que se puede emplear para reducir errores, obtener información sobre un conjunto de datos o convertir valores reales en intervalos discretos. Sin embargo, existen algunos desafíos asociados con esta técnica, como decidir el tamaño de contenedor apropiado para un conjunto de datos determinado.
Según el caso de uso específico, se pueden emplear técnicas alternativas para organizar un conjunto de datos en grupos definidos, como el algoritmo k-Nearest Neighbors (kNN). Es importante considerar cuidadosamente los requisitos específicos de un proyecto para determinar la técnica de preprocesamiento más apropiada a emplear.
Si está interesado en obtener más información sobre el agrupamiento u otras técnicas de preprocesamiento de datos, asegúrese de explorar mis artículos para obtener más artículos, tutoriales y recursos. Optar por recibir correos electrónicos cuando publique nuevos artículos. ¡Estén atentos para obtener más información y consejos prácticos sobre las últimas tendencias en aprendizaje automático y ciencia de datos!
Finalmente, aquí está el repositorio de github para este tutorial ¡Gracias!

![¿Qué es una lista vinculada, de todos modos? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































