1. 程式人生 > 實用技巧 >【機器學習與R語言】11- Kmeans聚類

【機器學習與R語言】11- Kmeans聚類

目錄

1.理解Kmeans聚類

1)基本概念

  • 聚類:無監督分類,對無標籤案例進行分類。
  • 半監督學習:從無標籤的資料入手,是哦那個聚類來建立分類標籤,然後用一個有監督的學習演算法(如決策樹)來尋找這些類中最重要的預測指標。
  • kmeans聚類演算法特點:

  • kmeans演算法涉及將n個案例中的每一個案例分配到指定k個類中的一個(指定k是為了最小化每個類內部差異,最大化類之間的差異)。
  • 為避免遍歷案例所有可能的組合來計算最優聚類,kemans使用了局部最優解的啟發式過程,即對初始的類分配進行修正來判斷是否提升了類內部的同質性。
  • kmeans聚類的兩個階段:一是將案例分配到初始的k個類中;二是根據落入當前類的案例調整類的邊界來更新分配。重複更新和分配多次,直到改變不會提升類的優度為止。
  • 可通過嘗試多次不同k的聚類分析來測試研究結果的穩健性。

2)kmeans運作的基本原理

①使用距離來分配和更新類

  • 初始類中心的選擇:從訓練集中選擇的k個隨機案例來確定;或者選擇發生再特徵空間任意地方的隨機值(而不是隻在資料的觀測值之間進行選擇);或者完全跳過這一步,通過將每個案例隨機分配到一個類中,直接進入更新階段。
  • 選擇初始類中心之後,其他的案例將分配到與其最相似,或者根據距離函式最相近的類中心。距離函式如歐氏距離、曼哈頓距離、閔可夫斯基距離等。
  • 距離計算的資料必須是數值型,且需要標準化,計算的是每一個案例與每一個類中心之間的距離。
  • 更新類:將初始的類中心轉移到一個新的位置(“質心”,通過計算分配到當前類的各點的均值來獲得)。類中心改變之後,類的邊界發生變化,案例重新分配,如此反覆更新,直到沒有額外的案例被重新分配為止,聚類最終完成。
  • 聚類結果的表達:一是可以報告每個案例的分配情況;二是可以報告最後一次更新之後的質心的座標。


運算過程如下:
指定k=3,選擇初始類中心

計算距離,歸類

更新類中心,重新分配

第二輪更新階段,重新分配

最終聚類結果

②選擇適當的聚類數

  • kmeans演算法對於隨機選擇的聚類中心很敏感。選擇類的數目需要一種微妙的平衡:大k會提升類的同質性,但有過擬合的風險。
  • 理想情況下,最好有一些關於真實分組的先驗知識。有時k也由業務需求或分析動機所決定。
  • 若沒有任何先驗知識,經驗規則就是k設為n/2的平方根(n是全部案例總數),對於大的資料集一般偏大。
  • “肘部法”度量不同k值:找到一個k(肘部點),使得高於該值之後的收益會發生遞減。

  • 但在實際中,反覆測試大量的k值是不可行的。不要要求最嚴格的效能,獲得類最優解集。大部分應用中,選擇一個k就夠了。

2.Kmeans聚類應用示例

探尋青少年市場細分

1)收集資料

30000名美國高中生的隨機案例資料集,在知名社交網路服務中儲存了他們的個人資料。將網站頁面內容劃分單詞,36個單詞被選來代表5大興趣類。每個案例包括4個個人特徵(畢業年份,性別,年齡,交友數)和36種興趣。

資料下載:

連結: https://pan.baidu.com/s/1CGkaRPc3glCjI-hWWg1Kug 提取碼: 74bm

2)探索和準備資料

包括缺失值的檢視,缺失值的虛擬編碼和缺失值插補等。

## Step 2: Exploring and preparing the data ----
teens <- read.csv("snsdata.csv")
str(teens)

# look at missing data for female variable
table(teens$gender)
table(teens$gender, useNA = "ifany") #計數缺失值

# look at missing data for age variable
summary(teens$age) #包含缺失值統計

# eliminate age outliers
teens$age <- ifelse(teens$age >= 13 & teens$age < 20,
                     teens$age, NA)

summary(teens$age)

# reassign missing gender values to "unknown"
teens$female <- ifelse(teens$gender == "F" &
                         !is.na(teens$gender), 1, 0)
teens$no_gender <- ifelse(is.na(teens$gender), 1, 0)

# check our recoding work
table(teens$gender, useNA = "ifany")
table(teens$female, useNA = "ifany")
table(teens$no_gender, useNA = "ifany")

# finding the mean age by cohort
mean(teens$age) # doesn't work
mean(teens$age, na.rm = TRUE) # works

# age by cohort
aggregate(data = teens, age ~ gradyear, mean, na.rm = TRUE)

# create a vector with the average age for each gradyear, repeated by person
# ave函式返回一個具有重複的組均值的向量,使得結果在長度上等於原始向量的長度
ave_age <- ave(teens$age, teens$gradyear,
                 FUN = function(x) mean(x, na.rm = TRUE))


teens$age <- ifelse(is.na(teens$age), ave_age, teens$age)

# check the summary results to ensure missing values are eliminated
summary(teens$age)

3)訓練模型

使用基礎包的kmeans函式。注意將特徵標準化,這裡用z-score標準化。
另一個就是k值的指定,比如對人口分析很熟悉,或者對關於自然分組的真是數量有一些預感,也可參考一些資料等,我們將符合年齡的高中生特徵確定為5個典型型別(聰明人,運動員,公主,罪犯,無特徵)。

## Step 3: Training a model on the data ----
interests <- teens[5:40]
interests_z <- as.data.frame(lapply(interests, scale))

set.seed(2345)
teen_clusters <- kmeans(interests_z, 5)

4)評估效能

模型的成功與否在於類對於預期目的是否有用。評估一個類是否有用的最基本方法之一就是檢查落在每一組中的案例數,數目過多或過少(如1個或幾個),則這些類不太有用。
為深入瞭解類,可檢視聚類質心的座標。因為已經做了z-score標準化,所以負值表示低於總體均值,正值表示高於總體均值。

## Step 4: Evaluating model performance ----
# look at the size of the clusters
teen_clusters$size

# look at the cluster centers
teen_clusters$centers

通過研究類在特徵(興趣)中的表現,可以構建有一個表來列出每組中的主要興趣項:

5)提高模型效能

根據聚類結果,可以確定每個案例被分配到了哪一類中,再探究不同的類在原始資料中各特徵的差異。

## Step 5: Improving model performance ----
# apply the cluster IDs to the original data frame
teens$cluster <- teen_clusters$cluster

# look at the first five records
teens[1:5, c("cluster", "gender", "age", "friends")]

# mean age by cluster
aggregate(data = teens, age ~ cluster, mean)

# proportion of females by cluster
aggregate(data = teens, female ~ cluster, mean)

# mean number of friends by cluster
aggregate(data = teens, friends ~ cluster, mean)

年齡、性別、朋友數量之間的關係表明,這些類是有用的預測因子,以這種方式來驗證這些類的預測能力。