Respuestas:
Un enfoque que produce resultados más consistentes es K-means ++ . Este enfoque reconoce que probablemente hay una mejor opción de ubicaciones de centroides iniciales que la asignación aleatoria simple. Específicamente, K-means tiende a funcionar mejor cuando los centroides se siembran de tal manera que no los agrupan en el espacio.
En resumen, el método es el siguiente:
Nota: debe actualizarse a medida que se agreguen más centroides. Debe establecerse como la distancia entre un punto de datos y el centroide más cercano.
También puede estar interesado en leer este documento que propone el método y describe su rendimiento general esperado.
Puedo estar malentendiendo su pregunta, pero generalmente k-means elige sus centroides al azar para usted dependiendo de la cantidad de grupos que establezca (es decir, k). Elegir el número para k tiende a ser un ejercicio subjetivo. Un buen lugar para comenzar es un diagrama de Elbow / Scree que se puede encontrar aquí:
http://en.wikipedia.org/wiki/Determining_the_number_of_clusters_in_a_data_set#The_Elbow_Method
El enfoque habitual para este problema es volver a ejecutar su algoritmo K-means varias veces, con diferentes inicializaciones aleatorias de los centroides, y mantener la mejor solución. Puede hacerlo evaluando los resultados en sus datos de entrenamiento o mediante validación cruzada.
Hay muchas otras formas de inicializar los centroides, pero ninguno de ellos tendrá el mejor rendimiento para cada problema. Puede evaluar estos enfoques junto con una inicialización aleatoria para su problema particular.
Estoy de acuerdo con la trama Elbow / Scree. Lo encontré más intuitivamente sensible que una semilla aleatoria. Aquí hay un código de ejemplo para probarlo.
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)