【问题标题】:Matlab: Random list of stimuli from folders with different probabilitiesMatlab:来自具有不同概率的文件夹的随机刺激列表
【发布时间】:2014-09-23 02:16:14
【问题描述】:

我有几个文件夹,其中包含包含刺激的子文件夹,并且想要生成这些刺激的随机列表。根据刺激优先级,子文件夹称为“1”、“2”、“3”。此外,最终列表应该包含来自每个文件夹的一定百分比的刺激。

示例: 40% 来自“鲜花”, 20% 来自“仙人掌”, 10% 来自“树木”, 30% 来自“水果”。

Fruit 包含诸如“Berries”、“Citrus”、“Stone Fruit”之类的子文件夹,它们的概率相等。

所有文件夹都包含这些子文件夹 1、2、3。首先,应使用来自 1 的刺激。每个刺激应该只呈现一次。只有当 1 中没有更多刺激时,才能添加来自 2 的刺激,依此类推。 概率分布仅在开始时很重要。如果一个文件夹用完了刺激,那很好。 如何实现文件夹的概率/权重和子文件夹的优先级?

这里是我的文件夹结构示例:

Stimuli/Flowers/1
Stimuli/Flowers/2
Stimuli/Flowers/3
Stimuli/Trees/1
Stimuli/Trees/2
Stimuli/Trees/3
Stimuli/Fruit/Berries/1
Stimuli/Fruit/Berries/2
Stimuli/Fruit/Berries/3
Stimuli/Fruit/Citrus/1
Stimuli/Fruit/Citrus/2
Stimuli/Fruit/Citrus/3

每个文件夹都包含文件作为刺激。


我的想法,到目前为止非常基本:

%get all files in a folder
sfolder='Stimuli/Berries/1';
stim=dir(fullfile(sfolder,[*.png]));
stim={stim(:).name};

stim=stim(randperm(size(stim,2)));  %randomization.  

我刚试过这个,它给了我文件夹的概率:

fs=dir('Stimuli');
fs={fs(:).name};
fs=fs(3:8);
weightvec=[0.2,0.4,0.3,0.1];
nofsamp=50;
chos=randsample(fs,nofsamp,1,weightvec);

【问题讨论】:

  • 1) 您能否给出一个简洁但完整的文件夹结构示例?是“刺激”文件吗? 2)子文件夹的优先级是做什么的?我很难意识到这一点。
  • 1) 我添加了一个文件夹结构示例。是的,刺激是文件。 2)首先,使用优先级最高的文件夹(1)中的文件,只有当没有文件时,才使用下一个文件夹中的文件。
  • 我会尝试定义一个类对象来完成这项工作。

标签: matlab random probability directory weighted


【解决方案1】:

定义一个类对象foo 来处理这项工作。

注意handle 的继承,因为方法会改变属性。

classdef foo < handle

    properties
        category
        priority
        name
        selected
    end
    methods (Static)
        function obj = parse(dirpath, files)
            N = sum( cellfun(@(x) length(x), {files.name}) );
            obj = foo.empty(N,0);
            counter = 0;
            for ii = 1:length(files)
                ff = files(ii);
                if ~isempty(ff.name)
                    fp = strsplit(strrep(ff.path, dirpath, ''),'/');
                    for jj = 1:length(ff.name)
                        counter = counter+1;
                        obj(counter) = foo( fp{1}, fp{2}, ...
                            regexprep(ff.name{jj}, '\.txt$', '') );
                    end
                end
            end
        end
    end
    methods
        function obj = foo(c, p, n)
            if nargin>0
                obj.category = c;
                obj.priority = p;
                obj.name = n;
                obj.selected = false;
            end
        end
        function obj = choose(stimuli)
            has_delegate = 0;
            while ~has_delegate
                cat = unique({stimuli.category});
                sub = false(3,length(stimuli));
                rcat = randi(length(cat));
                sub(1,:) = ismember( {stimuli.category}, cat(rcat) );
                rpri = 0;
                while ~has_delegate && rpri<3
                    rpri = rpri+1;
                    sub(2,:) = ismember({stimuli.priority}, num2str(rpri));
                    has_delegate = any(~[stimuli( ...
                        all(sub(1:2,:),1) ).selected]);
                end
                if has_delegate
                    sub(3,:) = ismember( [stimuli.selected], false );
                    delegate = find(all(sub,1));
                    rnam = delegate(randi(length(delegate)));
                    obj = stimuli(rnam);
                    stimuli(rnam).selected = true;
                end
            end
        end
    end

end

在主脚本中创建类对象数组。

使用 2 个库 countmemberdirwalk

clear;clc;

% import file names
dirpath = '/home/user/Downloads/S/';
[t_np, t_nd, t_nf] = dirwalk(dirpath);
files = arrayfun(@(x,y) struct('path',x,'name',y),t_np,t_nf);
% create stimuli structure
stimuli = foo.parse(dirpath, files);

% choose stimuli
M = 10;
select = foo.empty(M,0);
t_ii = 1;
while t_ii<=M
    select(t_ii) = stimuli.choose();
    t_ii = t_ii+1;
end
disp({select.name}')

% stats of category
t_stcat = {select.category};
stats = {unique(t_stcat), countmember(unique(t_stcat), t_stcat)};
for t_ii = 1:length(stats{1})
    fprintf('%2.2f %% from \''%s\''.\n', ...
        stats{2}(t_ii)/M*100, stats{1}{t_ii})
end
clearvars t_*

关于文件名

根据您的操作系统,您需要更改文件路径和之前的文件夹路径。

  • 在主脚本中,更改dirpath

  • 在类定义foo中,更改静态方法parse中写入的目录分隔符/和文件扩展名txt

输出

    'oak'
    'lily'
    'ash'
    'banana'
    'sunflower'
    'rose'
    'hazel'
    'cedar'
    'cherry'
    'maple'

30.00 % from 'Flower'.
10.00 % from 'Fruit'.
60.00 % from 'Tree'.
>> 

【讨论】:

  • 非常感谢!从文件夹中的选择就像我想要的那样工作。我可以在哪里预定义从文件夹中选择的刺激的百分比?这样我就可以满足'花'的40%,'仙人掌'的20%,'树木'的10%,'水果'的30%。
  • 好的,我将我的权重向量添加到选择函数中,这样我就可以影响百分比。 % rcat = 兰迪(长度(猫)); % 替换为 rcat=randsample(length(cat),1,1,weightvec);到目前为止,代码只选择了某些文件夹。一旦我得到 Fruit 文件夹及其子文件夹,一切都会好起来的。
  • if length(fp)&lt;=2 obj(counter) = music_select( fp{1}, fp{2}, ... regexprep(ff.name{jj}, '\.wav$', '') ); else obj(counter) = music_select( [fp{1}, '/', fp{2}], fp{3}, ... regexprep(ff.name{jj}, '\.wav$', '') );
  • weightvec 是如何定义的?
猜你喜欢
  • 1970-01-01
  • 2012-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-04
  • 1970-01-01
相关资源
最近更新 更多