111-文本分析之基于文本相似度的聚类

参考:《文本数据挖掘》

1、相似度计算

p_load(stringdist)

# 越接近1相似度越高
stringsim("hello", "Hello", method = "lv")
## [1] 0.8
# 通过dist函数求iris数据集前四列的相互距离
# 默认为欧式距离
dist(t(iris[, 1:4]))
##              Sepal.Length Sepal.Width Petal.Length
## Sepal.Width      36.15785                         
## Petal.Length     28.96619    25.77809             
## Petal.Width      57.18304    25.86407     33.86473
# 利用Pearson相关系数来表征不同变量之间的相似度
p_load(apcluster)

corSimMat(t(iris[, 1:4]))
##              Sepal.Length Sepal.Width Petal.Length Petal.Width
## Sepal.Length    1.0000000  -0.1175698    0.8717538   0.8179411
## Sepal.Width    -0.1175698   1.0000000   -0.4284401  -0.3661259
## Petal.Length    0.8717538  -0.4284401    1.0000000   0.9628654
## Petal.Width     0.8179411  -0.3661259    0.9628654   1.0000000

2、 聚类方法

划分聚类法:k-means聚类法、k-medoids聚类法等
层次聚类法:合成法(Agglomerative Clustering)和分割法(Divise Clustering)

p_load(tokenizers)
str_vec <- df$sku_name[1:5] %>% 
  paste0(collapse = " ") %>% 
  tokenize_words(strip_punct = T, strip_numeric = T, 
                 simplify = T) 

# Levenshtein距离计算
d <- adist(str_vec)

# 如果量纲不一致或极差很大,还需要提前中心化和标准化
# d_scale <- scale(d)

2.1 K-means聚类

# 确定分类数量
p_load(factoextra)

# method则设定了最小化损失函数的计算方法
fviz_nbclust(d, kmeans, method = "wss")
确定分类数量

k=3以后就很难减少损失函数,因此设定k=3。

km <- kmeans(d, centers = 3)
# 查看分类
km$cluster
##  [1] 1 2 2 1 3 2 2 1 2 2 1 3 2 1 1 1 1 2 2 1 1 3 1 3 3 1 2 2 3 2 2 2 1 2 2 1 2 2 2 3 2 2 2 2
## [45] 2 2 2 2 2 1 2 2 1 2 2 2 2 3 2 1 1 3 1 2 2 2 2 1 1 2 1 2 2 1 3 2 1 1 2
# 查看字符串分别属于哪个类
cbind(class = km$center, string = str_vec)
# 基于PCA的可视化方法呈现分类结果
fviz_cluster(km,
             data = d,
             # 椭圆
             ellipse.type = "euclid",
             # 防止标注交叠
             repel = T,
             # 绘制主题
             ggtheme = theme_minimal())
基于PCA方法呈现分类结果

2.2 PAM算法

可以缓解kmeans聚类的缺点。

p_load(cluster)

# pam算法进行最佳聚类数判断
fviz_nbclust(d, pam, method = "silhouette")
确定最佳分类数

可以看到最佳聚类数为2。

pam <- pam(d, 2)

cbind(class = pam$clustering, string = str_vec)
##       class string       
##  [1,] "1"   "1000pcs"    
##  [2,] "1"   "32mm"       
##  [3,] "1"   "0.5ml"      
##  [4,] "1"   "plastic"    
##  [5,] "2"   "centrifuge" 
##  [6,] "1"   "tube"       
##  [7,] "1"   "test"       
##  [8,] "1"   "tubing"     
##  [9,] "1"   "vial"       
## [10,] "1"   "clear"      
## [11,] (省略。。。)
# 聚类效果
fviz_cluster(pam, ellipse.type = "euclid",
             repel = T,
             ggtheme = theme_classic())
聚类效果
# 使用fpc包高效实现k-medoids方法
p_load(fpc)

# 设置K取值范围为1到10,返回最佳聚类结果
pam2 <- pamk(d, krange = 1:10)

pam2$nc
## [1] 2

PAM算法虽然解决了很多问题,但是它在处理大数据集的时候,对计算机内存要求很高,而且耗费时间也比较长。为了解决这个问题,CLARA(Clustering Large Applications)算法被提了出来。

2.3 CLARA算法

# 判断最佳聚类数
fviz_nbclust(d, clara, method = "silhouette") +
  theme_classic()
确定最佳分类数
# 聚类分析
clara_res <- clara(d, 2, 
                   # 设定子集大小
                   samples = 50, pamLike = T)

# 显示聚类结果
cbind(class = clara_res$clustering, string = str_vec)
##       class string       
##  [1,] "1"   "1000pcs"    
##  [2,] "2"   "32mm"       
##  [3,] "2"   "0.5ml"      
##  [4,] "1"   "plastic"    
##  [5,] "1"   "centrifuge" 
##  [6,] "2"   "tube"       
##  [7,] "2"   "test"       
##  [8,] "2"   "tubing"     
##  [9,] "2"   "vial"       
## (省略。。。)
# 可视化展示
fviz_cluster(clara_res, ellipse.type = "euclid",
             repel = T, ggtheme = theme_classic())

2.4 层次聚类法

2.4.1 合成法

p_load(cluster)

# 为距离矩阵的行进行命名,方便显示结果
rownames(d) <- str_vec

# 聚类
# stand参数控制是否进行标准化(默认为FALSE),用metric参数控制样本距离的计算方法(默认为“euclidean”,即欧式距离)
# 用method参数设置聚类方法(默认为“average”)
res_agnes <- agnes(d)

# 查看分类结果
res_agnes
## Call:     agnes(x = d) 
## Agglomerative coefficient:  0.8408839 
## Order of objects:
##  [1] 1000pcs     1000pcs     plastic     plastic     plastic     plastic     nonstick   
##  [8] 32mm        22mm        33mm        50ml        26ml        0.5ml       0.2ml      
## [15] tube        tube        style       size        hinge       with        mini       
## [22] tin         test        case        pcr         dab         jars        jars       
## [29] home        cork        gold        lot         x           box         box        
## [36] box         boxes       vial        vials       vials       small       small      
## [43] glass       glass       clear       candy       zakka       empty       metal      
## [50] 12pcs       10pcs       tubing      design      wedding     garden      casket     
## [57] silver      novelty     newest      bottles     bottles     bottles     storage    
## [64] storage     storage     storage     protable    centrifuge  centrifuge  container  
## [71] container   containers  organizer   gardening   capacity    silicone    households 
## [78] transparent transparent
## Height (summary):
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   2.000   8.570   8.552  12.258  31.678 
## 
## Available components:
## [1] "order"     "height"    "ac"        "merge"     "diss"      "call"      "method"   
## [8] "order.lab" "data"

通过agnes函数求得的是样本之间的亲疏关系,而没有直接进行分类。如果要进行分类,可以指定分类的数量,然后用cutree函数实现

group_info <- cutree(res_agnes, k = 2)
group_info
##  [1] 1 1 1 1 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 2 1 2 2 1 1 1 2 1 1 1 2 1 1 1 1 1 1 2 1 1 1 1
## [45] 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 2 1 1 1 1 1 1 1 1 2 1 1 1 2 1 1 1 1
# 不进行分类
fviz_dend(res_agnes)
为分类结果
# 进行分类
fviz_dend(res_agnes, k = 2, 
          # 标志大小
          cex = 0.5,
          # 设定类别颜色
          k_colors = c("#FC4E07", "#00AFBB"),
          # 设定标志颜色
          color_labels_by_k = T,
          # 设定矩形边框
          rect = T)
分类后结果
# 使用PCA方法对结果进行可视化

fviz_cluster(list(data = as_tibble(d), cluster = group_info),
             palette = c("#FC4E07", "#00AFBB"),
             ellipse.type = "convex",
             repel = T,
             show.clust.cent = F,
             ggtheme = theme_minimal())
PCA方法可视化

2.4.2 分割法

只需要将agnes函数换为diana函数即可。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,904评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,581评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,527评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,463评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,546评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,572评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,582评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,330评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,776评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,087评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,257评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,923评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,571评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,192评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,436评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,145评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容