k- 평균 군집화 에 대해 연구 해 왔으며 , 분명하지 않은 한 가지는 k 값을 선택하는 방법입니다. 그것은 시행 착오의 문제 일까, 아니면 더 있을까?
R
stackoverflow.com/a/15376462/1036500 : 이상 여기에)
k- 평균 군집화 에 대해 연구 해 왔으며 , 분명하지 않은 한 가지는 k 값을 선택하는 방법입니다. 그것은 시행 착오의 문제 일까, 아니면 더 있을까?
R
stackoverflow.com/a/15376462/1036500 : 이상 여기에)
답변:
베이지안 정보 기준 (BIC)을 최대화 할 수 있습니다.
BIC(C | X) = L(X | C) - (p / 2) * log n
여기서 L(X | C)
데이터 집합의 로그 우도되는 X
모델에있어서 C
, p
모델의 변수의 수이고 C
, 그리고 n
데이터 셋 포인트의 수이다. "X- 평균 : 군집 수를 효율적으로 추정하여 K- 평균 확장"을 참조하십시오 .ICML 2000에서 Dan Pelleg와 Andrew Moore의 .
또 다른 방법은 k
더 이상 설명 길이가 줄어들지 않을 때까지 중심 값을 제거하고 계속 제거하는 것입니다 (k 감소). 패턴 분석 및 응용 프로그램 vol. 에서 Horst Bischof, Ales Leonardis 및 Alexander Selb의 "강력한 벡터 정량화를위한 MDL 원리"를 참조하십시오 . 2, p. 1999-59-72.
마지막으로 하나의 군집으로 시작한 다음 각 군집에 지정된 점에 가우스 분포가있을 때까지 군집 분할을 유지할 수 있습니다. 에서 "배우기는 K 의 K -means" (2003 NIPS), 그렉 Hamerly 찰스 Elkan이 작품 더 나은 BIC 이상, 그리고 그 BIC가 충분히 강하게 모델의 복잡성을 처벌하지 않는 몇 가지 증거를 보여줍니다.
기본적으로 군집 수 ( k )와 군집 의 평균 분산이라는 두 변수 사이의 균형을 찾으려고 합니다. 전자를 최소화하면서 후자를 최소화하려고합니다. 물론 군집 수가 증가함에 따라 평균 분산이 감소합니다 ( k = n 의 사소한 경우까지). 및 분산 = 0 ).
데이터 분석에서 항상 그렇듯이 모든 경우에 다른 모든 방법보다 효과적인 진정한 접근 방법은 없습니다. 결국, 당신은 당신 자신의 최고의 판단을 사용해야합니다. 이를 위해 평균 분산에 대한 군집 수를 표시하는 데 도움이됩니다 (여기서 k의 여러 값에 대해 알고리즘을 이미 실행했다고 가정 ). 그런 다음 곡선의 무릎에 클러스터 수를 사용할 수 있습니다.
예, 엘보우 방법을 사용하여 가장 많은 수의 클러스터를 찾을 수 있지만 스크립트를 사용하여 팔꿈치 그래프에서 클러스터의 값을 찾는 것이 번거 롭습니다. 팔꿈치 그래프를 관찰하고 팔꿈치 점을 직접 찾을 수 있지만 스크립트에서 찾는 것은 많은 작업이었습니다.
또 다른 옵션은 Silhouette Method 를 사용 하여 찾는 것입니다. Silhouette의 결과는 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)
Thumb of Thumb이라는 것이 있습니다. 클러스터 수는 다음과 같이 계산할 수 있다고 말합니다.
k = (n/2)^0.5
여기서 n은 샘플의 총 요소 수입니다. 다음 문서에서이 정보의 정확성을 확인할 수 있습니다.
http://www.ijarcsms.com/docs/paper/volume1/issue6/V1I6-0015.pdf
분포가 가우스 분포 또는 정규 분포를 따르는 G- 평균이라는 다른 방법도 있습니다. 모든 k 그룹이 가우스 분포를 따를 때까지 k를 증가시키는 것으로 구성됩니다. 많은 통계가 필요하지만 수행 할 수 있습니다. 소스는 다음과 같습니다.
http://papers.nips.cc/paper/2526-learning-the-k-in-k-means.pdf
이게 도움이 되길 바란다!
먼저 데이터 의 최소 스패닝 트리 를 작성하십시오. 가장 비싼 K-1 모서리를 제거하면 트리가 K 클러스터로 분할
되므로 MST를 한 번 작성하고 다양한 K에 대한 클러스터 간격 / 메트릭을보고 곡선을 찾을 수 있습니다.
이것은 Single-linkage_clustering 에만 작동 하지만 빠르고 쉽습니다. 또한, MST는 좋은 시각 자료를 만듭니다.
예를 들어 클러스터링을위한 stats.stackexchange 시각화 소프트웨어 에서 MST 플롯을 참조하십시오
.
아무도이 훌륭한 기사를 언급하지 않은 것에 놀랐습니다 : 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/
그 후 스칼라에서 구현했으며 사용 사례에 실제로 좋은 결과를 제공하는 구현입니다. 코드는 다음과 같습니다.
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]]
}
2013b 이후의 모든 버전 인 MATLAB을 사용하는 경우 즉, 함수 evalclusters
를 사용 k
하여 주어진 데이터 세트에 가장 적합한 항목을 찾을 수 있습니다.
-이 기능을 사용하면 3 클러스터링 알고리즘 중에서 선택할 수 있습니다 kmeans
, linkage
하고 gmdistribution
.
- 그것은 또한 당신이 4 클러스터링 평가 기준 중에서 선택할 수 있습니다 CalinskiHarabasz
, DaviesBouldin
, gap
와 silhouette
.
k- 평균에 매개 변수로 제공 할 군집 k의 수를 모르면 자동으로 찾는 4 가지 방법이 있습니다.
G- 평균 알고리즘 : 통계적 테스트를 사용하여 k- 평균 중심을 2 개로 분할할지 여부를 결정하는 군집 수를 자동으로 검색합니다. 이 알고리즘은 데이터의 하위 집합이 가우스 분포 (이벤트의 정확한 이항 분포를 근사하는 연속 함수)를 따르는 가설에 대한 통계적 테스트를 기반으로 클러스터 수를 탐지하기위한 계층 적 접근 방식을 취하며, 그렇지 않은 경우 클러스터를 분할합니다. . 그것은 적은 수의 중심으로 시작합니다 (예 : 하나의 클러스터 만 (k = 1)), 알고리즘은 그것을 두 개의 중심 (k = 2)으로 나누고이 두 중심을 다시 분할합니다 (k = 4). 합계. G- 평균이이 4 개의 중심을 받아들이지 않으면 답은 이전 단계입니다.이 경우에는 2 개의 중심 (k = 2)입니다. 이것은 데이터 세트가 분할 될 클러스터의 수입니다. G- 평균은 인스턴스를 그룹화 한 후 얻을 수있는 군집 수를 예측할 수 없을 때 매우 유용합니다. "k"매개 변수를 잘못 선택하면 잘못된 결과가 나타날 수 있습니다. g- 평균의 병렬 버전을p- 평균 . G- 평균 소스 : 소스 1 소스 2 소스 3
x-means : 효율적으로 클러스터 위치 공간과 클러스터 수를 검색하여 BIC (Bayesian Information Criterion) 또는 AIC (Akaike Information Criterion) 측정을 최적화합니다. 이 버전의 k- 평균은 숫자 k를 찾고 k- 평균을 가속화합니다.
온라인 k- 평균 또는 스트리밍 k- 평균 : 전체 데이터를 한 번 스캔하여 k- 평균을 실행할 수 있으며 최적의 k 수를 자동으로 찾습니다. Spark가 구현합니다.
MeanShift 알고리즘 : 클러스터의 수에 대한 사전 지식이 필요하지 않고 클러스터의 모양을 제한하지 않는 비모수 적 클러스터링 기술입니다. 평균 이동 클러스터링은 매끄러운 밀도의 샘플에서 "블롭"을 발견하는 것을 목표로합니다. 중심 기반 알고리즘으로, 중심에 대한 후보를 지정된 지역 내 포인트의 평균으로 업데이트하여 작동합니다. 그런 다음 이러한 후보를 후 처리 단계에서 필터링하여 거의 중복되는 부분을 제거하여 최종 중심 세트를 형성합니다. 소스 : 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)를 찾는 것입니다. 자세한 설명은 여기에 있습니다 .
가능한 대답 중 하나는 유전자 알고리즘과 같은 메타 휴리스틱 알고리즘을 사용하여 k를 찾는 것입니다. 간단합니다. 임의의 K (일부 범위)를 사용하고 Silhouette And Fit과 같은 최적의 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})
또 다른 방법은 SOP (Self Organizing Maps)를 사용하여 최적의 클러스터 수를 찾는 것입니다. SOM (Self-Organizing Map)은 감독되지 않은 신경망 방법론으로, 문제 해결을 위해 입력 만 클러스터링에 사용하면됩니다. 이 접근법은 고객 세분화에 관한 논문에서 사용되었습니다.
논문의 참조는
Abdellah Amine et al., 클러스터링 기술 및 LRFM 모델을 사용한 전자 상거래에서의 고객 세분화 모델 : 모로코 온라인 매장 사례, 세계 과학 기술 공학 아카데미 국제 컴퓨터 및 정보 공학 저널 Vol : 9, No : 8 , 2015, 1999-2010
안녕하세요, 간단하고 간단하게 설명하겠습니다. 'NbClust'라이브러리를 사용하여 클러스터를 결정하고 싶습니다.
이제 'NbClust'함수를 사용하여 올바른 클러스터 수를 결정하는 방법 : 실제 데이터 및 클러스터를 사용하여 Github의 실제 프로젝트를 확인할 수 있습니다.이 'kmeans'알고리즘에 대한 범위도 올바른 수의 '센터'를 사용하여 수행됩니다.
Github 프로젝트 링크 : https://github.com/RutvijBhutaiya/Thailand-Customer-Engagement-Facebook
데이터 포인트를 육안으로 검사하여 클러스터 수를 선택할 수 있지만, 가장 간단한 데이터 세트를 제외한 모든 프로세스에 대해이 프로세스에 많은 모호성이 있음을 곧 알게 될 것입니다. 감독되지 않은 학습을 수행하고 라벨링 프로세스에 고유 한 주관성이 있기 때문에 항상 나쁜 것은 아닙니다. 여기서 특정 문제 또는 이와 비슷한 문제에 대한 이전 경험이 있으면 올바른 가치를 선택하는 데 도움이됩니다.
사용해야하는 군집 수에 대한 힌트를 원하면 Elbow 방법을 적용 할 수 있습니다.
먼저 k의 일부 값 (예 : 2, 4, 6, 8 등)에 대한 제곱 오차의 합 (SSE)을 계산하십시오. SSE는 군집의 각 구성원과 중심 사이의 제곱 거리의 합으로 정의됩니다. 수학적으로 :
SSE = ∑Ki = 1∑x∈cidist (x, ci) 2
SSE에 대해 k를 플로팅하면 k가 커질수록 오류가 줄어드는 것을 볼 수 있습니다. 클러스터 수가 증가하면 더 작아야하기 때문에 왜곡도 작아지기 때문입니다. 엘보우 방법의 아이디어는 SSE가 갑자기 감소하는 k를 선택하는 것입니다. 다음 그림에서 볼 수 있듯이 그래프에 "팔꿈치 효과"가 생성됩니다.
이 경우 k = 6은 엘보우 방법이 선택한 값입니다. 엘보우 방법은 휴리스틱이므로 특정 경우에는 제대로 작동하지 않을 수 있습니다. 때로는 팔꿈치가 두 개 이상이거나 팔꿈치가 전혀없는 경우가 있습니다. 이러한 상황에서는 일반적으로 해결하려는 특정 군집 문제와 관련하여 k- 평균의 성능을 평가하여 최상의 k를 계산하게됩니다.
나는 Python 패키지 kneed (Kneedle 알고리즘)에서 일했습니다. 곡선이 평평 해지기 시작하는 지점으로 군집 수를 동적으로 찾습니다. 니 포인트는 최대 곡률의 포인트입니다. 샘플 코드는 다음과 같습니다.
Y = [7342.1301373073857, 6881.7109460930769, 6531.1657905495022,
6356.2255554679778, 6209.8382535595829, 6094.9052166741121, 5980.0191582610196, 5880.1869867848218, 5779.8957906367368, 5691.1879324562778, 5617.5153566271356, 5532.2613232619951, 5467.352265375117, 5395.4493783888756, 5345.3459908298091, 5290.6769823693812, 5243.5271656371888, 5207.2501206569532, 5164.9617535255456]
x = 범위 (1, len (y) +1)
니들 임포트에서 KneeLocator kn = KneeLocator (x, y, 곡선 = '볼록한', 방향 = '감소')
프린트 (무릎)