Как определить оптимальную подвыборку из набора данных с отсутствующими значениями в MATLAB
Я хотел бы определить максимально возможную непрерывную подвыборку большого набора данных. Мой набор данных состоит из примерно 15 000 финансовых временных рядов длиной до 360 периодов. Я импортировал данные в MATLAB в виде числовой матрицы 360 на 15 000.
![введите описание изображения здесь]()
Эта матрица содержит много NaNs из-за того, что некоторые финансовые данные не доступны за весь период. На иллюстрации входы NaN отображаются синим цветом, а записи, отличные от NaN, отображаются синим цветом. Именно эти светло-голубые записи, отличные от NaN, я хотел бы идеально объединить в оптимальную подвыборку.
Я хотел бы найти максимально возможный непрерывный блок данных, содержащийся в моей матрице, при этом гарантируя, что моя матрица содержит достаточное количество периодов.
На первом этапе я хотел бы отсортировать свою матрицу слева направо в порядке убывания по количеству записей, отличных от NaN, в каждом столбце, то есть я хотел бы отсортировать по вектору, полученному путем ввода sum(~isnan(data),1)
.
На втором этапе я хотел бы найти подматрицу моей матрицы данных, которая по крайней мере 72 записи по первому измерению, и в противном случае максимально возможная, измеряемая общим количеством записей.
Каков наилучший способ реализовать это?
Ответы
Ответ 1
Большое предупреждение (может или не может применяться в зависимости от контекста)
Как отметил Олег, когда в финансовом временном ряду отсутствует наблюдение, оно часто отсутствует по причине: например. предприятие обанкротилось, предприятие было исключено, или инструмент не торговал (т.е. неликвидным). Построение образца без NaN, скорее всего, эквивалентно построению образца, где ни одно из этих событий не происходит!
Например, если это данные возврата хедж-фондов, выбор образца без NaN исключает средства, которые взорвали бы и прекратили торговлю. Исключение вложенных средств приведет к смещению оценок ожидаемой доходности вверх и оценок дисперсии или ковариации вниз.
Выбор периода выборки с наименьшим временным рядом с помощью NaN также исключает периоды, такие как финансовый кризис 2008 года, который может иметь или не иметь смысла. Исключение 2008 года может привести к недооценке того, как могут быть получены вещи с высокой вероятностью (хотя в том числе это может привести к переоценке вероятности некоторых редких событий).
Некоторые вещи:
- Выберите период выборки как можно дольше, но помните об ограничениях.
- Приложите все усилия, чтобы справиться с уклоном от насилия: например. если NaN представляют события делистинга, попробуйте получить какой-то возврат к делистинга.
- У вас почти наверняка будет несбалансированная панель с отсутствующими наблюдениями, и ваш алгоритм должен будет с этим справиться.
- Еще одна общая информация о финансах/панели данных, выбор образца в некоторый момент времени t, а затем последующий за ней в будущем - это нормально. Но выбор образца, основанного на том, что происходит во время или после периода выборки, может быть невероятно ошибочным.
Код, который делает то, что вы просили:
Это должно делать то, что вы просили, и быть довольно быстрым. Помните о проблемах, хотя, если отсутствует наблюдение, не является случайным и ортогональным тому, что вам нужно.
Входы представляют собой матрицу размера X на n:
T = 360; % number of time periods (i.e. rows) in X
n = 15000; % number of time series (i.e. columns) in X
T_subsample = 72; % desired length of sample (i.e. rows of newX)
% number of possible starting points for series of length T_subsample
nancount_periods = T - T_subsample + 1;
nancount = zeros(n, nancount_periods, 'int32'); % will hold a count of NaNs
X_isnan = int32(isnan(X));
nancount(:,1) = sum(X_isnan(1:T_subsample, :))'; % 'initialize
% We need to obtain a count of nans in T_subsample sized window for each
% possible time period
j = 1;
for i=T_subsample + 1:T
% One pass: add new period in the window and subtract period no longer in the window
nancount(:,j+1) = nancount(:,j) + X_isnan(i,:)' - X_isnan(j,:)';
j = j + 1;
end
indicator = nancount==0; % indicator of whether starting_period, series
% has no NaNs
% number of nonan series of length T_subsample by starting period
max_subsample_size_by_starting_period = sum(indicator);
max_subsample_size = max(max_subsample_size_by_starting_period);
% find the best starting period
starting_period = find(max_subsample_size_by_starting_period==max_subsample_size, 1);
ending_period = starting_period + T_subsample - 1;
columns_mask = indicator(:,starting_period);
columns = find(columns_mask); %holds the column ids we are using
newX = X(starting_period:ending_period, columns_mask);
Ответ 2
Здесь идея,
Предполагая, что вы можете перестроить серию, вычислить расстояние (вы определяете метрику, но если смотреть на nan vs not is nan, Хэмминг в порядке).
Теперь иерархически сгруппируйте серию и перегруппируйте их, используя либо дендрограмму
или http://www.mathworks.com/help/bioinfo/examples/working-with-the-clustergram-function.html
Вероятно, вы должны сократить любую серию, у которой не должно быть минимального количества значений non nan до начала.
Ответ 3
Сначала у меня мало понимания финансовой математики. Я понял, что вы хотите найти самую длинную непрерывную цепочку значений, отличных от NaN, для каждого временного ряда. Временной ряд следует сортировать в зависимости от длины этой цепи и каждого временного ряда, не содержащего цепь выше порогового значения, отбрасываемой. Это можно сделать, используя
data = rand(360,15e3);
data(abs(data) <= 0.02) = NaN;
%% sort and chop data based on amount of consecutive non-NaN values
binary_data = ~isnan(data);
% find edges, denote their type and calculate the biggest chunk in each
% column
edges = [2*binary_data(1,:)-1; diff(binary_data, 1)];
chunk_size = diff(find(edges));
chunk_size(end+1) = numel(edges)-sum(chunk_size);
[row, ~, id] = find(edges);
num_row_elements = diff(find(row == 1));
num_row_elements(end+1) = numel(chunk_size) - sum(num_row_elements);
%a chunk of NaN has a -1 in id, a chunk of non-NaN a 1
chunks_per_row = mat2cell(chunk_size .* id,num_row_elements,1);
% sort by largest consecutive block of non-NaNs
max_size = cellfun(@max, chunks_per_row);
[max_size_sorted, idx] = sort(max_size, 'descend');
data_sorted = data(:,idx);
% remove all elements that only have block sizes smaller then some number
some_number = 20;
data_sort_chop = data_sorted(:,max_size_sorted >= some_number);
Обратите внимание, что это может быть сделано намного проще, если порядок периодов в пределах временного ряда не имеет значения, так как данные ([1 2 3], id) и данные ([3 1 2], id) являются идентичны.
То, что я не знаю, если вы хотите отбросить все периоды в пределах временного ряда, которые не соответствуют самому большому значению, получить все эти цепочки как индивидуальные временные ряды,...
Не стесняйтесь оставлять комментарий, если он должен быть более конкретным.