ฉันกำลังศึกษาเกี่ยวกับการจัดกลุ่ม k หมายถึงและสิ่งหนึ่งที่ไม่ชัดเจนคือวิธีที่คุณเลือกคุณค่าของ k มันเป็นเพียงแค่เรื่องของการลองผิดลองถูกหรือมีมากกว่านั้นใช่ไหม
R
) ที่นี่: stackoverflow.com/a/15376462/1036500
ฉันกำลังศึกษาเกี่ยวกับการจัดกลุ่ม k หมายถึงและสิ่งหนึ่งที่ไม่ชัดเจนคือวิธีที่คุณเลือกคุณค่าของ k มันเป็นเพียงแค่เรื่องของการลองผิดลองถูกหรือมีมากกว่านั้นใช่ไหม
R
) ที่นี่: stackoverflow.com/a/15376462/1036500
คำตอบ:
คุณสามารถเพิ่มเกณฑ์ข้อมูล Bayesian (BIC) ให้สูงสุด:
BIC(C | X) = L(X | C) - (p / 2) * log n
ที่L(X | C)
จะเข้าสู่ระบบน่าจะเป็นของชุดข้อมูลX
ตามรูปแบบC
, p
คือจำนวนของพารามิเตอร์ในรูปแบบC
และn
เป็นจำนวนจุดในชุดข้อมูล ดู"X- mean : การขยายK- MEans ด้วยการประมาณจำนวนกลุ่มอย่างมีประสิทธิภาพ"โดย Dan Pelleg และ Andrew Moore ใน ICML 2000
อีกวิธีคือการเริ่มต้นด้วยค่าที่มากสำหรับk
และกำจัด centroids (ลด k) จนกว่ามันจะไม่ลดความยาวของคำอธิบายอีกต่อไป ดูหลักการ "MDL สำหรับการประมาณเวกเตอร์ที่แข็งแกร่ง"โดย Horst Bischof, เอลส์ Leonardis และอเล็กซานเด Selb ในการวิเคราะห์รูปแบบและการประยุกต์ใช้ฉบับ 2, p. 59-72, 2542
ในที่สุดคุณสามารถเริ่มต้นด้วยหนึ่งคลัสเตอร์จากนั้นให้แยกกลุ่มจนกว่าจุดที่กำหนดให้แต่ละกลุ่มมีการกระจายแบบเกาส์เซียน ใน"การเรียนรู้kในk- means" (NIPS 2003), Greg Hamerly และ Charles Elkan แสดงหลักฐานว่าการทำงานนี้ดีกว่า BIC และ BIC ไม่ได้ลงโทษความซับซ้อนของโมเดลอย่างรุนแรงเพียงพอ
โดยทั่วไปคุณต้องการค้นหาความสมดุลระหว่างสองตัวแปร: จำนวนของกลุ่ม ( k ) และความแปรปรวนเฉลี่ยของกลุ่ม คุณต้องการย่อเล็กสุดในขณะที่ยังย่อเล็กสุดไว้ แน่นอนว่าเมื่อจำนวนของกลุ่มเพิ่มขึ้นความแปรปรวนเฉลี่ยจะลดลง (ขึ้นอยู่กับกรณีเล็กน้อยของk = nและความแปรปรวน = 0)
เช่นเดียวกับในการวิเคราะห์ข้อมูลไม่มีวิธีการใดวิธีการหนึ่งที่ทำงานได้ดีกว่าวิธีอื่น ๆ ในทุกกรณี ในท้ายที่สุดคุณต้องใช้วิจารณญาณที่ดีที่สุดของคุณเอง สำหรับสิ่งนั้นจะช่วยในการพล็อตจำนวนกลุ่มเทียบกับความแปรปรวนเฉลี่ย (ซึ่งถือว่าคุณได้รันอัลกอริทึมสำหรับค่าkหลาย ๆ ค่าแล้ว) จากนั้นคุณสามารถใช้จำนวนกลุ่มที่หัวเข่าของโค้ง
ใช่คุณสามารถค้นหาจำนวนกลุ่มที่ดีที่สุดโดยใช้วิธี Elbow แต่ฉันพบว่ามันลำบากที่จะหาค่าของกลุ่มจากกราฟ elbow โดยใช้สคริปต์ คุณสามารถสังเกตกราฟข้อศอกและค้นหาจุดศอกด้วยตัวคุณเอง แต่มันก็เป็นงานจำนวนมากที่ค้นหาได้จากสคริปต์
อีกทางเลือกหนึ่งคือการใช้Silhouette Methodเพื่อค้นหา ผลลัพธ์จาก Silhouette สอดคล้องกับผลลัพธ์จากวิธี Elbow ใน R อย่างสมบูรณ์
นี่คือสิ่งที่ฉันทำ
#Dataset for Clustering
n = 150
g = 6
set.seed(g)
d <- data.frame(x = unlist(lapply(1:g, function(i) rnorm(n/g, runif(1)*i^2))),
y = unlist(lapply(1:g, function(i) rnorm(n/g, runif(1)*i^2))))
mydata<-d
#Plot 3X2 plots
attach(mtcars)
par(mfrow=c(3,2))
#Plot the original dataset
plot(mydata$x,mydata$y,main="Original Dataset")
#Scree plot to deterine the number of clusters
wss <- (nrow(mydata)-1)*sum(apply(mydata,2,var))
for (i in 2:15) {
wss[i] <- sum(kmeans(mydata,centers=i)$withinss)
}
plot(1:15, wss, type="b", xlab="Number of Clusters",ylab="Within groups sum of squares")
# Ward Hierarchical Clustering
d <- dist(mydata, method = "euclidean") # distance matrix
fit <- hclust(d, method="ward")
plot(fit) # display dendogram
groups <- cutree(fit, k=5) # cut tree into 5 clusters
# draw dendogram with red borders around the 5 clusters
rect.hclust(fit, k=5, border="red")
#Silhouette analysis for determining the number of clusters
library(fpc)
asw <- numeric(20)
for (k in 2:20)
asw[[k]] <- pam(mydata, k) $ silinfo $ avg.width
k.best <- which.max(asw)
cat("silhouette-optimal number of clusters:", k.best, "\n")
plot(pam(d, k.best))
# K-Means Cluster Analysis
fit <- kmeans(mydata,k.best)
mydata
# get cluster means
aggregate(mydata,by=list(fit$cluster),FUN=mean)
# append cluster assignment
mydata <- data.frame(mydata, clusterid=fit$cluster)
plot(mydata$x,mydata$y, col = fit$cluster, main="K-means Clustering results")
หวังว่ามันจะช่วย !!
อาจเป็นคนที่เริ่มต้นอย่างฉันกำลังมองหาตัวอย่างโค้ด ข้อมูลสำหรับsilhouette_score มีให้ที่นี่
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
range_n_clusters = [2, 3, 4] # clusters range you want to select
dataToFit = [[12,23],[112,46],[45,23]] # sample data
best_clusters = 0 # best cluster number which you will get
previous_silh_avg = 0.0
for n_clusters in range_n_clusters:
clusterer = KMeans(n_clusters=n_clusters)
cluster_labels = clusterer.fit_predict(dataToFit)
silhouette_avg = silhouette_score(dataToFit, cluster_labels)
if silhouette_avg > previous_silh_avg:
previous_silh_avg = silhouette_avg
best_clusters = n_clusters
# Final Kmeans for best_clusters
kmeans = KMeans(n_clusters=best_clusters, random_state=0).fit(dataToFit)
ดูกระดาษนี้ "การเรียนรู้ k ในค่าเฉลี่ย k" โดย Greg Hamerly, Charles Elkan ใช้การทดสอบแบบเกาส์เพื่อกำหนดจำนวนที่เหมาะสมของกลุ่ม นอกจากนี้ผู้เขียนอ้างว่าวิธีนี้ดีกว่า BIC ซึ่งกล่าวถึงในคำตอบที่ยอมรับ
มีบางอย่างที่เรียกว่า Rule of Thumb มันบอกว่าสามารถคำนวณจำนวนกลุ่มได้
k = (n/2)^0.5
โดยที่ n คือจำนวนองค์ประกอบทั้งหมดจากตัวอย่างของคุณ คุณสามารถตรวจสอบความถูกต้องของข้อมูลนี้ได้จากเอกสารต่อไปนี้:
http://www.ijarcsms.com/docs/paper/volume1/issue6/V1I6-0015.pdf
นอกจากนี้ยังมีวิธีอื่นที่เรียกว่า G-mean ซึ่งการกระจายของคุณเป็นไปตามการแจกแจงแบบเกาส์หรือการแจกแจงแบบปกติ ประกอบด้วยการเพิ่ม k จนกระทั่งกลุ่ม k ทั้งหมดของคุณติดตามการกระจายแบบเกาส์เซียน มันต้องใช้สถิติเป็นจำนวนมาก แต่สามารถทำได้ นี่คือแหล่งที่มา:
http://papers.nips.cc/paper/2526-learning-the-k-in-k-means.pdf
ฉันหวังว่านี่จะช่วยได้!
ขั้นแรกให้สร้างแผนภูมิทอดข้อมูลขั้นต่ำของคุณ การลบ K-1 ที่แพงที่สุดจะแบ่งต้นไม้ออกเป็นกลุ่ม K
ดังนั้นคุณจึงสามารถสร้าง MST ครั้งเดียวดูที่การเว้นวรรคแบบกระจุกดาว / ตัวชี้วัดสำหรับ K ต่างๆและนำหัวเข่าของเส้นโค้ง
ใช้งานได้กับSingle-linkage_clusteringเท่านั้น แต่ใช้งานได้ง่ายและรวดเร็ว นอกจากนี้ MST ยังให้ภาพที่ดี
ดูตัวอย่างพล็อต MST ภายใต้
ซอฟต์แวร์สร้างภาพ stats.stackexchange สำหรับการจัดกลุ่ม
ฉันประหลาดใจที่ไม่มีใครพูดถึงบทความที่ยอดเยี่ยมนี้: http://www.ee.columbia.edu/~dpwe/papers/PhamDN05-kmeans.pdf
หลังจากทำตามคำแนะนำอื่น ๆ ในที่สุดฉันก็เจอบทความนี้ในขณะที่อ่านบล็อกนี้: https://datasciencelab.wordpress.com/2014/01/21/selection-of-k-in-k-means-clustering-reloaded/
หลังจากนั้นฉันนำมาใช้ใน Scala การดำเนินการซึ่งสำหรับกรณีการใช้งานของฉันให้ผลลัพธ์ที่ดีจริงๆ นี่คือรหัส:
import breeze.linalg.DenseVector
import Kmeans.{Features, _}
import nak.cluster.{Kmeans => NakKmeans}
import scala.collection.immutable.IndexedSeq
import scala.collection.mutable.ListBuffer
/*
https://datasciencelab.wordpress.com/2014/01/21/selection-of-k-in-k-means-clustering-reloaded/
*/
class Kmeans(features: Features) {
def fkAlphaDispersionCentroids(k: Int, dispersionOfKMinus1: Double = 0d, alphaOfKMinus1: Double = 1d): (Double, Double, Double, Features) = {
if (1 == k || 0d == dispersionOfKMinus1) (1d, 1d, 1d, Vector.empty)
else {
val featureDimensions = features.headOption.map(_.size).getOrElse(1)
val (dispersion, centroids: Features) = new NakKmeans[DenseVector[Double]](features).run(k)
val alpha =
if (2 == k) 1d - 3d / (4d * featureDimensions)
else alphaOfKMinus1 + (1d - alphaOfKMinus1) / 6d
val fk = dispersion / (alpha * dispersionOfKMinus1)
(fk, alpha, dispersion, centroids)
}
}
def fks(maxK: Int = maxK): List[(Double, Double, Double, Features)] = {
val fadcs = ListBuffer[(Double, Double, Double, Features)](fkAlphaDispersionCentroids(1))
var k = 2
while (k <= maxK) {
val (fk, alpha, dispersion, features) = fadcs(k - 2)
fadcs += fkAlphaDispersionCentroids(k, dispersion, alpha)
k += 1
}
fadcs.toList
}
def detK: (Double, Features) = {
val vals = fks().minBy(_._1)
(vals._3, vals._4)
}
}
object Kmeans {
val maxK = 10
type Features = IndexedSeq[DenseVector[Double]]
}
หากคุณใช้ MATLAB เวอร์ชันใด ๆ นับตั้งแต่ปี 2013b นั่นคือคุณสามารถใช้ฟังก์ชันevalclusters
เพื่อค้นหาสิ่งที่เหมาะสมที่สุดk
สำหรับชุดข้อมูลที่กำหนด
ฟังก์ชั่นนี้ช่วยให้คุณเลือกจาก 3 ขั้นตอนวิธีการจัดกลุ่ม - kmeans
, และlinkage
gmdistribution
นอกจากนี้ยังช่วยให้คุณสามารถเลือกจาก 4 การจัดกลุ่มเกณฑ์การประเมิน - CalinskiHarabasz
, DaviesBouldin
, และgap
silhouette
หากคุณไม่ทราบจำนวนกลุ่ม k ที่จะให้เป็นพารามิเตอร์ให้กับ k-mean ดังนั้นจึงมีสี่วิธีในการค้นหาโดยอัตโนมัติ:
G-mean algortithm: ค้นพบจำนวนของกลุ่มโดยอัตโนมัติโดยใช้การทดสอบทางสถิติเพื่อตัดสินใจว่าจะแบ่งจุดกึ่งกลาง k-mean ออกเป็นสองส่วนหรือไม่ อัลกอริทึมนี้ใช้วิธีการลำดับชั้นในการตรวจสอบจำนวนกลุ่มตามการทดสอบทางสถิติสำหรับสมมติฐานที่ว่าเซตย่อยของข้อมูลเป็นไปตามการแจกแจงแบบเกาส์ (ฟังก์ชั่นต่อเนื่องซึ่งประมาณการกระจายแบบทวินามที่แน่นอนของเหตุการณ์) . มันเริ่มต้นด้วยศูนย์จำนวนน้อยพูดหนึ่งคลัสเตอร์เท่านั้น (k = 1) จากนั้นอัลกอริทึมจะแยกมันออกเป็นสองศูนย์ (k = 2) และแยกแต่ละศูนย์ทั้งสองนี้อีกครั้ง (k = 4) โดยมีสี่ศูนย์ใน รวม. ถ้า G-mean ไม่ยอมรับสี่ศูนย์เหล่านี้คำตอบคือขั้นตอนก่อนหน้า: สองศูนย์ในกรณีนี้ (k = 2) นี่คือจำนวนของกลุ่มข้อมูลของคุณที่จะถูกแบ่งออกเป็น G-mean มีประโยชน์มากเมื่อคุณไม่มีการประมาณจำนวนกลุ่มที่คุณจะได้รับหลังจากจัดกลุ่มอินสแตนซ์ของคุณ โปรดสังเกตว่าตัวเลือกที่ไม่สะดวกสำหรับพารามิเตอร์ "k" อาจให้ผลลัพธ์ที่ไม่ถูกต้องแก่คุณ g-mean รุ่นคู่ขนานถูกเรียกใช้P-วิธี แหล่งที่มาของ G-mean: แหล่งที่มา 1 แหล่งที่มา 2 แหล่งที่มา 3
x-mean : อัลกอริทึมใหม่ที่มีประสิทธิภาพค้นหาพื้นที่ของที่ตั้งคลัสเตอร์และจำนวนของกลุ่มเพื่อปรับเกณฑ์ข้อมูล Bayesian Information Criterion (BIC) หรือมาตรการ Akaike Information Criterion (AIC) k-mean รุ่นนี้ค้นหาหมายเลข k และเร่ง k-mean
ออนไลน์ k- หมายถึงหรือ k- หมายถึงการสตรีมมิ่ง: อนุญาตให้ดำเนินการ k- หมายถึงโดยการสแกนข้อมูลทั้งหมดครั้งเดียวและพบโดยอัตโนมัติจำนวนที่เหมาะสมของ k ประกายไฟใช้มัน
อัลกอริทึม MeanShift : มันเป็นเทคนิคการจัดกลุ่มแบบไม่ใช้พารามิเตอร์ซึ่งไม่จำเป็นต้องมีความรู้มาก่อนเกี่ยวกับจำนวนของกลุ่มและไม่ จำกัด รูปร่างของกลุ่ม หมายถึงการจัดกลุ่มกะมีจุดมุ่งหมายเพื่อค้นหา "blobs" ในตัวอย่างที่มีความหนาแน่น มันเป็นอัลกอริธึมที่ใช้เซนทรอยด์ซึ่งทำงานโดยการอัพเดทผู้สมัครสำหรับเซนทรอยด์ให้เป็นค่าเฉลี่ยของคะแนนภายในภูมิภาคที่กำหนด ผู้สมัครเหล่านี้จะถูกกรองในขั้นตอนหลังการประมวลผลเพื่อกำจัดรายการที่ซ้ำซ้อนใกล้กับแบบฟอร์มชุดสุดท้ายของ centroids แหล่งที่มา: source1 , source2 , source3
ฉันใช้วิธีแก้ปัญหาที่พบที่นี่: http://efavdb.com/mean-shift/และมันทำงานได้ดีมากสำหรับฉัน:
import numpy as np
from sklearn.cluster import MeanShift, estimate_bandwidth
from sklearn.datasets.samples_generator import make_blobs
import matplotlib.pyplot as plt
from itertools import cycle
from PIL import Image
#%% Generate sample data
centers = [[1, 1], [-.75, -1], [1, -1], [-3, 2]]
X, _ = make_blobs(n_samples=10000, centers=centers, cluster_std=0.6)
#%% Compute clustering with MeanShift
# The bandwidth can be automatically estimated
bandwidth = estimate_bandwidth(X, quantile=.1,
n_samples=500)
ms = MeanShift(bandwidth=bandwidth, bin_seeding=True)
ms.fit(X)
labels = ms.labels_
cluster_centers = ms.cluster_centers_
n_clusters_ = labels.max()+1
#%% Plot result
plt.figure(1)
plt.clf()
colors = cycle('bgrcmykbgrcmykbgrcmykbgrcmyk')
for k, col in zip(range(n_clusters_), colors):
my_members = labels == k
cluster_center = cluster_centers[k]
plt.plot(X[my_members, 0], X[my_members, 1], col + '.')
plt.plot(cluster_center[0], cluster_center[1],
'o', markerfacecolor=col,
markeredgecolor='k', markersize=14)
plt.title('Estimated number of clusters: %d' % n_clusters_)
plt.show()
ความคิดของฉันคือการใช้Silhouette Coefficientเพื่อค้นหาหมายเลขคลัสเตอร์ที่ดีที่สุด (K) รายละเอียดคำอธิบายที่นี่
สมมติว่าคุณมีเมทริกซ์ของข้อมูลที่เรียกว่าDATA
คุณสามารถทำการแบ่งพาร์ติชันบริเวณใกล้เคียงด้วยการประมาณจำนวนกลุ่ม (โดยการวิเคราะห์ภาพเงา) ดังนี้:
library(fpc)
maxk <- 20 # arbitrary here, you can set this to whatever you like
estimatedK <- pamk(dist(DATA), krange=1:maxk)$nc
คำตอบหนึ่งที่เป็นไปได้คือใช้อัลกอริทึม Meta Heuristic เช่น Genetic Algorithm เพื่อค้นหา k ง่ายมาก คุณสามารถใช้ K แบบสุ่ม (ในบางช่วง) และประเมินฟังก์ชั่นที่เหมาะสมของอัลกอริทึมทางพันธุกรรมกับการวัดบางอย่างเช่น Silhouette และค้นหา K ที่ดีที่สุดบนฟังก์ชั่นพอดี
km=[]
for i in range(num_data.shape[1]):
kmeans = KMeans(n_clusters=ncluster[i])#we take number of cluster bandwidth theory
ndata=num_data[[i]].dropna()
ndata['labels']=kmeans.fit_predict(ndata.values)
cluster=ndata
co=cluster.groupby(['labels'])[cluster.columns[0]].count()#count for frequency
me=cluster.groupby(['labels'])[cluster.columns[0]].median()#median
ma=cluster.groupby(['labels'])[cluster.columns[0]].max()#Maximum
mi=cluster.groupby(['labels'])[cluster.columns[0]].min()#Minimum
stat=pd.concat([mi,ma,me,co],axis=1)#Add all column
stat['variable']=stat.columns[1]#Column name change
stat.columns=['Minimum','Maximum','Median','count','variable']
l=[]
for j in range(ncluster[i]):
n=[mi.loc[j],ma.loc[j]]
l.append(n)
stat['Class']=l
stat=stat.sort(['Minimum'])
stat=stat[['variable','Class','Minimum','Maximum','Median','count']]
if missing_num.iloc[i]>0:
stat.loc[ncluster[i]]=0
if stat.iloc[ncluster[i],5]==0:
stat.iloc[ncluster[i],5]=missing_num.iloc[i]
stat.iloc[ncluster[i],0]=stat.iloc[0,0]
stat['Percentage']=(stat[[5]])*100/count_row#Freq PERCENTAGE
stat['Cumulative Percentage']=stat['Percentage'].cumsum()
km.append(stat)
cluster=pd.concat(km,axis=0)## see documentation for more info
cluster=cluster.round({'Minimum': 2, 'Maximum': 2,'Median':2,'Percentage':2,'Cumulative Percentage':2})
อีกวิธีหนึ่งคือการใช้ Self Organing Maps (SOP) เพื่อค้นหาจำนวนที่เหมาะสมของกระจุก SOM (Self-Organisation Map) เป็นวิธีการโครงข่ายประสาทที่ไม่ได้รับการสนับสนุนซึ่งต้องการเพียงอินพุตที่ใช้ในการจัดกลุ่มเพื่อแก้ไขปัญหา วิธีนี้ใช้ในเอกสารเกี่ยวกับการแบ่งส่วนลูกค้า
การอ้างอิงของกระดาษคือ
Abdellah Amine et al. รูปแบบการแบ่งกลุ่มลูกค้าใน E-commerce โดยใช้เทคนิคการจัดกลุ่มและรุ่น LRFM: กรณีของร้านค้าออนไลน์ในโมร็อกโกสถาบันวิทยาศาสตร์วิทยาศาสตร์วิศวกรรมศาสตร์และเทคโนโลยีนานาชาติวารสารคอมพิวเตอร์และสารสนเทศระดับโลกฉบับที่ 9: 8 , 2015, 1999 - 2010
สวัสดีฉันจะทำให้มันง่ายและตรงไปตรงมาเพื่ออธิบายฉันต้องการตรวจสอบกลุ่มโดยใช้ห้องสมุด 'NbClust'
ตอนนี้วิธีการใช้ฟังก์ชั่น 'NbClust' เพื่อกำหนดจำนวนที่เหมาะสมของกลุ่ม: คุณสามารถตรวจสอบโครงการจริงใน Github ด้วยข้อมูลและกลุ่มจริง - การขยายอัลกอริทึม 'kmeans' นี้ยังใช้หมายเลข 'ศูนย์' ที่เหมาะสม
ลิงค์โครงการ Github: https://github.com/RutvijBhutaiya/Thailand-Customer-Engagement-Facebook
คุณสามารถเลือกจำนวนกลุ่มโดยการตรวจสอบจุดข้อมูลของคุณ แต่คุณจะรู้ว่ามีความคลุมเครือจำนวนมากในกระบวนการนี้สำหรับทุกคนยกเว้นชุดข้อมูลที่ง่ายที่สุด สิ่งนี้ไม่ได้เลวร้ายเสมอไปเพราะคุณกำลังเรียนรู้อย่างไม่มีการดูแลและมีความเป็นตัวตนบางอย่างในกระบวนการติดฉลาก ที่นี่การมีประสบการณ์ก่อนหน้านี้กับปัญหานั้น ๆ หรือสิ่งที่คล้ายกันจะช่วยให้คุณเลือกค่าที่เหมาะสม
หากคุณต้องการคำใบ้เกี่ยวกับจำนวนกลุ่มที่คุณควรใช้คุณสามารถใช้วิธี Elbow:
ก่อนอื่นให้คำนวณผลรวมของข้อผิดพลาดกำลังสอง (SSE) สำหรับค่าบางค่าของ k (เช่น 2, 4, 6, 8, ฯลฯ ) SSE หมายถึงผลรวมของระยะห่างกำลังสองระหว่างสมาชิกแต่ละกลุ่มของคลัสเตอร์และเซนทรอยด์ ศาสตร์:
SSE = = ΣKi1Σx∈cidist (x, CI) 2
หากคุณพล็อต k กับ SSE คุณจะเห็นว่าข้อผิดพลาดลดลงเมื่อ k มีขนาดใหญ่ขึ้น เนื่องจากเมื่อจำนวนคลัสเตอร์เพิ่มขึ้นควรมีขนาดเล็กลงดังนั้นความเพี้ยนจึงน้อยลง แนวคิดของวิธีข้อศอกคือการเลือก k ที่ SSE ลดลงอย่างกระทันหัน สิ่งนี้จะสร้าง "ผลข้อศอก" ในกราฟตามที่คุณเห็นในภาพต่อไปนี้:
ในกรณีนี้ k = 6 คือค่าที่เลือกวิธี Elbow พิจารณาว่าวิธี Elbow นั้นเป็นวิธีแก้ปัญหาด้วยวิธีนี้และอาจทำงานได้ไม่ดีในกรณีของคุณ บางครั้งมีข้อศอกมากกว่าหนึ่งหรือไม่มีข้อศอกเลย ในสถานการณ์เหล่านั้นคุณมักจะสิ้นสุดการคำนวณ k ที่ดีที่สุดโดยการประเมินว่า k-mean มีประสิทธิภาพอย่างไรในบริบทของปัญหาการจัดกลุ่มเฉพาะที่คุณพยายามแก้ไข
ฉันทำงานกับแพคเกจ Python kneed (อัลกอริทึม Kneedle) พบว่าจำนวนกลุ่มแบบไดนามิกเป็นจุดที่เส้นโค้งเริ่มแบน .. ได้รับชุดของค่า x และ y, kneed จะกลับจุดหัวเข่าของฟังก์ชั่น จุดเข่าเป็นจุดที่มีความโค้งสูงสุดนี่คือตัวอย่างรหัส
Y = [7,342.1301373073857, 6,881.7109460930769, 6,531.1657905495022,
6,356.2255554679778, 6,209.8382535595829, 6,094.9052166741121, 5,980.0191582610196, 5,880.1869867848218, 5,779.8957906367368, 5,691.1879324562778, 5,617.5153566271356, 5,532.2613232619951, 5,467.352265375117, 5,395.4493783888756, 5,345.3459908298091, 5,290.6769823693812, 5,243.5271656371888, 5,207.2501206569532, 5,164.9617535255456]
x = ช่วง (1, len (y) +1)
จากการนำเข้า kneed KneeLocator kn = KneeLocator (x, y, curve = 'นูน', direction = 'ลดลง')
พิมพ์ (kn.knee)