在MATLAB / Octave中对字符串值单元格数组进行矢量化设置操作

时间:2013-07-03 20:06:48

标签: matlab set octave vectorization

我有一个大型数据集X,其中包含调查受访者的人口统计信息。这些数据在很大程度上是分类的,因此X中的每一行都包含一系列字符串值的特征,例如性别,种族,兴趣等等。 X的每列都是单个响应类别。我已将此数据集加载到MATLAB / Octave中的大单元数组中(在两者上进行测试)。我想测量每个样本和数据集中每个其他样本之间的Jaccard距离。基本上我想做的是:

dist = zeros(size(X,1));    % Initialize my distance matrix
for ii = 1:size(X,1)
    for jj = ii:size(X,1)   % Only need the upper triangle since dist is symmetric
        % Find the Jaccard distance between the ii-th and jj-th respondent
        dist(ii,jj) = 1 - numel(intersect(X(ii,:), X(jj,:))) / numel(union(X(ii,:), X(jj,:)));
    end
end

除了显然我想要对代码进行矢量化。我尝试使用cellfunbsxfun进行矢量化,但是当我执行类似的操作时:

res = cellfun('intersect', X, X, 'UniformOutput', false);

我得到一个与X大小相同的单元格数组,其中(i,j)元素相当于intersect(X(i,j), X(i,j));基本上是(i-j)-cell中的唯一字符。这对我没有帮助。当我尝试:

res = bsxfun('intersect', X, X);

我得到一个长单元格数组,其中包含(我认为)X中任何单元格所具有的所有唯一值。这对我也没有帮助。

我想要一个解决方案,使我能够在本讨论开始时对代码进行矢量化。如果更容易这样做,那么找到X子集的代码与X中任意一行的最小(或最大)Jaccard距离就是我所需要的。

提前致谢!

编辑:将循环代码更改为仅计算dist的上三角形。仍然需要太长时间,而且它是非矢量化的这一事实让我在哲学层面上感到困惑。

编辑:键入X给出的X(1,:)的第一个元素是:

ans =
{
  [1,1] = Non - U.S. Citizen
  [1,2] = Denied
  [1,3] = M
  [1,4] = CHINA
  [1,5] = Full Time
  [1,6] = D-Asian American or Pacific Islander
  [1,7] = 
  [1,8] = 
  [1,9] = MSME
  [1,10] = 
}

这只是在我等待实际调查结果时测试开发算法的数据,但调查结果会有类似的形式。

编辑:来自X的更多数据,但是以CSV格式显示,如下所示:

Non - U.S. Citizen,Denied,M,INDIA,Full Time,E-Other,,,MSME,
Non - U.S. Citizen,Denied,F,INDIA,Full Time,D-Asian American or Pacific Islander,,,MSME,DESIGN
Non - U.S. Citizen,Denied,M,INDIA,Full Time,E-Other,,,MS,
Non - U.S. Citizen,Denied,M,IRAN,Full Time,B-Caucasian American Non-Hispanic,,,PhD,NANO
Non - U.S. Citizen,Left Without Degree,M,JORDAN,Full Time,E-Other,,,,
Non - U.S. Citizen,Denied,F,IRAN,Full Time,E-Other,,,PhD,BIOENG
,Not Attending,M,,Full Time,,,,PhD,
Non - U.S. Citizen,Not Attending,F,IRAN,Full Time,I-International Student,,,PhD,
Non - U.S. Citizen,Denied,M,BANGLADESH,Full Time,E-Other,,,PhD,NANO
Non - U.S. Citizen,Denied,M,BANGLADESH,Full Time,E-Other,,,MS,

1 个答案:

答案 0 :(得分:0)

这可能是一种解决方法,我将在一行数据上进行说明:

a={'Non - U.S. Citizen','Denied','M','INDIA','Full Time','E-Other','','','MSME',''}

对每个单元格元素求和,这会将字符串转换为双精度值并求和它们的值。假设非唯一总和结果的可能性很小(如果没有你可以实现的技巧,但我怀疑它实际上会发生),它将起作用:

b=cellfun(@sum,a,'un',0)

现在每个单元格元素只有一个数字,您可以使用cell2mat来获取矩阵和\或pdist等...