В этом примере показано, как оценить специфичный для категории (такой как молодой по сравнению со старым, штекерным по сравнению с розеткой), отдельно-специфичные, и параметры всего населения с помощью PK профилируют данные от нескольких индивидуумов.
Предположим, что вы имеете данные о концентрации плазмы препарата от 30 индивидуумов и хотите оценить фармакокинетические параметры, а именно, объемы центрального и периферийного отсека, разрешения и межразделенного на отсеки разрешения. Примите, что концентрация препарата по сравнению с профилем времени следует за снижением biexponential , где концентрация препарата во время t, и и наклоны для соответствующих экспоненциальных снижений.
Эти синтетические данные содержат ход времени плазменных концентраций 30 индивидуумов после дозы шарика (100 мг), измеренных в разное время и для центральных и для периферийных отсеков. Это также содержит категориальные переменные, а именно, Sex и Age.
clear
load('sd5_302RAgeSex.mat')Преобразуйте набор данных в groupedData объект, который является необходимым форматом данных для подходящего функционального sbiofit. groupedData объект также позволяет вам независимую переменную набора и имена переменных группы (если они существуют). Установите модули IDВремя, CentralConc, PeripheralConc, Age, и Sex переменные. Модули являются дополнительными и только необходимыми для UnitConversion покажите, который автоматически преобразует соответствие с физическими количествами в одну сопоставимую модульную систему.
gData = groupedData(data);
gData.Properties.VariableUnits = {'','hour','milligram/liter','milligram/liter','',''};
gData.Propertiesans = struct with fields:
Description: ''
UserData: []
DimensionNames: {'Row' 'Variables'}
VariableNames: {1x6 cell}
VariableDescriptions: {}
VariableUnits: {1x6 cell}
VariableContinuity: []
RowNames: {}
CustomProperties: [1x1 matlab.tabular.CustomProperties]
GroupVariableName: 'ID'
IndependentVariableName: 'Time'
IndependentVariableName и GroupVariableName свойства были автоматически установлены в Time и ID переменные данных.
Отобразите данные об ответе для каждого индивидуума.
t = sbiotrellis(gData,'ID','Time',{'CentralConc','PeripheralConc'},... 'Marker','+','LineStyle','none'); % Resize the figure. t.hFig.Position(:) = [100 100 1280 800];

Пользуйтесь встроенной библиотекой PK, чтобы создать модель 2D отсека с дозированием вливания и устранением первого порядка, где уровень устранения зависит от разрешения и объема центрального отсека. Используйте configset объект включить модульное преобразование.
pkmd = PKModelDesign; pkc1 = addCompartment(pkmd,'Central'); pkc1.DosingType = 'Bolus'; pkc1.EliminationType = 'linear-clearance'; pkc1.HasResponseVariable = true; pkc2 = addCompartment(pkmd,'Peripheral'); model = construct(pkmd); configset = getconfigset(model); configset.CompileOptions.UnitConversion = true;
Для получения дополнительной информации при создании разделенных на отсеки моделей PK с помощью SimBiology® встроенная библиотека, смотрите, Создают Фармакокинетические Модели.
Примите, что каждый индивидуум получает дозу шарика 100 мг во время = 0. Для получения дополнительной информации при подготовке различных стратегий дозирования, смотрите Дозы в Моделях SimBiology.
dose = sbiodose('dose','TargetName','Drug_Central'); dose.StartTime = 0; dose.Amount = 100; dose.AmountUnits = 'milligram'; dose.TimeUnits = 'hour';
Данные содержат измеренную плазменную концентрацию в центральных и периферийных отсеках. Сопоставьте эти переменные с соответствующими компонентами модели, которые являются Drug_Central и Drug_Peripheral.
responseMap = {'Drug_Central = CentralConc','Drug_Peripheral = PeripheralConc'};Задайте объемы центральных и периферийных отсеков Central и Peripheral, межразделенное на отсеки разрешение Q12, и разрешение Cl_Central как параметры, чтобы оценить. estimatedInfo объект позволяет вам опционально указать, что параметр преобразовывает, начальные значения и границы параметра. Начиная с обоих Central и Peripheral ограничиваются быть положительным, задать логарифмическое преобразование для каждого параметра.
paramsToEstimate = {'log(Central)', 'log(Peripheral)', 'Q12', 'Cl_Central'};
estimatedParam = estimatedInfo(paramsToEstimate,'InitialValue',[1 1 1 1]);Оцените один набор параметров для каждого индивидуума путем установки 'Pooled' аргумент пары "имя-значение" false.
unpooledFit = sbiofit(model,gData,responseMap,estimatedParam,dose,'Pooled',false);Постройте подходящие результаты по сравнению с исходными данными для каждого индивидуума (группа).
t = plot(unpooledFit);
% Resize the figure.
t.hFig.Position(:) = [100 100 1280 800];
Для необъединенной подгонки, sbiofit всегда возвращается, каждый заканчивается объект для каждого индивидуума.
Исследуйте необъединенные оценки, чтобы видеть, существуют ли какие-либо специфичные для категории параметры, то есть, если некоторые параметры связаны с одной или несколькими категориями. Если существуют какие-либо зависимости от категории, может быть возможно уменьшать количество степеней свободы путем оценки только специфичных для категории значений для тех параметров.
Сначала извлеките ID и значения категории для каждого ID
catParamValues = unique(gData(:,{'ID','Sex','Age'}));Добавьте переменные в таблицу, содержащую оценку каждого параметра.
allParamValues = vertcat(unpooledFit.ParameterEstimates); catParamValues.Central = allParamValues.Estimate(strcmp(allParamValues.Name, 'Central')); catParamValues.Peripheral = allParamValues.Estimate(strcmp(allParamValues.Name, 'Peripheral')); catParamValues.Q12 = allParamValues.Estimate(strcmp(allParamValues.Name, 'Q12')); catParamValues.Cl_Central = allParamValues.Estimate(strcmp(allParamValues.Name, 'Cl_Central'));
Постройте оценки каждого параметра для каждой категории. gscatter требует Statistics and Machine Learning Toolbox™. Если у вас нет его, используйте другие альтернативные функции построения графика, такие как plot.
h = figure;
ylabels = {'Central','Peripheral','Cl\_Central','Q12'};
plotNumber = 1;
for i = 1:4
thisParam = estimatedParam(i).Name;
% Plot for Sex category
subplot(4,2,plotNumber);
plotNumber = plotNumber + 1;
gscatter(double(catParamValues.Sex), catParamValues.(thisParam), catParamValues.Sex);
ax = gca;
ax.XTick = [];
ylabel(ylabels(i));
legend('Location','bestoutside')
% Plot for Age category
subplot(4,2,plotNumber);
plotNumber = plotNumber + 1;
gscatter(double(catParamValues.Age), catParamValues.(thisParam), catParamValues.Age);
ax = gca;
ax.XTick = [];
ylabel(ylabels(i));
legend('Location','bestoutside')
end
% Resize the figure.
h.Position(:) = [100 100 1280 800];
На основе графика кажется, что молодые индивидуумы склонны иметь более высокие объемы центральных и периферийных отсеков (Central, Peripheral) чем старые индивидуумы (то есть, объемы, кажется, являются возрастными). Кроме того, штекеры имеют тенденцию иметь более высокий уровень раскрываемости преступлений (Cl_Central) чем розетки, но противоположное для параметра Q12 (то есть, разрешение и Q12, кажется, сексуально-специфичны).
Используйте 'CategoryVariableName' свойство estimatedInfo объект задать, который категория использовать во время подбора кривой. Используйте 'Sex' как группа к пригодному для разрешения Cl_Central и Q12 параметры. Используйте 'Age' как группа к пригодному для Central и Peripheral параметры.
estimatedParam(1).CategoryVariableName = 'Age'; estimatedParam(2).CategoryVariableName = 'Age'; estimatedParam(3).CategoryVariableName = 'Sex'; estimatedParam(4).CategoryVariableName = 'Sex'; categoryFit = sbiofit(model,gData,responseMap,estimatedParam,dose)
categoryFit =
OptimResults with properties:
ExitFlag: 3
Output: [1x1 struct]
GroupName: []
Beta: [8x5 table]
ParameterEstimates: [120x6 table]
J: [240x8x2 double]
COVB: [8x8 double]
CovarianceMatrix: [8x8 double]
R: [240x2 double]
MSE: 0.4362
SSE: 205.8690
Weights: []
LogLikelihood: -477.9195
AIC: 971.8390
BIC: 1.0052e+03
DFE: 472
DependentFiles: {1x3 cell}
EstimatedParameterNames: {'Central' 'Peripheral' 'Q12' 'Cl_Central'}
ErrorModelInfo: [1x3 table]
EstimationFunction: 'lsqnonlin'
При подборе кривой по категориям (или группа), sbiofit всегда возвращается, каждый заканчивается объект, не один для каждого уровня категории. Это вызвано тем, что и штекерные и розеточные индивидуумы считаются частью той же оптимизации с помощью тех же ошибочных параметров модели и параметров ошибок, так же для молодых и старых индивидуумов.
Постройте специфичные для категории предполагаемые результаты.
t = plot(categoryFit);
% Resize the figure.
t.hFig.Position(:) = [100 100 1280 800];
Для Cl_Central и Q12 параметры, все штекеры имели те же оценки, и так же для розеток. Для Central и Peripheral параметры, у всех молодых индивидуумов были те же оценки, и так же для старых индивидуумов.
Чтобы лучше сравнить результаты, подбирайте модель ко всем данным, объединенным вместе, то есть, оцените один набор параметров для всех индивидуумов путем установки 'Pooled' аргумент пары "имя-значение" true. Предупреждающее сообщение говорит вам, что эта опция проигнорирует любую специфичную для категории информацию (если они будут существовать).
pooledFit = sbiofit(model,gData,responseMap,estimatedParam,dose,'Pooled',true);Warning: CategoryVariableName property of the estimatedInfo object is ignored when using the 'Pooled' option.
Постройте подходящие результаты по сравнению с исходными данными. Несмотря на то, что отдельный график был сгенерирован для каждого индивидуума, данные были адаптированы с помощью того же набора параметров (то есть, у всех индивидуумов была та же подходящая линия).
t = plot(pooledFit);
% Resize the figure.
t.hFig.Position(:) = [100 100 1280 800];
Сравните остаточные значения CentralConc и PeripheralConc ответы для каждой подгонки.
t = gData.Time;
allResid(:,:,1) = pooledFit.R;
allResid(:,:,2) = categoryFit.R;
allResid(:,:,3) = vertcat(unpooledFit.R);
h = figure;
responseList = {'CentralConc', 'PeripheralConc'};
for i = 1:2
subplot(2,1,i);
oneResid = squeeze(allResid(:,i,:));
plot(t,oneResid,'o');
refline(0,0); % A reference line representing a zero residual
title(sprintf('Residuals (%s)', responseList{i}));
xlabel('Time');
ylabel('Residuals');
legend({'Pooled','Category-Specific','Unpooled'});
end
% Resize the figure.
h.Position(:) = [100 100 1280 800];
Как показано в графике, необъединенная подгонка произвела лучшую подгонку к данным, когда это соответствует данным к каждому индивидууму. Это ожидалось, поскольку это использовало большую часть количества степеней свободы. Подгонка категории уменьшала количество степеней свободы подгонкой данных к двум категориям (пол и возраст). В результате остаточные значения были больше, чем необъединенная подгонка, но еще меньшими, чем подгонка населения, которая оценила всего один набор параметров для всех индивидуумов. Подходящая категорией сила быть хорошим компромиссом между необъединенным и объединенным подбором кривой при условии, что любая иерархическая модель существует в ваших данных.