我想确定大数据集的最大可能连续子样本。我的数据集包含大约15,000个金融时间序列,最长可达360个周期。我已经将数据导入到MATLAB中,作为一个360乘15,000的数值矩阵。
由于部分财务数据在整个期间无法使用,因此该矩阵包含大量NaN。在图示中,NaN条目以深蓝色显示,非NaN条目以浅蓝色显示。正是这些浅蓝色的非NaN条目,我希望理想地组合成一个最佳的子样本。
我想找到矩阵中包含的最大可能的连续数据块,同时确保我的矩阵包含足够数量的句点。
在第一步中,我想按照每列中非NaN条目的数量从左到右依次排序我的矩阵,也就是说,我想按输入{{1 }}
在第二步中,我想找到我的数据矩阵的子数组,它沿着第一维至少有72个条目,否则尽可能大,用条目总数来衡量。
实施此方法的最佳方法是什么?
答案 0 :(得分:5)
正如奥列格提到的那样,当一个金融时间序列中缺少一个观察时,它常常因为理由而缺失:例如。该实体破产,该实体被摘牌,或该工具没有交易(即非流动性)。构建没有NaN的样本可能相当于构建一个没有发生这些事件的样本!
例如,如果这是对冲基金的回报数据,选择没有NaN的样本将排除爆炸和停止交易的资金。剔除内爆资金会使预期回报的估计偏向上升,并且估计方差或协方差向下。
采用NaN最少的时间序列选择一个样本期也会排除像2008年金融危机这样的时期,这可能是也可能没有意义。排除2008年可能导致低估了乱七八糟的事情(尽管包括它可能会导致高估某些罕见事件的可能性)。
有些事要做:
这应该做你所要求的并且非常快。如果缺少观察是不是随机的并且与您关心的内容正交,请注意这些问题。
输入是T×n大小的矩阵X:
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);
答案 1 :(得分:3)
这是一个想法,
假设你可以重新安排系列,计算距离(你决定了指标,但是如果看的是nan而不是nan,那么Hamming就可以了)。
现在对系列进行分层聚类,并使用树形图重新排列它们 或http://www.mathworks.com/help/bioinfo/examples/working-with-the-clustergram-function.html
在开始之前,你应该修剪任何没有最小数量的非纳米值的系列。
答案 2 :(得分:2)
首先,我对金融数学知之甚少。我理解你想要为每个时间序列找到最长的连续非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),则可以更简单地完成此操作。相同。
我不知道的是,如果您想丢弃时间序列中与最大值不对应的所有时段,请将所有这些链作为单独的时间序列,...
如果必须更具体,请随意删除评论。