零售中的客户细分

customer segmentation in retail

我有一个 'home and construction' 零售的大型销售数据库。 而且我需要知道店里的电工、水管工、油漆工等是谁。

我的第一个方法是 select 与专业相关的文章(例如,电线 [文章] 与电工 [专业] 相关)然后,根据客户销售情况,了解客户是谁是。

但这工作量很大。

我的第二种做法是先做一个聚类分割,然后发现哪个聚类属于一个专业。 (这好多了,因为我可以发现新的细分市场)

但是,我该怎么做呢?我应该占用什么类型的集群? Kmeans,模糊?我应该对该模型采用哪些变量?我应该使用 PCA 来知道要搜索多少个集群吗?

我的数据header(简体):

customer_id | transaction_id | transaction_date | item_article_id | item_group_id | item_category_id | item_qty | sales_amt

如有任何帮助,我们将不胜感激 (对不起我的英语)

您想根据购买的商品识别 类 客户(我认为这是出于营销原因)。这需要一种聚类方法。我将向您介绍整个设置过程。

聚类space

让我们首先考虑一下您究竟要聚类什么:订单还是客户。在任何一种情况下,您描述项目的方式和它们之间的距离都是相同的。我将首先讨论订单的基本情况,然后解释适用于客户聚类的注意事项。

为了您的目的,订单的特征是购买了哪些商品,可能还有多少。就 space 而言,这意味着每种类型的文章 (item_article_id) 都有一个维度,例如 "wire" 维度。如果您只关心一件商品是否被购买,则每个商品在每个维度上的坐标为 0 或 1。如果某个订单包含电线但不包含管道,则它在 "wire" 维度上的值为 1,在 "pipe" 维度上的值为 0。

不过,关心数量还是有话要说的。也许水管工会购买大量胶水,而电工只会购买少量胶水。在这种情况下,您可以将每个维度中的坐标设置为相应商品的数量(大概是item_qty)。所以假设你有三件物品,电线,管道和胶水,那么 vector (2, 3, 0) 描述的一个订单包括 2 根电线,3 根管道和 0 根胶水,而一个订单向量描述的(0, 1, 4)包括0根线材,1根管子和4根胶水。

如果给定商品的数量差异很大,即如果某些订单包含的某些商品比其他订单多一个数量级,那么使用对数刻度可能会有所帮助。假设你有这四个订单:

  1. 2根电线,2根管子,1根胶水
  2. 3 根电线,2 根管子,0 根胶水
  3. 0 根电线,100 根管子,1 根胶水
  4. 0 根电线,300 根管子,3 根胶水

前两个订单看起来像是电工的,后两个订单看起来像是水管工的。但是,如果您使用线性标度,3 阶将更接近 1 阶和 2 阶而不是 4 阶。我们通过对编码这些阶的向量使用对数标度来解决这个问题(我使用以 10 为底的对数在这里,但你采用哪个基数并不重要,因为它们仅相差一个常数因子):

  1. (0.30, 0.30, 0)
  2. (0.48, 0.30, -2)
  3. (-2, 2, 0)
  4. (-2, 2.48, 0.48)

现在订单 3 最接近订单 4,正如我们预期的那样。请注意,我使用 -2 作为特殊值来表示没有文章,因为 0 的对数未定义(log(x) 趋向于负无穷大,而 x 趋向于 0)。 -2 表示我们假设该订单包含了商品的 1/100;您可以使特殊值或多或少极端化,具体取决于您希望对未包含文章这一事实赋予多少权重。

您的聚类算法(无论您采用哪种算法,请参见下文)的输入将是一个位置矩阵,其中一行代表每个项目(订单或客户),一列代表每个维度(文章),或者每个单元格中金额的存在 (0/1)、金额或对数,具体取决于您根据上述讨论选择的内容。如果您按客户聚类,则可以简单地将属于该客户的所有订单的金额相加,然后再计算进入您的位置矩阵的每个单元格的内容(如果您使用对数刻度,请将金额相加 before取对数)。

按订单而非客户进行聚类可为您提供更多详细信息,但也会带来更多噪音。客户可能在一个订单内保持一致,但在他们之间却不一致;也许客户有时表现得像水管工,有时表现得像电工。只有按订单聚类才能找到这种模式。然后你会发现每个客户属于每个集群的频率;也许某人的订单中有 70% 属于电工类型,30% 属于管道工类型。另一方面,管道工可能只在一个订单中购买管道,然后在下一个订单中只购买胶水。只有按客户分组并对他们的订单金额求和,您才能平衡地了解每个客户的平均需求。

从这里开始,我将使用名称 my.matrix 来引用您的位置矩阵。

聚类算法

如果您希望能够发现新的客户类型,您可能希望尽可能让数据自己说话。一个很好的老式 在这种情况下,具有完整链接的层次聚类 (CLINK) 可能是一个合适的选择。在 R 中,您只需执行 hclust(dist(my.matrix))(这将使用欧几里德距离度量,这对您的情况来说可能已经足够好了)。它将紧密相邻的项目或集群连接在一起,直到所有项目都归类到层次结构树中。您可以将树的任何分支视为一个集群,观察该分支的典型文章数量,并决定该分支是否代表其自身的客户群,应该拆分为子分支,还是与兄弟分支合并。优点是您可以找到 "full story" 哪些项目和项目集群彼此最相似以及有多少。缺点是算法的结果不会告诉您在何处划定客户群之间的边界;您可以通过多种方式切割聚类树,因此如何识别客户类型取决于您的解释。

另一方面,如果您愿意预先确定聚类的数量 (k),则 k-means 是一种非常可靠的方法,可以对您的客户进行任何细分在 k 种不同的类型中。在 R 中,你会做 kmeans(my.matrix, k)。出于营销目的,拥有(比方说)5 个不同的客户资料就足够了,您可以为其制作定制广告,而不是对所有客户一视同仁。使用 k-means,您无需探索数据中存在的所有多样性,但您可能不需要这样做。

如果你不想预先固定簇的数量,但你也不想事后手动决定在何处绘制线段之间的边界,还有第三种可能。您从 k-means 算法开始,让它生成的聚类中心数量远大于您希望最终得到的聚类数量(例如,如果您希望最终得到大约 10 个聚类,让 k-means 算法寻找 200 个簇)。然后,使用 mean shift 算法进一步聚类结果中心。您最终会得到数量较少的紧凑型集群。 James Li over here. You can use the mean shift algorithm in R with the ms function from the LPCM package, see this documentation.

更详细地解释了该方法

关于使用 PCA

PCA 不会告诉您需要多少个聚类。PCA 回答了一个不同的问题:哪些变量似乎代表了一个共同的潜在(隐藏)因素。从某种意义上说,这是一种对变量(即实体的属性)进行聚类的方法,而不是对实体本身进行聚类。主要成分(共同的潜在因素)的数量并不表示所需的集群数量。如果您想了解有关客户兴趣的每篇文章的预测价值,PCA 仍然很有趣。

来源