Forecasting a time series using yule-walker predicts to small value - matlab

I'm trying to forecast a value at step n+1 using yule-walker ar approach in matlab. The problem is that when plotting my predicted values they seem to small, like the predicted signal being a scaled version of the original.
To put my problem very simple I wrote this stripped down version that inputs a ramp (instead of a signal I measured) to be forecasted.
x = [-5 -4 -3 -2 -1 0 1 2 3 4 5];
a = aryule(x,9); % uses Yule-Walker modelling
pred = filter(-a(2:end),1,x);
disp(pred(end)); % the predicted value at time n+1
The result: 3.4415 While it should be something like 6 ... Any ideas on what I could be missing here?

Related

Matlab `quantile` doesn't interpolate between sample values on ECDF?

According to Matlab's help, quantile interpolates linearly between points on the empirical cumulative distribution function (ECDF). Importantly, the points interpolated between are the mid-points of the risers at each step. I'm finding the actual behaviour to be significantly different. Here is my example, the ECDF, and a line segment to show the interpolation:
y= [ 1 2 5 5 5 5 5 5 9 10 ]
ecdf(y)
grid on
set(get(gca,'Children'),'LineWidth',2)
hold on
% Line segment for interpolation
x2points=[2;5]; y2points=[0.15;0.5];
plot(x2points,y2points)
From the interpolation line segment, we would expect the quantile for F(x)=0.3 to be around x=3.3, but instead, it is x=5.
yInterior=0.3 % Value to get `x` for
xInterior=interp1(y2points,x2points,yInterior) % ans = 3.2857
xInterior=quantile(y,yInterior) % ans x=5
Is there another piece of documentation elsewhere that I'm missing which explains this difference?
Am I the only one seeing this?
I'm using Matlab 2015b.

plotting graphs with x-axis of desired length in matlab

I want to plot graphs in matlab, In hand, I had two raw data obtained from the market, say at year 0.25,0.5,0.75,1,2,3 and 4, corresponding values of product A are [0.9998,0.997,0.887,0.779,0.661,0.442,0.345] and B are [0.878,0.765,0.662,0.594,0.436,0.304,0.211] respectively. When I use
plot([0.25,0.5,0.75,1,2,3,4],[0.9998,0.997,0.887,0.779,0.661,0.442,0.345],'k+',[0.25,0.5,0.75,1,2,3,4],[0.878,0.765,0.662,0.594,0.436,0.304,0.211],'b*')
However, the graphs produced gives 4 lines. What should be done to fix the problem?
You need to create a graphic handler before modifying the XTick, Use the following
figure
ax = gca ;
plot([0.25,0.5,0.75,1,2,3,4],[0.9998,0.997,0.887,0.779,0.661,0.442,0.345],'k+',[0.25,0.5,0.75,1,2,3,4],[0.878,0.765,0.662,0.594,0.436,0.304,0.211],'b*')
ax.XTick = [0 0.25 0.5 0.75 1 2 3 4];

Is my implementation of confusion matrix correct? Or is something else at fault here?

I have trained a multi class svm classifier with 5 classes, i.e. svm(1)...svm(5).
I then used 5 images not used to during the training of these classifiers for testing.
These 5 images are then tested with their respective classifier. i.e. If 5 images were taken from class one they are tested against the same class.
predict = svmclassify(svm(i_t),test_features);
The predict produces a 5 by 1 vector showing the result.
-1
1
1
1
-1
I sum these and then insert it into a diagonal matrix.
Ideally it should be a diagonal matrix with 5 written diagonally when all images are correctly classified. But the result is very poor. I mean in some cases I am getting negative result. I just want to verify if this poor result is because my confusion matrix is not accurate or if I should use some other feature extractor.
Here is the code I wrote
svm_table = [];
for i_t = 1:numel(svm)
test_folder = [Path_training folders(i_t).name '\']; %select writer
feature_count = 1; %Initialize count for feature vector accumulation
for j_t = 6:10 %these 5 images that were not used for training
[img,map] = imread([test_folder imlist(j_t).name]);
test_img = imresize(img, [100 100]);
test_img = imcomplement(test_img);
%Features extracted here for each image.
%The feature vector for each image is a 1 x 16 vector.
test_features(feature_count,:) = Features_extracted;
%The feature vectors are accumulated in a single matrix. Each row is an image
feature_count = feature_count + 1; % increment the count
end
test_features(isnan(test_features)) = 0; %locate Nan and replace with 0
%I was getting NaN in some images, which was causing problems with svm, so just replaced with 0
predict = svmclassify(svm(i_t),test_features); %produce column vector of preicts
svm_table(end+1,end+1) = sum(predict); %sum them and add to matrix diagonally
end
this is what I am getting. Looks like a confusion matrix but is very poor result.
-1 0 0 0 0
0 -1 0 0 0
0 0 3 0 0
0 0 0 1 0
0 0 0 0 1
So I just want to know what is at fault here. My implementation of confusion matrix. My way of testing the svm or my selection of features.
I would like to add some issues:
You mention that: << These 5 images are then tested with their respective classifier. i.e. If 5 images were taken from class one they are tested against the same class. >>
You are never supposed to know the class (category) of test images. Of course, you need to know the test category labels for calculating various metrics such as accuracy, precision, confusion matrix etc. Apart from that, when you are using SVM to determine which class the example belongs to, you have to try all the SVMs.
There are two popular ways of training and testing multi-class SVMs, namely one-vs-all and one-vs-one approach. Read this answer and its corresponding question to understand them in detail.
I don't know if MATLAB SVM is capable of doing multiclass classification, but if you use LIBSVM then its uses one-vs-one approach. It will also do the testing for you correctly. However, if you want to design your own one-vs-one classifier, this is how you should proceed:
Say you have 5 classes, then train all possible combinations of pairs = 5c2 = 10 pairs ({1,2}, ..., {1,5},{2,1},...,{2,5},...,{5,4}). While testing, you have to apply all the 10 models and count all the votes to decide the final result. For example, we train models for 4 pairs (say), ({1 vs 2}, {1 vs 3}, {2 vs 1}, {2 vs 3}) and the outputs of 4 models are {1,1,0,1} respectively. That means, your 4 predicted classes are {1,1,1,2}. Therefore, the final class is 1.
Once you get all the predicted labels, then you can actually use the command confusionmat to get the confusion matrix. If you want to make your own, then make a 5x5 matrix of zeros. Add a 1 to the position (actual label, predicted label) i.e. if the actual class was 2 and you predicted it as 3, then add 1 at the position (2nd row, 3rd col) in the matrix.
Several issues that I can see...
1) What you're using is not really a multi class SVM. Your taking several different SVM models and applying them to the same test data (not really the same thing). You need to look at the documentation for svmtrain. When you use it you give it two kinds of data, the training data (parameter vectors for each training image) and the Group data (vector of classes for the images associated with the vectors..). What you get will be one SVM model which will decide between 1 of the options. (I usually use libsvm, so Im not that familiar with Matlabs SVM implementation, but that should be the gist of it)
2) Your confusion matrix is derived incorrectly (see: http://en.wikipedia.org/wiki/Confusion_matrix). Start by making a 5x5 zeros matrix to hold the confusion matrix. Loop through each of your test images and let the SVM model classify the image (it should pick 1 of the five possibilities). Add 1 at the proper position of the confusion matrix. So if the image should classify as a 3 and the SVM classifies it as a 4 you should add 1 to the 3,4 position...

Calculating standard deviation using data points and count vector in Matlab

I want to use Matlab to calculate the standard deviation of a population I have compiled.
The matlab function takes as input one large population vector and outputs the standard dev.
However, for optimisation purposes, instead of one large vector, I have a set of individual data points, and the number of times each point is used.
I could use a loop and create a huge population vector, but it's not ideal.
How could I go about this?
Very easy from the definition of standard deviation: just introduce weights to account for the number of repetitions of each data point:
data = [1 3 4 2 4]; %// data values
count = [4 5 4 5 8]; %// number of times for each value
mu = sum(data.*count)./(sum(count));
dev = sqrt(sum((data-mu).^2.*count)./(sum(count)-1)); %// or ./sum(count)

How can I do a linear best fit from one point to another in a matrix multiple times in order to detrend a series?

For this type of data I want to do an interpolation like fit from one maxima to a minima and so on, so I can look for superimposed high frequencies:
I have a matrix of values such as:
a=[ 3 7 10 3 1 5 10 5 3 2 4 8 10 7 4 3 4 2 1 4 5 7 10 8 7 6 6 4 3 2];
Now I want to choose the relative and maximum and minimum values such that
a=[ 3 0 10 0 1 0 10 0 0 2 0 0 10 0 0 0 0 0 1 0 0 0 10 0 0 0 0 0 0 2];
I essentially want to fit a straight line from a(1) to a(3) and then from a(3) to a(5) and so on, and then subtract the fit from the data.
I know there is a function "detrend" that uses a breakpoint method it denotes as "bp", and that is the closest thing I found resembling my goal.
If you know of a way MATLAB can do this I will greatly appreciate it, otherwise it seems like I have to write an m-file to do it.
I think what your question is asking for is interpolation between the local minima and local maxima of a time series (what you call the "relative minimum and maximum values".)
See this similar question and add some code that does a linear interpolation between the local minima and maxima.
interp1() will do this handily. There is no need for the input points or the output points to be evenly spaced.
>> x = sort(rand(1,10));
>> y = rand(1,10);
>> plot (x,y,'r.');
>> xx = 0:0.01:1;
>> yy = interp1(x,y,xx);
>> hold on;
>> plot (xx,yy,'b-')
What I think you really want to do is decompose the signal into components based on local time scale. (that is, where the frequencies change with time). Use the empirical mode decomposition. Wavelet methods might be an alternative, but the output of the EMD is very easy to interpret visually.
Incidentally, the plain FFT won't work if applied to the entire length of a signal that is time varying - the FFT assumes a stationary (non-varying) signal.
You need to apply the Short-Time Fourier Transform, which is the FFT applied over sliding windows of the data to get a picture of frequency over time. See the spectrogram() function.
>> plot (x,y)
>> x=0:0.001:1;
>> y = chirp(x);
>> plot (x,y);
>> figure;
>> spectrogram(y);
There are issues with time vs. frequency resolution of the short-time Fourier transform that limit its application when your sampling rate is low compared to the frequency of the data. It would would be unlikely to work well for the example data you posted a picture of.