《数据分析实战》--用R做聚类分析《数据分析实战》–用R做聚类分析

《数据分析实战》–用R做聚类分析

本文参考的是 《数据分析实战》

的第八章。

背景: 针对某公司的产品,现目前需要服务好已有的用户,针对不同的用户群体设计并推广不同的营销策略。

现状: 目标用户不明确。

预期: 明确目标用户群。


读取数据

读取Dau数据:

    > dau <- read.csv('dau.csv',header = T,stringsAsFactors = F)
    > head(dau)
        log_date app_name user_id
    1 2013-05-01  game-01  608801
    2 2013-05-01  game-01  712453
    3 2013-05-01  game-01  776853
    4 2013-05-01  game-01  823486
    5 2013-05-01  game-01  113600
    6 2013-05-01  game-01  452478
[/code]

读取Dpu数据:

```code
    > dpu <- read.csv('dpu.csv',header = T,stringsAsFactors = F)
    > head(dpu)
        log_date app_name user_id payment
    1 2013-05-01  game-01  804005     571
    2 2013-05-01  game-01  793537      81
    3 2013-05-01  game-01  317717      81
    4 2013-05-01  game-01  317717      81
    5 2013-05-01  game-01  426525     324
    6 2013-05-01  game-01  540544     243
[/code]

读取用户行为数据:

```code
    > user.action <- read.csv('action.csv',header = T,stringsAsFactors = F)
    > head(user.action)
        log_date app_name user_id A1 A2 A3 A4 A5 A6  A7    A8  A9 A10 A11 A12 ... A54
    1 2013-10-31  game-01  654133  0  0  0  0  0  0   0  0.00   0   0   0   0 ...  46
    2 2013-10-31  game-01  425530  0  0  0  0 10  1 233 58.25 288 230  19   2 ...  71
    3 2013-10-31  game-01  709596  0  0  0  0  0  0   0  0.00   0   0   0   0 ...   2
    4 2013-10-31  game-01  525047  0  2  0  0  9  0   0  0.00 177 160   0   0 ... 109
    5 2013-10-31  game-01  796908  0  0  0  0  0  0   0  0.00   5  30   0   0 ...  64
    6 2013-10-31  game-01  776120  0  0  0  0  9  0   0  0.00 325 195  38   8 ... 312
[/code]

其中列A1 ~ A54 表示各种行为的编码,这些行为的编码和行为日志名称是通过另外一份数据表来管理的。

* * *

##  数据处理

1.将Dau和Dpu合并:

```code
    # 合并消费额数据
    > dau2 <- merge(dau, dpu[, c("log_date", "user_id", "payment"), ],
                    by = c("log_date", "user_id"), all.x = T)
    # 添加消费额标志位
    > dau2$is.payment <- ifelse(is.na(dau2$payment), 0, 1)
    
    # 将无消费记录的消费额设为0
    > dau2$payment <- ifelse(is.na(dau2$payment), 0, dau2$payment)
    > head(dau2)
        log_date user_id app_name payment is.payment
    1 2013-05-01    1141  game-01       0          0
    2 2013-05-01    1689  game-01       0          0
    3 2013-05-01    2218  game-01       0          0
    4 2013-05-01    3814  game-01       0          0
    5 2013-05-01    3816  game-01       0          0
    6 2013-05-01    4602  game-01       0          0
[/code]

2.按月统计:

```code
    # 增加一列表示月份
    > dau2$log_month <- substr(dau2$log_date,1,7)
    # 按月统计
    > mau <- ddply(dau2,
    +              .(log_month,user_id),
    +              summarize,
    +              payment = sum(payment),
    +              access_days=length(log_date))
    > head(mau)
      log_month user_id payment access_days
    1   2013-05      65       0           1
    2   2013-05     115       0           1
    3   2013-05     194       0           1
    4   2013-05     426       0           4
    5   2013-05     539       0           1
    6   2013-05     654       0           1
[/code]

* * *

##  数据分析

现状我们通过聚类来对数据进行分析:

1.确定类的个数:  
可以使用k-means 方法,将排行榜得分作为变量,把用户分为3 个类。  
k-means 方法可以通过kmeans 函数来执行,但该方法的缺点是结果不稳定。ykmeans 程序包中的ykmeans 函数,在内部将kmeans
函数执行了100 次,因此能够获得稳定的结果。

```code
    > library(ykmeans)
    > library(ggplot2)
    > library(scales)
    # A47为排行榜得分
    > user.action2 <- ykmeans(user.action,"A47", "A47", 3)
    # 每个类的人数
    > table(user.action2$cluster)
    
       1    2    3 
    2096  479   78 
[/code]

对确定好的类进行画图:

```code
    # 排行榜得分的分布
    > ggplot(arrange(user.action2,desc(A47)),
    +        aes(x=1:length(user_id),y=A47,
    +            col=as.factor(cluster),
    +            shape=as.factor(cluster)))+
    +   geom_line()+
    +   xlab("user")+
    +   ylab("Ranking point")+
    +   scale_y_continuous(labels = comma)+
    +   ggtitle("Ranking point")+
    +   theme(legend.position = "none")
[/code]

![这里写图片描述](https://img-
blog.csdn.net/20180604160236934?)

2.限定排名考前的用户:

```code
    > user.action.h <- user.action2[user.action2$cluster >= 2,names(user.action)]
[/code]

3.进行主成分分析:  
行为日志里保存着用户所有行为的记录,可能存在各个行为之间相互影响的情况。另外,由于用户有的行为并没有发生,因此值为0
的行为记录有很多。所以我们实际上拿到的数据并不会像教科书中的数据那样工整。在这种情况下,很有可能无法执行k-means 方法,因此我们要将数值大都为0
的变量和相关性较高的变量删除掉,然后利用主成分分析进行正交变换。

```code
    # 用于机器学习的库
    # 利用库中包含的函数进行数据的前期处理
    > library(caret)
    > user.action.f <- user.action.h[, -c(1:4)]
    > row.names(user.action.f) <- user.action.h$user_id
    > head(user.action.f)
    # 删除那些信息量小的变量
    > nzv <- nearZeroVar(user.action.f)
    > user.action.f.filterd <- user.action.f[,-nzv]
    # 删除那些相关性高的变量
    > user.action.cor <- cor(user.action.f.filterd)
    > highly.cor.f <- findCorrelation(user.action.cor,cutoff=.7)
    > user.action.f.filterd <- user.action.f.filterd[,-highly.cor.f]
    # 进行主成分分析
    # pca
    > user.action.pca.base <- prcomp(user.action.f.filterd, scale = T)
[/code]

4.进行聚类:

```code
    > user.action.pca <- data.frame(user.action.pca.base$x)
    > keys <- names(user.action.pca)
    > user.action.km <- ykmeans(user.action.pca, keys, "PC1", 3:6)
    > table(user.action.km$cluster)
    
      1   2   3   4   5 
     23 228  88 164  54 
[/code]

结果如下图:

```code
    > ggplot(user.action.km,
    +        aes(x=PC1,y=PC2,col=as.factor(cluster), shape=as.factor(cluster))) +
    +   geom_point()
[/code]

![这里写图片描述](https://img-
blog.csdn.net/2018060417034743?)

5.形成雷达图:

```code
    df.filterd <- createRadarChartDataFrame(scale(df.filterd))
    names(df.filterd)
    
    radarchart(df.filterd, seg = 5, plty = 1:5, plwd = 4, pcol = rainbow(5))
    legend("topright", legend = 1:5, col = rainbow(5), lty = 1:5)
[/code]

![这里写图片描述](https://img-
blog.csdn.net/20180604171147708?)

具体结果如上图,至此,数据分析结束~

* * *


![在这里插入图片描述](https://www.icode9.com/i/ll/?i=20210608151750993.gif)
上一篇:推荐一款 Java 接口快速开发框架,干活快到飞起。。


下一篇:X-Magic Pair