Spark構建聚類模型(二)

weixin_34249678發表於2018-12-11
  1. 評估聚類模型的效能

    聚類的評估通常分為兩部分:內部評估和外部評估。內部評估表示評估過程使用訓練模型時使用的訓練資料,外部評估則使用訓練資料之外的資料。

  • 內部評價指標

    通用的內部評價指標包括WCSS(我們之前提過的K-元件的目標函式)、Davies-Bouldin指數、Dunn指數和輪廓係數(silhouette coefficient)。所有這些度量指標都是使類簇內部的樣本距離儘可能接近,不同類簇的樣本相對較遠。

  • 外部評價指標

    因為聚類被認為是無監督分類,如果有一些帶標註的資料,便可以用這些標籤來評估聚類模
    型。可以使用聚類模型預測類簇(類標籤),使用分類模型中類似的方法評估預測值和真實標籤的誤差(即真假陽性率和真假陰性率)。

  • 在MovieLens資料集計算效能

    MLlib提供的函式computeCost可以方便地計算出給定輸入資料RDD [Vector]的WCSS。下面我們使用這個方法計算電影和使用者訓練資料的效能

    val movieCost = movieClusterModel.computeCost(movieVectors)
    val userCost = userClusterModel.computeCost(userVectors)
    println("WCSS for movies: " + movieCost)
    WCSS for movies: 2273.1845750824914
    println("WCSS for users: " + userCost)
    WCSS for users: 1491.3740578499805
    
  1. 聚類模型引數調優

    不同於以往的模型, K-均值模型只有一個可以調的引數,就是K,即類中心數目

  • 通過交叉驗證選擇K

    類似分類和迴歸模型,我們可以應用交叉驗證來選擇模型最優的類中心數目。這和監督學習的過程一樣。需要將資料集分割為訓練集和測試集,然後在訓練集上訓練模型,在測試集上評估感興趣的指標的效能。如下程式碼用60/40劃分得到訓練集和測試集,並使用MLlib內建的WCSS類方法評估聚類模型的效能:

    val trainTestSplitMovies = movieVectors.randomSplit(Array(0.6, 0.4), 123)
    val trainMovies = trainTestSplitMovies(0)
    val testMovies = trainTestSplitMovies(1)
    val costsMovies = Seq(2, 3, 4, 5, 10, 20).map { k => (k, KMeans.
    train(trainMovies, numIterations, k, numRuns).computeCost(testMovies))
    }
    println("Movie clustering cross-validation:")
    Movie clustering cross-validation:
    costsMovies.foreach { case (k, cost) => println(f"WCSS for K=$k id $cost%2.2f") }
    WCSS for K=2 id 884.43
    WCSS for K=3 id 885.07
    WCSS for K=4 id 884.39
    WCSS for K=5 id 874.54
    WCSS for K=10 id 885.56
    WCSS for K=20 id 878.53
    
    

    為了實驗的完整性,我們還計算了使用者聚類在交叉驗證下的效能:

    val trainTestSplitUsers = userVectors.randomSplit(Array(0.6, 0.4), 123)
    val trainUsers = trainTestSplitUsers(0)
    val testUsers = trainTestSplitUsers(1)
    val costsUsers = Seq(2, 3, 4, 5, 10, 20).map { k => (k,
    KMeans.train(trainUsers, numIterations, k,
    numRuns).computeCost(testUsers)) }
    println("User clustering cross-validation:")
    costsUsers.foreach { case (k, cost) => println(f"WCSS for K=$k id $cost%2.2f") }
    WCSS for K=2 id 612.19
    WCSS for K=3 id 614.20
    WCSS for K=4 id 607.50
    WCSS for K=5 id 604.97
    WCSS for K=10 id 601.47
    WCSS for K=20 id 609.47
    
    

相關文章