R

在距離矩陣上執行 k-means 是否與在數據矩陣(文本挖掘數據)上一樣有效?

  • June 29, 2016

(這篇文章是我昨天發布的一個問題的轉貼(現已刪除),但我試圖縮減字數並簡化我的問題)

我希望得到一些幫助來解釋我創建的 kmeans 腳本和輸出。這是在文本分析的背景下。在閱讀了幾篇關於文本分析的在線文章後,我創建了這個腳本。我在下面鏈接到其中的一些。

示例 r 腳本和文本數據語料庫我將在這篇文章中引用:

library(tm) # for text mining

## make a example corpus
# make a df of documents a to i
a <- "dog dog cat carrot"
b <- "phone cat dog"
c <- "phone book dog"
d <- "cat book trees"
e <- "phone orange"
f <- "phone circles dog"
g <- "dog cat square"
h <- "dog trees cat"
i <- "phone carrot cat"
j <- c(a,b,c,d,e,f,g,h,i)
x <- data.frame(j)    

# turn x into a document term matrix (dtm)
docs <- Corpus(DataframeSource(x))
dtm <- DocumentTermMatrix(docs)

# create distance matrix for clustering
m <- as.matrix(dtm)
d <- dist(m, method = "euclidean")

# kmeans clustering
kfit <- kmeans(d, 2)
#plot – need library cluster
library(cluster)
clusplot(m, kfit$cluster)

這就是腳本。下面是腳本中一些變量的輸出:

這裡是 x,被轉換成語料庫的數據框 x:

x
                      j
   1 dog dog cat carrot
   2      phone cat dog
   3     phone book dog
   4     cat book trees
   5       phone orange
   6  phone circles dog
   7     dog cat square
   8      dog trees cat
   9   phone carrot cat

這是生成的文檔術語矩陣 dtm:

   > inspect(dtm)
<<DocumentTermMatrix (documents: 9, terms: 9)>>
Non-/sparse entries: 26/55
Sparsity           : 68%
Maximal term length: 7
Weighting          : term frequency (tf)

   Terms
Docs book carrot cat circles dog orange phone square trees
  1    0      1   1       0   2      0     0      0     0
  2    0      0   1       0   1      0     1      0     0
  3    1      0   0       0   1      0     1      0     0
  4    1      0   1       0   0      0     0      0     1
  5    0      0   0       0   0      1     1      0     0
  6    0      0   0       1   1      0     1      0     0
  7    0      0   1       0   1      0     0      1     0
  8    0      0   1       0   1      0     0      0     1
  9    0      1   1       0   0      0     1      0     0

這是距離矩陣 d

> d
        1        2        3        4        5        6        7        8
2 1.732051                                                               
3 2.236068 1.414214                                                      
4 2.645751 2.000000 2.000000                                             
5 2.828427 1.732051 1.732051 2.236068                                    
6 2.236068 1.414214 1.414214 2.449490 1.732051                           
7 1.732051 1.414214 2.000000 2.000000 2.236068 2.000000                  
8 1.732051 1.414214 2.000000 1.414214 2.236068 2.000000 1.414214         
9 2.236068 1.414214 2.000000 2.000000 1.732051 2.000000 2.000000 2.000000

這是結果,kfit:

> kfit
K-means clustering with 2 clusters of sizes 5, 4

Cluster means:
        1        2        3        4        5        6        7        8        9
1 2.253736 1.194938 1.312096 2.137112 1.385641 1.312096 1.930056 1.930056 1.429253
2 1.527463 1.640119 2.059017 1.514991 2.384158 2.171389 1.286566 1.140119 2.059017

Clustering vector:
1 2 3 4 5 6 7 8 9 
2 1 1 2 1 1 2 2 1 

Within cluster sum of squares by cluster:
[1] 13.3468 12.3932
(between_SS / total_SS =  29.5 %)

Available components:

[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss" "betweenss"    "size"         "iter"        
[9] "ifault"      

這是結果圖: 在此處輸入圖像描述

我對此有幾個問題:

  1. 在計算我的距離矩陣 d(kfit 計算中使用的參數)時,我這樣做了d <- dist(m, method = "euclidean"):我遇到的另一篇文章是這樣做的:d <- dist(t(m), method = "euclidean"). 然後,在我最近發布的一個SO 問題上,有人評論說“kmeans 應該在數據矩陣上運行,而不是在距離矩陣上運行!”。大概他們的意思是kmeans()應該將 m 而不是 d 作為輸入。在這 3 個變體中,哪個/誰是“正確的”。或者,假設所有這些都以一種或另一種方式有效,這將是建立初始基線模型的常規方式?
  2. 據我了解,當在 d 上調用 kmeans 函數時,會發生選擇 2 個隨機質心(在本例中為 k=2)。然後 r 將查看 d 中的每一行並確定哪些文檔最接近哪個質心。根據上面的矩陣 d,它實際上會是什麼樣子?例如,如果第一個隨機質心是 1.5,第二個是 2,那麼如何分配文檔 4?在矩陣中 d doc4 是 2.645751 2.000000 2.000000 所以(在 ​​r 中)mean(c(2.645751,2.000000,2.000000)) = 2.2 所以在這個例子中,在 kmeans 的第一次迭代中,doc4 被分配給值為 2 的集群,因為它更接近那比1.5。在此之後,集群的平均值被重新定義為新的質心,並在適當的情況下重新分配文檔。這是對的還是我完全錯過了重點?
  3. 在上面的 kfit 輸出中,什麼是“集群意味著”?例如,Doc3 集群 1 的值為 1.312096。在這種情況下,這個數字是多少?[編輯,因為在發布幾天后再次查看這個,我可以看到它是每個文檔到最終集群中心的距離。所以最小的數字(最接近的)決定了每個文檔被分配到哪個集群]。
  4. 在上面的 kfit 輸出中,“聚類向量”看起來就像每個文檔被分配到的集群。好的。
  5. 在上面的 kfit 輸出中,“在簇內按簇的平方和”。那是什麼?13.3468 12.3932 (between_SS / total_SS = 29.5 %). 衡量每個集群內的方差,大概意味著較低的數字意味著更強的分組,而不是更稀疏的分組。這是一個公平的說法嗎?給定 29.5% 的百分比呢?那是什麼?是 29.5%“好”。在任何 kmeans 實例中,是否會首選更低或更高的數字?如果我嘗試使用不同數量的 k,我會尋找什麼來確定增加/減少的集群數量是幫助還是阻礙了分析?
  6. 該圖的屏幕截圖從 -1 變為 3。這裡測量的是什麼?與教育和收入、身高和體重相反,在這種情況下,排名最高的數字 3 是多少?
  7. 在圖中的消息“這兩個組件解釋了 50.96% 的點可變性”我已經在這裡找到了一些詳細信息(以防其他人遇到這篇文章 - 只是為了完整理解 kmeans 輸出想要添加在這裡。)。

以下是我閱讀的一些幫助我創建此腳本的文章:

要了解該kmeans()函數的工作原理,您需要閱讀文檔和/或檢查底層代碼。也就是說,我確信它不需要一個距離矩陣,甚至不用費心。您可以編寫自己的函數來從距離矩陣進行 k 均值聚類,但這會非常麻煩。

k-means 算法旨在對數據矩陣進行操作,而不是對距離矩陣進行操作。它只會最小化平方歐幾里得距離(參見為什麼 k-means 聚類算法只使用歐幾里得距離度量?)。僅當您可以將歐幾里得距離作為有意義的距離度量時才有意義。自從算法發明以來,情況一直如此,但似乎很少有人意識到這一點,因此 k-means 可能是機器學習中被誤用最多的算法。

歐幾里得距離對於稀疏的分類數據(文本挖掘)沒有任何意義,所以我什至不會嘗試這樣的事情。您首先需要弄清楚什麼距離度量適合您的數據(@ttnphns 在這裡解釋了一些可能的度量:當屬性是名義時,個人的最佳距離函數是什麼?)。然後,您可以計算距離矩陣並使用可以對一個進行操作的聚類算法(例如,k-medians / PAM、各種分層算法等)。

引用自:https://stats.stackexchange.com/questions/221144

comments powered by Disqus