function [Arbol correcto2] = CancerDiagnosis()
% Wisconsin Diagnostic Breast Cancer (WDBC)
% Creamos un clasificador de celulas cancerosas basandonos en las
% caracteristicas extraidas de imagenes de las muestras. El significado de
% cada una esta explicado a continuacion.
%
%
%
% 1) ID number
% 2) Diagnosis (M = malignant, B = benign)
% 3-32)
%
% Ten real-valued features are computed for each cell nucleus:
%
% a) radius (mean of distances from center to points on the perimeter)
% b) texture (standard deviation of gray-scale values)
% c) perimeter
% d) area
% e) smoothness (local variation in radius lengths)
% f) compactness (perimeter^2 / area - 1.0)
% g) concavity (severity of concave portions of the contour)
% h) concave points (number of concave portions of the contour)
% i) symmetry
% j) fractal dimension ("coastline approximation" - 1)
%
%
%
%
%
close all
%leemos el archivo y lo guardamos en una matriz
matrix = dlmread2('wdbc.data', ',');
x = [];
y = [];
pos=[];
neg=[];
Arbolaux=zeros(30,1)';
percent= [1:20:size(matrix,1)];
correcto2=0;
for i= percent
c = cvpartition(size(matrix,1),'holdout',i); %%Seleccionaremos el conjunto de training y el de test !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
idtest=test(c);
idtrain = training(c);
testmat= matrix(idtest,:); % Conjunto de muestras para test
trainmat=matrix(idtrain,:); %Conjunto de muestras para training
%Identificadores de clases
cancertest= char(testmat(:,2));
cancertrain = char(trainmat(:,2));
%Identificadores de casos
idtrain=str2double(trainmat(:,1));
idtest=str2double(testmat(:,1));
trainmat = [single(str2double(trainmat(:,3:end)))] ; % Nos quedamos con las caracteristicas
testmat=[single(str2double(testmat(:,3:end)))];
Arbol={};
taux={};
Arbol =arbol_training(trainmat,Arbol,cancertrain,taux);
x = [x length(cancertrain)];
display('--------------------------------------------------------------')
[Correcto falso_pos falso_neg]= Validacion(testmat,Arbol,cancertest,idtest);
display('--------------------------------------------------------------')
y = [y Correcto];
pos=[pos falso_pos];
neg=[neg falso_neg];
if(Correcto > correcto2 && Correcto~=100)
Arbolaux=Arbol;
correcto2=Correcto;
end
end % para cada columna, calculamos su entropia y la guardamos en el vector
hold on;
axis([1 size(matrix,1)+10 0 101])
xlabel('Tamany conjunt aprenentatge')
ylabel('Percentatge classificacio correcta')
plot(x,y,'b');
plot(x,pos,'--r');
plot(x,neg,'--k');
legend('Aprenentatge','Falsos positius','Falsos Negatius')
hold off;
Arbol=Arbolaux;
end % para cada columna, calculamos su entropia y la guardamos en el vector
% vGanancia
function [I valor]= Mayor_ganancia(trainmat,cancer)
entropia = calcular_entropia(cancer) ; % calculamos la entropia del sistema
vGanancia = [];
vc=[];
for i=1:size(trainmat,2)
[ganancia c] = calcularGanancia(trainmat,cancer,entropia,i);
vGanancia = [vGanancia ganancia];
vc = [vc c];
end
[maxim I]=max(vGanancia);
valor =vc(I);
end
function [entropia] = calcular_entropia(cancer)
% Contar palabras, solo que aqui contamos las veces que
% aparece M o B y luego aplicamos la formula para calcular la entropia del
% sistema
pos=length(find(cancer =='B'));
neg=length(cancer)-pos;
tamany=length(cancer);
entropia = -1*(pos/tamany)*log2(pos/tamany) - (neg/tamany)* ...
log2(neg/tamany);
end
function [Arbol taux] = arbol_training(trainmat,Arbol,cancer,taux)
% Funcion recursiva que nos construye el arbol de decision. Para cada paso mirara
% cual es el atributo que aporta mayor ganancia, y dentro de este agrupara
% los valores continuos para definir n conjuntos
%
% La siguiente iteracion estara formada por las muestras que tienen el atributo con mayor
% ganancia de forma que el conjuto se decrementa en cada paso.
%
% trainmat: Matriz de training con las caracteristicas
% Arbol: Arbol final que retornara la funcion. Inicialmente se le pasa vacio {}
% cancer: Vector que nos indica si es o no cancerosa cada muestra de nuestro conjunto. Tambien se
% va actualizando para mantener solo los casos que nos interesan
% taux: Arbol auxiliar que nos permitira concatenar mas adelante todo el arbol de decision.
%
[I valor]=Mayor_ganancia(trainmat,cancer); %Buscamos la columna (caracteristica) que aporta mayor ganancia
% S(1);
% S(2);
taux2=taux;
for rama=1:2 %Repetiremos para mirar las dos vias de cada nodo (mayores o menores)
taux=taux2;
if rama ==1 %Miraremos los casos mayores que el valor frontera
%
% ---------------------- Buscamos los mayores y los metemos en el arbol -----------------------
filesMayor=find(trainmat(:,I)>=valor);
taux{length(taux)+1}=[[I,valor],1]; %El nodo contendra la columna, el valor, y un numero que indica que se trata de la rama mayor que el valor
newtrain=trainmat(filesMayor,:); %Actualizamos nuestro conjunto
newcancer=cancer(filesMayor); %Actualizamos el conjunto de canceroso
% ---------------------- Buscamos los menores y los metemos en el arbol -----------------------
else
filesMenor=find(trainmat(:,I)<valor);
taux{length(taux)+1}=[[I,valor],-1]; %El nodo contendra la columna, el valor, y un numero que indica que se trata de la rama menor que el valor
newtrain=trainmat(filesMenor,:); %Actualizamos nuestro conjunto
newcancer=cancer(filesMenor); %Actualizamos el conjunto de canceroso
end
final=unique(newcancer); % Miramos ahora si todos los casos son positivos
% o todos negativos, si no es asi,
% continuaremos con la recursividad
if (length(final)==1)
taux{length(taux)+1}=final; %Si todos son positivos o negativos ponemos el valor
% en el arbol para que se sepa que
% se ha terminado esa rama
Arbol{length(Arbol)+1}=taux;
else
Arbol=arbol_training(newtrain,Arbol,newcancer,taux);
end
end
end
function [be]=Evaluar(test,Arbol)
%Funcion que evalua una muestra del conjunto de Test. Para cada
%caracteristica del Arbol aprendido, mirara si podemos hacer un matching
%con los nodos. Si no es posible, retornaremos Invalido.
Correcto=0;
for i=1:length(Arbol) %Recorremos el Arbol
valido=1;
for j=1:length(Arbol{i})-1 %Recorremos la rama
if (Arbol{i}{j}(3)==1) % Si el valor nos indica que es la rama de los mayores
if(test(Arbol{i}{j}(1)) < Arbol{i}{j}(2))
valido=0; %Miraremos si podemos continuar evaluando en esta rama, esto es,
break % que los valores se encuentren dentro del conjunto que representa esta via.
end
else
if (test(Arbol{i}{j}(1)) > Arbol{i}{j}(2))