function teht4(D)

%% Datan alustus.

Y = D(:,2);
X = D(:,1);

r = randperm(length(Y));

% Lisätään hiukan featureja
X_train = [X.^0 X X.^2];
Y_train = Y;


% Poimitaan datan kokotiedot.
[numSamples, numFeatures] = size(X_train);

% Ristiinvalidoinnin osat. 6 osiota.
S = ceil(6 .* rand(numSamples, 1));


%% Harjanneregressio

% regularisointiparametri
delta = linspace(0, 5, 1000);

% varataan w vektoreille tilaa
w = zeros(length(delta), numFeatures);

predictedSquareError = zeros(length(delta), 1);

% For each delta
for i = 1:length(delta)
	
	
    % For each S
	for j = 1:6
		
        % {S \cut S_k} treenaukseen
		S_X_train = X_train(S ~= j, :);
		S_Y_train = Y_train(S ~= j);
		
        % {S_k} testaukseen
		S_X_test  = X_train(S == j, :);
		S_Y_test  = Y_train(S == j);
        
		% hae w joka minimoi L2 virheen.
		S_w = (S_X_train' * S_X_train + delta(i) * eye(numFeatures)) \ (S_X_train' * S_Y_train);
		
        % Summataan virheiden keskiarvot
		predictedSquareError(i) = predictedSquareError(i) + mean( (S_Y_test - S_X_test * S_w).^2 ) / 6;
    end
    
	% hae koko datalle w joka minimoi L2 virheen.
    w(i, :) = ((X_train' * X_train + delta(i) * eye(numFeatures)) \ (X_train' * Y_train))';
end

% Valitse virheen minimoiva delta.
[min_error_regression, index_regression] = min(predictedSquareError);

disp('harjanne -regression virhe-estimaatti: ')
disp(min_error_regression)
disp('saavutettiin arvolla delta = ')
disp(delta(index_regression))



%% knn-regression

% For each k value
error = zeros(10, 1);
for k = 1:10
    errors(k) = 0;
    total_tests = 0;
    
    % For each S
	for j = 1:6
		
        % {S \cut S_k} treenaukseen
		S_X_train = X(S ~= j, :);
		S_Y_train = Y_train(S ~= j);
		
        % {S_k} testaukseen
		S_X_test  = X(S == j, :);
		S_Y_test  = Y_train(S == j);
        
        for i=1:length(S_X_test)
            [distances, indices] = sort( abs(S_X_train - S_X_test(i)) , 'ascend');
            y_values = S_Y_train(indices(1:k));
            y_value = mean(y_values);
            
            error(k) = error(k) + (y_value - S_Y_test(i))^2;
            total_tests = total_tests + 1;
        end
    end
    
    error(k) = error(k) / total_tests;
end

[min_knn_error, index] = min(error);
disp('knn virhe-estimaatti: ')
disp(min_knn_error)
disp('saavutettiin arvolla k = ')
disp(index)
