Binning de dados explicado
Histórico e isenção de responsabilidade: na empresa em que trabalho, segmentamos nossos clientes em quatro classes com base em seu comportamento de pagamento. Normalmente, ao segmentar clientes em um ambiente de negócios, três parâmetros são usados: Recenticidade (quando um cliente fez uma compra recentemente), Frequência (com que frequência um cliente faz compras) e Monetário (quanto um cliente gasta em cada compra). No entanto, neste caso, usarei apenas Frequência para explicar o conceito de binning. No futuro, fornecerei uma explicação mais abrangente sobre a segmentação de clientes.
Mas o que é binning?
Binning de dados é o processo de organizar seus dados em um intervalo finito de intervalos. Esses intervalos de intervalos são chamados de “bins”.
Binning de dados, também conhecido como “ divisão de dados ”, é uma técnica de pré-processamento de dados usada em aprendizado de máquina e mineração de dados para agrupar valores de dados contínuos em intervalos discretos ou “bins”. A categorização pode atender a vários propósitos, incluindo a redução de erros de dados suavizando as flutuações nos dados, obtendo insights sobre a distribuição de dados e convertendo recursos de valor real em intervalos discretos, também conhecidos como codificação one-hot.
Existem dois tipos principais de métodos de binning: binning de frequência e binning de largura igual. Existem variações desses métodos, mas todos são essencialmente baseados em uma dessas duas abordagens. Neste tutorial, o foco está na implementação de um algoritmo básico de binning de comprimento igual. Binning de largura igual envolve dividir o intervalo de valores em um conjunto de dados em um número especificado de intervalos igualmente espaçados entre os valores mínimo e 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 o conceito de categorização de dados, vamos considerar um exemplo prático usando o Typescript. Suponha que temos um conjunto de dados que registra o número de compras feitas pelos clientes em um período de tempo específico. O conjunto de dados é representado na seguinte matriz:
const trxFreq = [229, 293, 394, 39, 39, 49, 93, 100, 29, 48, 188]
Para analisar o conjunto de dados de frequência de compra do cliente, é necessário dividir os dados em quatro caixas distintas rotuladas de `D-Clientes` a `A-Clientes`. Para conseguir isso, primeiro criaremos uma estrutura de dados simples para armazenar nossas caixas.
/**
* 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[]
O código para a toBinfunção pode ser algo como isto:
/**
* 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 com frequência mais baixa / Clientes sortudos
- Bin 2: Compras de baixa frequência / Clientes pouco interessados
- Bin 3: Compras com frequência moderada / Clientes ok
- Bin 4: Compras de alta frequência / Bons 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
}))
A largura do bin é calculada tomando a diferença entre os valores máximo e mínimo e dividindo-a pelo número de bins desejados. Essa largura será usada para agrupar valores em suas caixas apropriadas.
Por fim, criamos uma matriz vazia para armazenar nossas caixas, que preencheremos com dados na próxima etapa do algoritmo. Ao criar essas caixas vazias, estabelecemos a estrutura para o subseqüente agrupamento de dados em caixas.
// 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
}
É importante observar que esta etapa requer que o conjunto de dados seja classificado em ordem crescente para localizar os índices apropriados. A falha em classificar o conjunto de dados de antemão resultaria em binning incorreto.
Para ver o algoritmo em ação, um exemplo totalmente funcional é fornecido abaixo.
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
}
toBinUma vez implementada a função, ela pode ser invocada pelo código do cliente para produzir uma matriz de Binobjetos que representam os dados agrupados. Para fazer isso, o código do cliente deve passar o conjunto de dados de entrada, o número desejado de compartimentos e, opcionalmente, um array de rótulos para a toBinfunção.
Como exemplo, podemos fornecer transações de amostra e invocar a toBinfunção neste conjunto de dados para produzir uma matriz de Binobjetos que representam os dados 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 a pena notar que o algoritmo que implementamos tem uma complexidade de tempo de O(n log n) devido à necessidade de classificar o conjunto de dados de entrada. Além disso, a complexidade espacial do algoritmo é O(k) , onde k é o número de compartimentos.
Notas de Encerramento e Retiradas:
Para resumir, neste tutorial, abordamos um algoritmo simples de categorização de largura igual e fornecemos um exemplo de como ele pode ser usado para agrupar clientes com base em sua frequência de compra. Binning é uma técnica comum de pré-processamento de dados que pode ser empregada para reduzir erros, obter informações sobre um conjunto de dados ou converter valores reais em intervalos discretos. No entanto, existem alguns desafios associados a essa técnica, como decidir o tamanho apropriado da caixa para um determinado conjunto de dados.
Dependendo do caso de uso específico, técnicas alternativas podem ser empregadas para organizar um conjunto de dados em grupos definidos, como o algoritmo k-Nearest Neighbors (kNN). É importante considerar cuidadosamente os requisitos específicos de um projeto para determinar a técnica de pré-processamento mais apropriada a ser empregada.
Se você estiver interessado em aprender mais sobre binning ou outras técnicas de pré-processamento de dados, certifique-se de explorar meus artigos para obter mais artigos, tutoriais e recursos. Opte por receber e-mails quando eu publicar novos artigos. Fique ligado para mais informações e dicas práticas sobre as últimas tendências em aprendizado de máquina e ciência de dados!
Finalmente, aqui está o repositório do github para este tutorial Obrigado!





































![O que é uma lista vinculada, afinal? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)