Skip to content

Instantly share code, notes, and snippets.

@abrahamhurtado
Last active February 23, 2019 08:38
Show Gist options
  • Select an option

  • Save abrahamhurtado/d65d3dad634937db6b94fbfa790d724c to your computer and use it in GitHub Desktop.

Select an option

Save abrahamhurtado/d65d3dad634937db6b94fbfa790d724c to your computer and use it in GitHub Desktop.
Gestos
function Centroid = createEmptyCentroids(K, attributes)
Centroid = zeros(K, attributes);
end
% Cargamos el dataset con las siguientes variables
% SAMPLES_FIXED_Kmeans_Deltas que son los datos
% SAMPLES_FIXED_Kmeans_Labels contiene la clase asignada a cada regisro
load('IA_Kmeans_Muestras.mat');
% renombramos SAMPLES_FIXED_Kmeans_Deltas como dataset
dataset = SAMPLES_FIXED_Kmeans_Deltas;
% calculamos el número de clases en el dataset
num_clases = size(unique(SAMPLES_FIXED_Kmeans_Labels), 1);
% calculamos el total de atributos
num_atributos = size(dataset, 2);
% calculamos el total de datos
num_datos = length(dataset);
% renombramos SAMPLES_FIXED_Kmeans_Labels como RealClasses
RealClasses = SAMPLES_FIXED_Kmeans_Labels;
% creamos dos centroides vacíos
centroids = createEmptyCentroids(num_clases, num_atributos);
centroids2 = createEmptyCentroids(num_clases, num_atributos);
% populamos el primer centroide con datos aleatorios
% centroids = populateCentroid(centroids, dataset, num_clases, RealClasses);
centroids = notSoRandomCentroid(centroids, dataset, num_clases);
% creamos un vector donde se almacenarán las distancias
% de cada registro con respecto a cada uno de los centroides
distancias = zeros(num_datos, num_clases);
% creamos un vector vacío donde se almacenarán las predicciones
% del algoritmo para cada registro
predictions = zeros(num_datos, 1);
% mientras los centroides sean completamente diferentes (no converjan), se
% ejecutará el algoritmo
iteraciones = 0;
while isequal(centroids, centroids2) == false
iteraciones = iteraciones + 1;
% obtenemos la distancia ecludiana para cada muestra con cada uno de
% los centroides
for m = 1:num_datos
for n = 1:num_clases
distancias(m,n) = sqrt(sum((dataset(m,:) - centroids(n,:)).^2));
end
end
% se obtiene el centroide más cercano a la muestra para obtener la
% clase asignada y se guarda en el vector predictions
for i = 1:length(distancias)
clase = find(distancias(i,:) == min(distancias(i,:)));
predictions(i) = clase;
end
% obtenemos las muestras asignadas a cada cluster y promediamos los
% atributos de cada una para llenar los nuevos centroides
for j = 1:num_clases
instancesAssignedToClusterJ = dataset((predictions == j),:);
for k = 1:size(instancesAssignedToClusterJ, 2)
centroids2(j,k) = sum(instancesAssignedToClusterJ(:,k)) / length(instancesAssignedToClusterJ);
end
end
if isequal(centroids, centroids2) == false
centroids = centroids2;
centroids2 = createEmptyCentroids(num_clases, num_atributos);
else
break
end
end
disp(sprintf('Se hicieron %f iteraciones', iteraciones));
disp(100* sum(predictions == RealClasses)/length(dataset))
disp(100* sum((predictions == 1) == (RealClasses == 1))/length(dataset))
disp(100* sum((predictions == 2) == (RealClasses == 2))/length(dataset))
disp(100* sum((predictions == 3) == (RealClasses == 3))/length(dataset))
disp(100* sum((predictions == 4) == (RealClasses == 4))/length(dataset))
disp(100* sum((predictions == 5) == (RealClasses == 5))/length(dataset))
disp(100* sum((predictions == 6) == (RealClasses == 6))/length(dataset))
disp(100* sum((predictions == 7) == (RealClasses == 7))/length(dataset))
disp(100* sum((predictions == 8) == (RealClasses == 8))/length(dataset))
% Cargamos el dataset proporcionado por la profesora
load('IA_Kmeans_Muestras.mat');
% Por comodidad, renombramos las variables SAMPLES_FIXED_Kmeans_Deltas y
% SAMPLES_FIXED_Kmeans_Labels a dataset y dataset_classes, respectivamente
dataset = SAMPLES_FIXED_Kmeans_Deltas;
dataset_classes = SAMPLES_FIXED_Kmeans_Labels;
% Calculamos el total de clases a partir de dataset_classes, el resultado
% debe ser, como ya sabíamos, 8.
K = length(unique(dataset_classes));
% Filtramos elementos de dataset, según la clase que le corresponde en
% dataset_classes. Esto nos ayudará en el cálculo de porcentajes de
% aciertos más adelantes.
k1 = dataset((dataset_classes == 1), :);
k2 = dataset((dataset_classes == 2), :);
k3 = dataset((dataset_classes == 3), :);
k4 = dataset((dataset_classes == 4), :);
k5 = dataset((dataset_classes == 5), :);
k6 = dataset((dataset_classes == 6), :);
k7 = dataset((dataset_classes == 7), :);
k8 = dataset((dataset_classes == 8), :);
% Por conveniencia, declaramos total_datos para contener el total de
% conjuntos (633) y total_atributos para contener el total de atributos
% (18)
total_datos = length(dataset);
total_atributos = size(dataset, 2);
% Declaramos dos matrices de dimensiones K x total_atributos, es decir, 8 *
% 18, que se llenará con los centroides para cada cluster.
centroids = zeros(K, total_atributos);
centroids2 = zeros(K, total_atributos);
% Declaramos una matriz de total_datos x 1, 633 x 1, donde cada casilla se
% llenará con la asignación de clase del algoritmo para cada registro del
% dataset.
predictions = zeros(total_datos, 1);
% Se declara la variable iteraciones, para llevar el conteo de ciclos de
% ejecución del algoritmo hasta la convergencia.
iteraciones = 0;
% Populamos centroids usando los índices que nos proporcionó la profesora.
centroids = notSoRandomCentroid(centroids, dataset, K)
% El algoritmo se ejecutará hasta que centroids y centroids2 sean iguales,
% es decir, que converjan.
while isequal(centroids, centroids2) == false
iteraciones = iteraciones + 1;
% Recorremos por el total de datos, en este caso 633
for i = 1:total_datos
% Obtenemos la distancia euclidiana del registro i del dataset
% respecto a todos los centroides.
% bsxfun(@minus, centroides, dataset(i, :)) nos permite a cada
% renglón de la matriz de centroids, restarle el registro ubicado
% en dataset(i), una operación que no se puede ejecutar
% naturalmente y que hubiera requerido otro ciclo for.
% sum(@minus, centroides, dataset(i, :))', se hace la suma de la
% matriz transpuesta porque las sumas de matrices se hacen columna
% por columna, como está acomodada originalmente la matriz
% centroids 8 x 18, la suma resultaría en una matriz horizontal de
% 1 x 18, nosotros queremos 1 x 8.
[~, claseAsignada] = min(sum(bsxfun(@minus, centroids, dataset(i,:))'.^2));
predictions(i,:) = claseAsignada;
end
% centroids2 ahora almacena centroids
centroids2 = centroids;
% Recorremos por el total de clases que tenemos, en este caso 8
for j = 1:K
% Filtramos los registros de dataset según las predicciones para la
% clase j.
registrosAsignadosEnJ = dataset(predictions == j, :);
% El nuevo centroids es la media de las predicciones.
centroids(j,:) = mean(registrosAsignadosEnJ);
end
end
% Se calcula el porcentaje de aciertos para cada clase.
aciertos_k1 = (sum(predictions(dataset_classes == 1) == 1) / length(k1)) * 100;
aciertos_k2 = (sum(predictions(dataset_classes == 2) == 2) / length(k2)) * 100;
aciertos_k3 = (sum(predictions(dataset_classes == 3) == 3) / length(k3)) * 100;
aciertos_k4 = (sum(predictions(dataset_classes == 4) == 4) / length(k4)) * 100;
aciertos_k5 = (sum(predictions(dataset_classes == 5) == 5) / length(k5)) * 100;
aciertos_k6 = (sum(predictions(dataset_classes == 6) == 6) / length(k6)) * 100;
aciertos_k7 = (sum(predictions(dataset_classes == 7) == 7) / length(k7)) * 100;
aciertos_k8 = (sum(predictions(dataset_classes == 8) == 8) / length(k8)) * 100;
% Se calcula el porcentaje de aciertos general.
aciertos = (sum(predictions == dataset_classes)/total_datos) * 100;
fprintf('Se hicieron %f iteraciones', iteraciones);
disp('')
disp(aciertos_k1);
disp(aciertos_k2);
disp(aciertos_k3);
disp(aciertos_k4);
disp(aciertos_k5);
disp(aciertos_k6);
disp(aciertos_k7);
disp(aciertos_k8);
disp(aciertos);
% Esta funcion genera los centroides tomando en cuenta los indices provistos por la profesora
function Centroid = notSoRandomCentroid(Centroid, dataset, K)
rows = [1, 234, 388, 481, 495, 501, 577, 587];
for c=1:K
% El centroide c es igual al registro ubicado la posicion rows(c) del dataset
Centroid(c, :) = dataset(rows(c),:);
end
end
function Centroid = populateCentroid(Centroid, dataSet, K, classes)
% recorremos rengl�n por rengl�n
for i = 1:K
x = dataSet(classes == i, :);
% recorremos columna por columna
for j = 1:(size(dataSet, 2))
% obtenemos los valores m�nmos y m�ximos para cada columna
minimo = min(x(:,j));
maximo = max(x(:,j));
% asignamos a la casilla J del centroide I un valor random
% entre el m�nimo y el m�ximo de cada columna
Centroid(i,j) = (rand() * (maximo - minimo)) + minimo;
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment