【问题标题】:How can i segment clients on granular level using python and ML?如何使用 python 和 ML 在粒度级别细分客户端?
【发布时间】:2020-03-02 03:19:30
【问题描述】:

新手提醒

过去几个月我一直在学习 Python 中的机器学习,并取得了一些不错的成果。然而,目前,我被一个项目困住了,需要有更多经验的人指导(谷歌只能带你到现在看来????)。

我想要达到的目标

我有一个充满客户及其交易的虚拟数据集。我想根据他们的人口统计数据、消费分数和购物行为将他们聚类或分割成更小的“部落”。例如,一个“部落”描述可能是这样细化的:(男性,35 岁,主要在每个月上半月的周六下午购买基于音乐的产品,并且消费得分很高) 我想找到细粒度细分和一般细分之间的最佳点,例如:按收入和支出分数进行细分。

我尝试过的

首先,我分配了一个 int 值,表示每个客户事务中每个分类出现的频率。例如:

Client | Home  | Movies | Games 
    1      3        1       0

这表示客户 1 已经购买了 3 次家庭相关商品,1 次电影相关商品,并且他们从未购买过游戏类别中的任何商品。

我对天数(即星期日 - 星期六)、周数(即任何给定月份的第 1-5 周数)、小时(即 hour_one - hour_twenty_four)做了同样的事情。

这种方法允许我创建一个纯数字数据的干净向量。

这是我的 JSON 格式的原始输入数据示例(处理前):

[
    {
        "id": 1,
        "customer_id": 1,
        "age": 47,
        "gender": "Female",
        "first_name": "Lea",
        "last_name": "Calafato",
        "email": "lcalafato0@cafepress.com",
        "phone_number": "612-170-5956",
        "income_k": 24,
        "location": "Nottingham",
        "sign_up_date": "2/16/2019",
        "transactions": [
            {
                "customer_id": "1",
                "product_id": 42,
                "product_cat": "Home",
                "price": 106.92,
                "time": "8:15 PM",
                "date": "04/15/2019",
                "day": "Monday",
                "week_num": 3
            },
            {
                "customer_id": "1",
                "product_id": 30,
                "product_cat": "Movies",
                "price": 26.63,
                "time": "10:12 AM",
                "date": "09/17/2019",
                "day": "Tuesday",
                "week_num": 4
            }
        ],
        "number_of_purchases": 2,
        "last_purchase": "09/17/2019",
        "total_spent": 133.55
    }
]

这是我经过处理和标准化后的数据框:

age                  750 non-null int64
income_k             750 non-null int64
spending_score       750 non-null int64
gender__Female       750 non-null uint8
gender__Male         750 non-null uint8
Home                 750 non-null float64
Movies               750 non-null float64
Games                750 non-null float64
Grocery              750 non-null float64
Music                750 non-null float64
Health               750 non-null float64
Beauty               750 non-null float64
Sports               750 non-null float64
Toys                 750 non-null float64
Garden               750 non-null float64
Computers            750 non-null float64
Clothing             750 non-null float64
Books                750 non-null float64
Outdoors             750 non-null float64
Industrial           750 non-null float64
Kids                 750 non-null float64
Tools                750 non-null float64
Automotive           750 non-null float64
Electronics          750 non-null float64
Jewelery             750 non-null float64
Baby                 750 non-null float64
Shoes                750 non-null float64
week_one             750 non-null float64
week_two             750 non-null float64
week_three           750 non-null float64
week_four            750 non-null float64
week_five            750 non-null float64
Sunday               750 non-null float64
Monday               750 non-null float64
Tuesday              750 non-null float64
Wednesday            750 non-null float64
Thursday             750 non-null float64
Friday               750 non-null float64
Saturday             750 non-null float64
hour_one             750 non-null float64
hour_two             750 non-null float64
hour_three           750 non-null float64
hour_four            750 non-null float64
hour_five            750 non-null float64
hour_six             750 non-null float64
hour_seven           750 non-null float64
hour_eight           750 non-null float64
hour_nine            750 non-null float64
hour_ten             750 non-null float64
hour_eleven          750 non-null float64
hour_twelve          750 non-null float64
hour_thirteen        750 non-null float64
hour_fourteen        750 non-null float64
hour_fithteen        750 non-null float64
hour_sixteen         750 non-null float64
hour_seventeen       750 non-null float64
hour_eighteen        750 non-null float64
hour_nineteen        750 non-null float64
hour_twenty          750 non-null float64
hour_twenty_one      750 non-null float64
hour_twenty_two      750 non-null float64
hour_twenty_three    750 non-null float64
hour_twenty_four     750 non-null float64*

我已经通过 k-means 和 DBSCAN 算法运行了这些数据,但无济于事。 k-means 给了我 4 个集群,这对我的要求来说太笼统了,而 DBSCAN 给了我零个集群,每个数据点都被视为噪声。

如果有任何不清楚的地方,我深表歉意,请随时要求我澄清任何事情。提前致谢。

【问题讨论】:

  • 我们在您的问题描述中遗漏了最重要的一项:什么定义了“最佳位置”?它是对集群距离或集群大小的某种度量,还是从对每一列的经验质量的理解中得出的?除非它是一个特定的编程问题,否则您不仅应该细化您的问题,还应该将帖子移至适当的组。 On topichow to ask 和 ...the perfect question 在这里申请。
  • @Prune 指出。以后,我会寻找更合适的论坛。至于“甜蜜点”,我只是呼吁有更多经验的人知道答案。

标签: python machine-learning artificial-intelligence cluster-analysis


【解决方案1】:

如果您的数据未按比例缩放,则可能会发生这种情况。 在此处查看 Iris 数据集的通用示例:

import pandas as pd
import numpy as np
import seaborn
from sklearn.preprocessing import MinMaxScaler
from  sklearn.cluster import KMeans

iris = seaborn.load_dataset('iris')
scaling = MinMaxScaler(feature_range=(-1, 1)).fit(iris.iloc[:,:-1])
iris_scale = pd.DataFrame(scaling.transform(iris.iloc[:,:-1]),columns=iris.iloc[:,:-1].columns)
km = KMeans(n_clusters=3, random_state=1)
km.fit(iris_scale)
y_kmeans = pd.DataFrame({'cluster': km.predict(iris_scale), 'real':iris['species'], 'stam':1})
y_kmeans.pivot_table(index=['real'],columns=['cluster'], aggfunc='count')

这是你应该得到的结果:

cluster        0     1     2
real                        
setosa       NaN  50.0   NaN
versicolor  47.0   NaN   3.0
virginica   14.0   NaN  36.0

这意味着 k-means 将所有“setosa”物种聚集为集群 1,即使不知道它是同一个物种。 确保您的数据经过缩放(标准化)。

【讨论】:

  • 我会试试这个。谢谢
  • My data after being normalized :
  • `年龄income_k spending_score gender__Female gender__Male家庭电影... 0 0.889170 0.454044 0.000000 0.018919 0.000000 0.018919 0.018919 ... 1 0.209039 0.596147 0.758733 0.000000 0.007742 0.007742 0.007742 ... 2 0.492814 0.739221 0.197126 0.000000 0.024641 0.000000 0.049281。 .. 3 0.438854 0.894586 0.000000 0.000000 0.016879 0.000000 0.000000 ... 4 0.280203 0.446249 0.809475 0.010378 0.000000 0.010378 0.000000 0.010378 031 0.010378 0.000000 031
  • 我仍然遇到和以前一样的问题。聚类太笼统了。
【解决方案2】:

如果您使用 k=4,K-means 将为您提供 4 个聚类。如果你想要更多的成本,增加k...

同样,DBSCAN 也有一个需要设置权才能达到预期的效果。

【讨论】:

  • 当然,但是,在通过 k-means 聚类算法运行数据之前,我使用了肘部方法。根据在线建议,最好将 k 设置为数据角度发生显着变化的点……还是不??
  • 肘部方法对于真实数据来说是垃圾。它仅适用于玩具示例。如果您想要更多集群,请使用更大的 k。尽管如果 k-means 没有产生令人信服的结果,我不会感到惊讶——它对良好的数据准备非常敏感。鉴于您的属性列表,我怀疑 any 方法会从这个混乱中产生任何有意义的东西。
  • @Anoy-Mousse 能否根据我的数据集推荐一个更好的属性列表,告诉我它一团糟并不是很有帮助。另外,为什么肘部方法对于真实数据来说是“废话”?是否有替代方法来确定最佳聚类数?
  • 是的,有两打更好的方法,在文献中很容易找到。但他们都假设您的数据适合 k-means;它需要 continuous 变量,但您的属性大多似乎是二进制的。但是其他方法也会有类似的问题:它们依赖于 you 定义距离测量,这样相关的(对于 your 问题!)记录比不同的记录更相似。
  • 所以直到 可以在数学上定义这些数据上的“好”集群是什么(我当然看不出什么是好的),我怀疑你能得到一个算法产生“好”的结果。
猜你喜欢
  • 2018-04-24
  • 1970-01-01
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-01
  • 2018-11-04
相关资源
最近更新 更多