如何在MATLAB中从缺少值的数据集中识别最佳子样本

时间:2016-02-01 01:01:29

标签: matlab

我想确定大数据集的最大可能连续子样本。我的数据集包含大约15,000个金融时间序列,最长可达360个周期。我已经将数据导入到MATLAB中,作为一个360乘15,000的数值矩阵。

enter image description here

由于部分财务数据在整个期间无法使用,因此该矩阵包含大量NaN。在图示中,NaN条目以深蓝色显示,非NaN条目以浅蓝色显示。正是这些浅蓝色的非NaN条目,我希望理想地组合成一个最佳的子样本。

我想找到矩阵中包含的最大可能的连续数据块,同时确保我的矩阵包含足够数量的句点。

在第一步中,我想按照每列中非NaN条目的数量从左到右依次排序我的矩阵,也就是说,我想按输入{{1 }}

在第二步中,我想找到我的数据矩阵的子数组,它沿着第一维至少有72个条目,否则尽可能大,用条目总数来衡量。

实施此方法的最佳方法是什么?

3 个答案:

答案 0 :(得分:5)

一个很大的警告(根据具体情况可能适用也可能不适用)

正如奥列格提到的那样,当一个金融时间序列中缺少一个观察时,它常常因为理由而缺失:例如。该实体破产,该实体被摘牌,或该工具没有交易(即非流动性)。构建没有NaN的样本可能相当于构建一个没有发生这些事件的样本!

例如,如果这是对冲基金的回报数据,选择没有NaN的样本将排除爆炸和停止交易的资金。剔除内爆资金会使预期回报的估计偏向上升,并且估计方差或协方差向下。

采用NaN最少的时间序列选择一个样本期也会排除像2008年金融危机这样的时期,这可能是也可能没有意义。排除2008年可能导致低估了乱七八糟的事情(尽管包括它可能会导致高估某些罕见事件的可能性)。

有些事要做:

  1. 尽可能选择一个样本期,但要注意这些限制。
  2. 尽力处理生存偏见:例如。如果NaNs代表退市事件,请尝试获得某种退市回报。
  3. 你几乎肯定会有一个不平衡的面板,缺少观察结果,你的算法必须处理它。
  4. 另一个一般的财务/面板数据点,在某个时间点选择一个样本然后跟随它进入未来是完全可以的。但是,根据样本期间或之后发生的事情选择样本可能会产生令人难以置信的误导。
  5. 执行您所问的代码:

    这应该做你所要求的并且非常快。如果缺少观察是不是随机的并且与您关心的内容正交,请注意这些问题。

    输入是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),则可以更简单地完成此操作。相同。

我不知道的是,如果您想丢弃时间序列中与最大值不对应的所有时段,请将所有这些链作为单独的时间序列,...

如果必须更具体,请随意删除评论。