데이터 비닝 설명
배경 및 고지 사항: 제가 근무하고 있는 회사에서는 고객을 결제 방식에 따라 네 가지 등급으로 분류했습니다. 일반적으로 비즈니스 환경에서 고객을 분류할 때 최근성(고객이 얼마나 최근에 구매했는지), 빈도(고객이 구매하는 빈도) 및 통화(고객이 각 구매에 지출하는 금액)의 세 가지 매개변수가 사용됩니다. 그러나 이 경우 비닝의 개념을 설명하기 위해 빈도만 사용하겠습니다. 앞으로는 고객 세분화에 대해 보다 포괄적인 설명을 하도록 하겠습니다.
근데 비닝이 뭐에요?
데이터 비닝은 데이터를 유한한 범위의 간격으로 구성하는 프로세스입니다. 이러한 간격 범위를 "빈"이라고 합니다.
" 데이터 버킷팅 "이라고도 하는 데이터 비닝은 기계 학습 및 데이터 마이닝에서 연속 데이터 값을 불연속 간격 또는 "빈"으로 그룹화하는 데 사용되는 데이터 사전 처리 기술입니다. 비닝은 데이터의 변동을 완화하여 데이터 오류를 줄이고, 데이터 분포에 대한 인사이트를 얻고, 실제 값 기능을 불연속 간격으로 변환하는 등 다양한 용도로 사용할 수 있습니다(원-핫 인코딩이라고도 함).
비닝 방법에는 주파수 비닝과 등폭 비닝의 두 가지 기본 유형이 있습니다. 이러한 방법의 변형이 존재하지만 모두 기본적으로 이 두 가지 접근 방식 중 하나를 기반으로 합니다. 이 자습서에서는 기본 동일 길이 비닝 알고리즘을 구현하는 데 중점을 둡니다. 등폭 비닝은 데이터 세트의 값 범위를 최소값과 최대값 사이의 동일한 간격의 지정된 수로 나누는 것을 포함합니다.
const width = (max - min) / number_of_bins
const bins_values = [min, min + width, min + 2 * width, ..., min + number_of_bins * width]
데이터 비닝의 개념을 설명하기 위해 Typescript를 사용하는 실제 예를 살펴보겠습니다. 특정 기간 동안 고객이 구매한 횟수를 기록하는 데이터 세트가 있다고 가정합니다. 데이터 세트는 다음 배열로 표시됩니다.
const trxFreq = [229, 293, 394, 39, 39, 49, 93, 100, 29, 48, 188]
고객 구매 빈도의 데이터 세트를 분석하려면 데이터를 'D-Customers'에서 'A-Customers'까지 레이블이 지정된 4개의 별도 그룹으로 나눌 필요가 있습니다. 이를 달성하기 위해 먼저 저장소를 저장할 간단한 데이터 구조를 만듭니다.
/**
* 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[]
함수 의 코드는 toBin다음과 같을 수 있습니다.
/**
* 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
}
- 빈 1: 빈도가 가장 낮은 구매/행운의 고객
- Bin 2: 빈도가 낮은 구매 / 관심이 적은 고객
- 구간 3: 보통 빈도의 구매/괜찮은 고객
- 구간 4: 높은 빈도의 구매/좋은 고객
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
}))
빈 너비는 최대값과 최소값의 차이를 원하는 빈 수로 나누어 계산합니다. 이 너비는 값을 적절한 저장소로 그룹화하는 데 사용됩니다.
마지막으로 알고리즘의 다음 단계에서 데이터로 채울 저장소를 보관할 빈 배열을 만듭니다. 이러한 빈 빈을 생성하여 이후에 데이터를 빈으로 그룹화하기 위한 프레임워크를 설정합니다.
// 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
}
이 단계에서는 적절한 인덱스를 찾기 위해 데이터 세트를 오름차순으로 정렬해야 한다는 점에 유의해야 합니다. 사전에 데이터 세트를 정렬하지 않으면 비닝이 잘못됩니다.
작동 중인 알고리즘을 보기 위해 완전히 작동하는 예제가 아래에 제공됩니다.
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
}
함수 가 구현되면 클라이언트 코드에서 호출하여 그룹화된 데이터를 나타내는 개체 toBin배열을 생성할 수 있습니다 . Bin이를 위해 클라이언트 코드는 입력 데이터 세트, 원하는 빈 수 및 선택적으로 레이블 배열을 함수에 전달해야 합니다 toBin.
예를 들어 샘플 트랜잭션을 제공하고 이 데이터 세트에서 함수를 호출하여 그룹화된 데이터를 나타내는 개체 toBin배열을 생성 할 수 있습니다.Bin
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 ]
// }
// ]
우리가 구현한 알고리즘은 입력 데이터 세트를 정렬해야 하기 때문에 O(n log n) 의 시간 복잡도를 갖는다는 점은 주목할 가치가 있습니다 . 또한 알고리즘의 공간 복잡도는 O(k) 이며 여기서 k는 빈의 수입니다.
마무리 메모 및 테이크 아웃:
요약하면 이 자습서에서는 간단한 등폭 비닝 알고리즘을 다루었으며 구매 빈도에 따라 고객을 그룹화하는 데 사용할 수 있는 방법의 예를 제공했습니다. 구간화는 오류를 줄이고 데이터 세트에 대한 통찰력을 얻거나 실제 값을 이산 간격으로 변환하는 데 사용할 수 있는 일반적인 데이터 사전 처리 기술입니다. 그러나 주어진 데이터 세트에 적합한 빈 크기를 결정하는 것과 같이 이 기술과 관련된 몇 가지 문제가 있습니다.
특정 사용 사례에 따라 kNN(k-Nearest Neighbors) 알고리즘과 같은 정의된 그룹으로 데이터 세트를 구성하는 대체 기술을 사용할 수 있습니다. 사용할 가장 적절한 사전 처리 기술을 결정하려면 프로젝트의 특정 요구 사항을 신중하게 고려하는 것이 중요합니다.
범주화 또는 기타 데이터 전처리 기술에 대해 자세히 알아보려면 내 기사에서 더 많은 기사, 자습서 및 리소스를 살펴보십시오. 새 기사를 게시할 때 이메일 수신을 선택합니다. 기계 학습 및 데이터 과학의 최신 동향에 대한 더 많은 통찰력과 실용적인 팁을 기대해 주세요!
마지막으로, 이 튜토리얼을 위한 github 저장소가 있습니다. 감사합니다!

![연결된 목록이란 무엇입니까? [1 부]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































