Matlab:来自具有不同概率的文件夹的刺激的随机列表

时间:2014-07-31 08:05:21

标签: matlab random probability directory weighted

我有几个文件夹,子文件夹包含刺激,并希望生成这些刺激的随机列表。根据刺激优先级,子文件夹被称为“1”,“2”,“3”。此外,最终列表应该具有来自每个文件夹的一定比例的刺激。

实施例: 40%来自'鲜花', 来自'仙人掌'的20%, 10%来自'Trees', 30%来自'Fruit'。

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 个答案:

答案 0 :(得分:0)

定义一个类对象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中,更改以静态方法/编写的目录定界符txt和文件扩展名parse

输出

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

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