clear all;
close all;
clc;

% Nacteni dat
load fisheriris
X = meas;    % 4 sloupce odpovidajici 4 priznakum (velikost matice 150x4)
y = species; % klasifikacni tridy (velikost matice 150x1)

% Nazvy priznaku
featureNames = {'Sepal Length', 'Sepal Width', 'Petal Length', 'Petal Width'};

% Vykresleni hodnot priznaku pro jednotlive klasifikacni tridy
figure;
for i = 1:4
    subplot(2,2,i);
    boxplot(X(:,i), y);
    title(featureNames{i});
    xlabel('Trida');
    ylabel('Hodnota');
    grid on;
end

% Krizova validace (Cross validace)
k = 10; % pocet foldu
cv = cvpartition(y, 'KFold', k);

% Inicializace metrik
accuracy = zeros(k, 1);

% Smycka pres CV foldy
for i = 1:k
    
    % Indexy pro trenovaci a testovaci mnozinu.
    % Jeden z moznych zpusobu - indexy lze vytvaret i jinak
    trainIdx = training(cv, i);
    testIdx = test(cv, i);
    
    % Rozdeleni dat na trenovaci a testovaci cast dle indexu trainIdx a testIdx
    X_train = X(trainIdx, :);
    y_train = y(trainIdx);
    X_test = X(testIdx, :);
    y_test = y(testIdx);
    
    % Normalizace priznaku: z-score podle trenovacich dat
    mu = mean(X_train);
    sigma = std(X_train);
    sigma(sigma == 0) = 1;  % prevence deleni nulou
    X_train_norm = (X_train - mu) ./ sigma;
    X_test_norm = (X_test - mu) ./ sigma;  % normalizace testovacich dat stejnymi parametry
    
    % Natrenovani klasifikatoru (v tomto pripade 3-NN)
    model = fitcknn(X_train_norm, y_train, 'NumNeighbors', 3);
    
    % Otestovani na testovaci casti dat (predikce klasifikacnich trid)
    y_pred = predict(model, X_test_norm);
    
    % Vypocet presnosti klasifikace
    accuracy(i) = sum(strcmp(y_pred, y_test)) / length(y_test);
end

% Presnosti klasifikace pro jednotlive foldy
figure;
bar(1:k, 100*accuracy);
xlabel('Fold');
ylabel('Presnost klasifikace (%)');
title('Presnosti klasifikace pro jednotlive foldy (3-NN)');
ylim([0 100]);
grid on;

% Celkova prumerna presnost klasifikace
avg_accuracy = mean(accuracy);
fprintf('Prumerna presnost klasifikace pri 10-fold cross-validaci: %.2f%%\n', avg_accuracy * 100);