Моделирование популяционной фармакокинетики фенобарбитала у новорожденных

Этот пример показывает, как создать простую нелинейную модель смешанных эффектов на основе клинических фармакокинетических данных.

Данные были собраны по 59 предсрочным младенцам, получавшим фенобарбитал для предотвращения судорог в течение первых 16 дней после рождения. Каждый индивидуум получал начальную дозу с последующей одной или несколькими поддерживающими дозами при внутривенном введении болюса. В общей сложности от 1 до 6 измерений концентрации были получены от каждого индивидуума в разы, отличные от времени дозы, в рамках обычного мониторинга, в общей сложности 155 измерений. Были также зарегистрированы веса младенцев и счетов APGAR (мера здоровья новорожденных).

Этот пример использует данные, описанные в [1], исследовании, финансируемом грантом NIH/NIBIB P41-EB01975.

Этот пример требует Statistics and Machine Learning Toolbox™.

Загрузка данных

Эти данные были загружены с веб-сайта http://depts.washington.edu/rfpk/ (больше не активен) Ресурсного средства для фармакокинетики населения в виде текстового файла и сохранен как массив набора данных для простоты использования.

load pheno.mat ds

Визуализация данных на Trellis Plot

t = sbiotrellis(ds, 'ID', 'TIME', 'CONC', 'marker', 'o',...
       'markerfacecolor', [.7 .7 .7], 'markeredgecolor', 'r', ...
       'linestyle', 'none');

% Format the plot.
t.plottitle = 'States versus Time';

t.updateFigureForPrinting();

Опишите данные

В порядок выполнения нелинейного моделирования смешанных эффектов на этом наборе данных мы должны преобразовать данные в groupedData объект, контейнер для хранения табличных данных, который разделен на группы. The groupedData конструктор автоматически идентифицирует обычно используемые имена переменных как сгруппированная переменная или независимая (временная) переменная. Отобразите свойства данных и подтвердите, что GroupVariableName и IndependentVariableName правильно идентифицируются как 'ID' и 'TIME', соответственно.

data = groupedData(ds);
data.Properties
ans = struct with fields:
                Description: ''
                   UserData: []
             DimensionNames: {'Observations'  'Variables'}
              VariableNames: {'ID'  'TIME'  'DOSE'  'WEIGHT'  'APGAR'  'CONC'}
       VariableDescriptions: {}
              VariableUnits: {}
         VariableContinuity: []
                   RowNames: {}
           CustomProperties: [1×1 matlab.tabular.CustomProperties]
          GroupVariableName: 'ID'
    IndependentVariableName: 'TIME'

Определите модель

Мы подбираем к данным простую модель из одного отсека с введением болюсной дозы и линейным устранением клиренса.

pkmd = PKModelDesign;
pkmd.addCompartment('Central', 'DosingType', 'Bolus', 'EliminationType', ...
    'Linear-Clearance', 'HasResponseVariable', true);
model = pkmd.construct;

% The model species |Drug_Central| corresponds to the data variable |CONC|.
responseMap = 'Drug_Central = CONC';

Задайте начальные оценки для параметров

Параметрами, подходящими в этой модели, являются объем центрального отсека (Central) и коэффициент клиренса (Cl_Central). NLMEFIT вычисляет фиксированные и случайные эффекты для каждого параметра. Базовый алгоритм предполагает, что параметры обычно распределены. Это предположение может не соответствовать биологическим параметрам, которые ограничены, чтобы быть положительными, таким как объем и клиренс. Нам нужно задать преобразование для предполагаемых параметров, так что преобразованные параметры действительно следуют нормальному распределению. По умолчанию SimBiology ® выбирает логарифмическое преобразование для всех предполагаемых параметров. Поэтому модель является:

log(Vi)=log(ϕV,i)=θV+ηV,i

и

log(Cli)=log(ϕCl,i)=θCl+ηCl,i,

где θ, eta, и ϕ являются фиксированными эффектами, случайными эффектами и оцененными значениями параметров, соответственно, рассчитанными для каждой группы i. Мы предоставляем некоторые произвольные начальные оценки для V и Cl в отсутствие лучших эмпирических данных.

estimatedParams = estimatedInfo({'log(Central)', 'log(Cl_Central)'}, ...
    'InitialValue', [1 1]);

Извлечение информации о дозах из данных

Создайте дозу образца, которая нацелена на виды Drug_Central и используйте createDoses способ формирования доз для каждого ребенка на основе количества дозировки, перечисленного в переменной DOSE.

sampleDose = sbiodose('sample', 'TargetName', 'Drug_Central');
doses = createDoses(data, 'DOSE', '', sampleDose);

Подбор модели

Слегка ослабьте допуски, чтобы ускорить подгонку.

fitOptions.Options = statset('TolFun', 1e-3, 'TolX', 1e-3);
[nlmeResults, simI, simP] = sbiofitmixed(model, data, responseMap, ...
    estimatedParams, doses, 'nlmefit', fitOptions);

Визуализация подобранной модели с данными

Наложите установленные результаты симуляции на верхнюю часть из наблюдаемых данных, уже отображаемых на графике решетки. Для результатов населения симуляций выполняются с использованием предполагаемых фиксированных эффектов в качестве значений параметров. Для отдельных результатов симуляций выполняются с использованием суммы фиксированных и случайных эффектов в качестве значений параметров.

t.plot(simP, [], '', 'Drug_Central');
t.plot(simI, [], '', 'Drug_Central',...
    'legend',{'Observed', 'Fit-Pop.', 'Fit-Indiv.'});

Исследуйте установленные параметры и ковариации

disp('Summary of initial results');
Summary of initial results
disp('Parameter Estimates Without Random Effects:');
Parameter Estimates Without Random Effects:
disp(nlmeResults.PopulationParameterEstimates(1:2,:));
    Group         Name         Estimate
    _____    ______________    ________

      1      {'Central'   }      1.4086
      1      {'Cl_Central'}    0.006137
disp('Estimated Fixed Effects:');
Estimated Fixed Effects:
disp(nlmeResults.FixedEffects);
       Name        Description      Estimate    StandardError
    __________    ______________    ________    _____________

    {'theta1'}    {'Central'   }    0.34257       0.061246   
    {'theta2'}    {'Cl_Central'}    -5.0934       0.079501   
disp('Estimated Covariance Matrix of Random Effects:');
Estimated Covariance Matrix of Random Effects:
disp(nlmeResults.RandomEffectCovarianceMatrix);
             eta1       eta2  
            _______    _______

    eta1    0.20323          0
    eta2          0    0.19338

Сгенерируйте прямоугольный график предполагаемых параметров

Этот пример использует команды построения графиков MATLAB ®, чтобы визуализировать результаты. Несколько обычно используемых графиков также доступны как встроенные опции при выполнении аппроксимации параметра через интерфейс рабочего стола SimBiology ®.

% Create a box plot of the calculated random effects.
boxplot(nlmeResults);

Сгенерируйте график невязок с течением времени

% The vector of observation data also includes NaN's at the time points at
% which doses were given. We need to remove these NaN's to be able to plot
% the residuals over time.
timeVec = data.(data.Properties.IndependentVariableName);
obsData = data.CONC;
indicesToKeep = ~isnan(obsData);
timeVec = timeVec(indicesToKeep);

% Get the residuals from the fitting results.
indRes = nlmeResults.stats.ires(indicesToKeep);
popRes = nlmeResults.stats.pres(indicesToKeep);

% Plot the residuals. Get a handle to the plot to be able to add more data
% to it later.
resplot = figure;
plot(timeVec,indRes,'d','MarkerFaceColor','b','markerEdgeColor','b');
hold on;
plot(timeVec,popRes,'d','MarkerFaceColor','w','markerEdgeColor','b');
hold off;

% Create a reference line representing a zero residual, and set its
% properties to omit this line from the plot legend.
refl = refline(0,0);
refl.Annotation.LegendInformation.IconDisplayStyle = 'off';

% Label the plot.
title('Residuals versus Time');
xlabel('Time');
ylabel('Residuals');
legend({'Individual','Population'});

Извлечение зависимых от группы ковариационных значений из набора данных

Получите среднее значение каждой ковариаты для каждой группы.

covariateLabels = {'WEIGHT', 'APGAR'};
covariates = grpstats(ds, data.Properties.GroupVariableName, 'mean',...
    'DataVars', covariateLabels);

Исследуйте результаты подгонки параметра NLME на возможные ковариатные зависимости

% Get the parameter values for each group (empirical Bayes estimates). 
paramValues = nlmeResults.IndividualParameterEstimates.Estimate;
isCentral = strcmp('Central', nlmeResults.IndividualParameterEstimates.Name);
isCl = strcmp('Cl_Central', nlmeResults.IndividualParameterEstimates.Name);

% Plot the parameter values vs. covariates for each group.
figure;
subplot(2,2,1);
plot(covariates.mean_WEIGHT,paramValues(isCentral), '.');
ylabel('Volume');

subplot(2,2,3);
plot(covariates.mean_WEIGHT,paramValues(isCl), '.');
ylabel('Clearance');
xlabel('weight');

subplot(2,2,2);
plot(covariates.mean_APGAR, paramValues(isCentral), '.');

subplot(2,2,4);
plot(covariates.mean_APGAR, paramValues(isCl), '.');
xlabel('APGAR');

Создайте CovariateModel, чтобы смоделировать ковариатные зависимости

На основе графиков, по-видимому, существует корреляция между объемом и весом, клиренсом и весом, и, возможно, объемом и счетом APGAR. Мы принимаем решение сосредоточиться на эффекте веса путем моделирования двух из этих ковариатных зависимостей: объема («Central»), варьирующегося с весом и клиренсом («Cl _ Central»), варьирующимся с весом. Наша модель:

log(Vi)=log(ϕV,i)=θV+θV/weight*weighti+ηV,i

и

log(Cli)=log(ϕCl,i)=θCl+θCl/weight*weighti+ηCl,i

% Define the covariate model.
covmodel            = CovariateModel;
covmodel.Expression = ({'Central = exp(theta1 + theta2*WEIGHT + eta1)','Cl_Central = exp(theta3 + theta4*WEIGHT + eta2)'});

% Use constructDefaultInitialEstimate to create a initialEstimates struct.
initialEstimates = covmodel.constructDefaultFixedEffectValues;
disp('Fixed Effects Description:');
Fixed Effects Description:
disp(covmodel.FixedEffectDescription);
    {'Central'          }
    {'Cl_Central'       }
    {'Central/WEIGHT'   }
    {'Cl_Central/WEIGHT'}

Обновите начальные оценки, используя значения, оцененные от подбора кривой базовой модели.

initialEstimates.theta1 = nlmeResults.FixedEffects.Estimate(1);
initialEstimates.theta3 = nlmeResults.FixedEffects.Estimate(2);
covmodel.FixedEffectValues = initialEstimates;

Подбор модели

[nlmeResults_cov, simI_cov, simP_cov] = sbiofitmixed(model, data, responseMap, ...
    covmodel, doses, 'nlmefit', fitOptions);

Исследуйте установленные параметры и ковариации

disp('Summary of results when modeling covariate dependencies');
Summary of results when modeling covariate dependencies
disp('Parameter Estimates Without Random Effects:');
Parameter Estimates Without Random Effects:
disp(nlmeResults_cov.PopulationParameterEstimates);
    Group         Name         Estimate 
    _____    ______________    _________

     1       {'Central'   }       1.2973
     1       {'Cl_Central'}    0.0061576
     2       {'Central'   }       1.3682
     2       {'Cl_Central'}    0.0065512
     3       {'Central'   }       1.3682
     3       {'Cl_Central'}    0.0065512
     4       {'Central'   }      0.99431
     4       {'Cl_Central'}    0.0045173
     5       {'Central'   }       1.2973
     5       {'Cl_Central'}    0.0061576
     6       {'Central'   }       1.1664
     6       {'Cl_Central'}      0.00544
     7       {'Central'   }       1.0486
     7       {'Cl_Central'}     0.004806
     8       {'Central'   }       1.1664
     8       {'Cl_Central'}      0.00544
     9       {'Central'   }       1.2973
     9       {'Cl_Central'}    0.0061576
     10      {'Central'   }       1.2973
     10      {'Cl_Central'}    0.0061576
     11      {'Central'   }       1.1664
     11      {'Cl_Central'}      0.00544
     12      {'Central'   }       1.2301
     12      {'Cl_Central'}    0.0057877
     13      {'Central'   }       1.1059
     13      {'Cl_Central'}    0.0051132
     14      {'Central'   }       1.1059
     14      {'Cl_Central'}    0.0051132
     15      {'Central'   }       1.2301
     15      {'Cl_Central'}    0.0057877
     16      {'Central'   }       1.1664
     16      {'Cl_Central'}      0.00544
     17      {'Central'   }       1.1059
     17      {'Cl_Central'}    0.0051132
     18      {'Central'   }       1.0486
     18      {'Cl_Central'}     0.004806
     19      {'Central'   }       1.0486
     19      {'Cl_Central'}     0.004806
     20      {'Central'   }       1.1664
     20      {'Cl_Central'}      0.00544
     21      {'Central'   }        1.605
     21      {'Cl_Central'}    0.0078894
     22      {'Central'   }       1.3682
     22      {'Cl_Central'}    0.0065512
     23      {'Central'   }       3.2052
     23      {'Cl_Central'}     0.017654
     24      {'Central'   }       3.3803
     24      {'Cl_Central'}     0.018782
     25      {'Central'   }      0.89394
     25      {'Cl_Central'}    0.0039908
     26      {'Central'   }       3.9653
     26      {'Cl_Central'}     0.022619
     27      {'Central'   }       1.6927
     27      {'Cl_Central'}    0.0083936
     28      {'Central'   }       3.3803
     28      {'Cl_Central'}     0.018782
     29      {'Central'   }       1.0486
     29      {'Cl_Central'}     0.004806
     30      {'Central'   }        1.605
     30      {'Cl_Central'}    0.0078894
     31      {'Central'   }       1.2973
     31      {'Cl_Central'}    0.0061576
     32      {'Central'   }       4.1819
     32      {'Cl_Central'}     0.024064
     33      {'Central'   }       1.5218
     33      {'Cl_Central'}    0.0074154
     34      {'Central'   }       1.5218
     34      {'Cl_Central'}    0.0074154
     35      {'Central'   }       2.3292
     35      {'Cl_Central'}     0.012173
     36      {'Central'   }       1.3682
     36      {'Cl_Central'}    0.0065512
     37      {'Central'   }       1.1664
     37      {'Cl_Central'}      0.00544
     38      {'Central'   }       1.2301
     38      {'Cl_Central'}    0.0057877
     39      {'Central'   }       1.6927
     39      {'Cl_Central'}    0.0083936
     40      {'Central'   }       1.1059
     40      {'Cl_Central'}    0.0051132
     41      {'Central'   }       1.5218
     41      {'Cl_Central'}    0.0074154
     42      {'Central'   }       2.7323
     42      {'Cl_Central'}     0.014659
     43      {'Central'   }      0.99431
     43      {'Cl_Central'}    0.0045173
     44      {'Central'   }       1.2973
     44      {'Cl_Central'}    0.0061576
     45      {'Central'   }      0.94279
     45      {'Cl_Central'}    0.0042459
     46      {'Central'   }       1.1059
     46      {'Cl_Central'}    0.0051132
     47      {'Central'   }       2.4565
     47      {'Cl_Central'}     0.012951
     48      {'Central'   }      0.89394
     48      {'Cl_Central'}    0.0039908
     49      {'Central'   }       1.2301
     49      {'Cl_Central'}    0.0057877
     50      {'Central'   }       1.1059
     50      {'Cl_Central'}    0.0051132
     51      {'Central'   }      0.99431
     51      {'Cl_Central'}    0.0045173
     52      {'Central'   }      0.99431
     52      {'Cl_Central'}    0.0045173
     53      {'Central'   }       1.5218
     53      {'Cl_Central'}    0.0074154
     54      {'Central'   }        1.605
     54      {'Cl_Central'}    0.0078894
     55      {'Central'   }       1.1059
     55      {'Cl_Central'}    0.0051132
     56      {'Central'   }      0.84763
     56      {'Cl_Central'}     0.003751
     57      {'Central'   }       1.8827
     57      {'Cl_Central'}    0.0095009
     58      {'Central'   }       1.2973
     58      {'Cl_Central'}    0.0061576
     59      {'Central'   }       1.1059
     59      {'Cl_Central'}    0.0051132
disp('Estimated Fixed Effects:');
Estimated Fixed Effects:
disp(nlmeResults_cov.FixedEffects);
       Name            Description         Estimate    StandardError
    __________    _____________________    ________    _____________

    {'theta1'}    {'Central'          }    -0.48453      0.067952   
    {'theta3'}    {'Cl_Central'       }     -5.9575       0.12199   
    {'theta2'}    {'Central/WEIGHT'   }     0.53203      0.040788   
    {'theta4'}    {'Cl_Central/WEIGHT'}     0.61957      0.074264   
disp('Estimated Covariance Matrix:');
Estimated Covariance Matrix:
disp(nlmeResults_cov.RandomEffectCovarianceMatrix);
              eta1       eta2  
            ________    _______

    eta1    0.029793          0
    eta2           0    0.04644

Визуализация подобранной модели с данными

t.plot(simP_cov, [], '', 'Drug_Central');
t.plot(simI_cov, [], '', 'Drug_Central',...
    'legend',{'Observed', 'Fit-Pop..', 'Fit-Indiv.', 'Cov. Fit-Pop.', 'Cov. Fit-Indiv.'});

Сравните невязки с остатками из модели без ковариатных зависимостей

Следующий график показывает, что невязки населения меньше в ковариатной модели по сравнению с исходной подгонкой.

% Get the residuals from the fitting results.
indRes = nlmeResults_cov.stats.ires(indicesToKeep);
popRes = nlmeResults_cov.stats.pres(indicesToKeep);

% Return to the original residual plot figure and add the new data.
figure(resplot);
hold on;
plot(timeVec,indRes,'d','MarkerFaceColor','r','markerEdgeColor','r');
plot(timeVec,popRes,'d','MarkerFaceColor','w','markerEdgeColor','r');
hold off;

% Update the legend.
legend('off');
legend({'Individual','Population','Individual(Cov.)','Population(Cov.)'});

Ссылки

[1] Grasela TH Jr, Donn SM. Неонатальное население фармакокинетика фенобарбитала, полученная из рутинных клинических данных. Dev Pharmacol Ther 1985:8 (6). 374-83.