Risposte:
Un approccio che produce risultati più coerenti è K-mean ++ . Questo approccio riconosce che esiste probabilmente una scelta migliore delle posizioni del centroide iniziale rispetto alla semplice assegnazione casuale. In particolare, i mezzi K tendono a funzionare meglio quando i centroidi sono seminati in modo tale da non raggrupparli nello spazio.
In breve, il metodo è il seguente:
Nota: deve essere aggiornato man mano che vengono aggiunti più centroidi. Dovrebbe essere impostato per essere la distanza tra un punto dati e il centroide più vicino.
Potresti anche essere interessato a leggere questo documento che propone il metodo e descrive le prestazioni complessive previste.
Potrei fraintendere la tua domanda, ma di solito k-mean sceglie i tuoi centroidi in modo casuale per te a seconda del numero di cluster che hai impostato (cioè k). Scegliere il numero per k tende ad essere un esercizio soggettivo. Un buon punto di partenza è una trama Elbow / Scree che può essere trovata qui:
http://en.wikipedia.org/wiki/Determining_the_number_of_clusters_in_a_data_set#The_Elbow_Method
L'approccio usuale a questo problema è rieseguire l'algoritmo K-mean più volte, con diverse inizializzazioni casuali dei centroidi e mantenere la soluzione migliore. Puoi farlo valutando i risultati sui tuoi dati di allenamento o attraverso la validazione incrociata.
Esistono molti altri modi per inizializzare i centroidi, ma nessuno di questi funzionerà al meglio per ogni singolo problema. È possibile valutare questi approcci insieme all'inizializzazione casuale per il problema specifico.
Sono d'accordo con la trama Elbow / Scree. L'ho trovato più intuitivamente sensato di un seme casuale. Ecco un codice di esempio per provarlo.
Ks=30
mean_acc=np.zeros((Ks-1))
std_acc=np.zeros((Ks-1))
ConfustionMx=[];
for n in range(1,Ks):
#Train Model and Predict
kNN_model = KNeighborsClassifier(n_neighbors=n).fit(X_train,y_train)
yhat = kNN_model.predict(X_test)
mean_acc[n-1]=np.mean(yhat==y_test);
std_acc[n-1]=np.std(yhat==y_test)/np.sqrt(yhat.shape[0])
plt.plot(range(1,Ks),mean_acc,'g')
plt.fill_between(range(1,Ks),mean_acc - 1 * std_acc,mean_acc + 1 * std_acc, alpha=0.10)
plt.legend(('Accuracy ', '+/- 3xstd'))
plt.ylabel('Accuracy ')
plt.xlabel('Number of Nabors (K)')
plt.tight_layout()
plt.show()
print( "The best accuracy was with", mean_acc.max(), "with k=", mean_acc.argmax()+1)