Минимизируйте разницу между индикаторными переменными в Matlab

Я новичок в Matlab и хочу написать программу, которая выбирает значение параметра (P), чтобы минимизировать разницу между двумя векторами, где каждый вектор является переменной в фрейме данных. Первый вектор (назовем его A) представляет собой заданный вектор из единиц и нулей, а второй вектор (назовем его B) имеет каждый из своих элементов, определенных как индикаторная функция, которая зависит от значения параметра P и других переменных в фрейм данных. Например, пусть C будет третьей переменной в наборе данных, поэтому

А = [1, 0, 0, 1, 0]

В = [х, у, г, и, v]

где x = 1, если (C[1]+10)^0,5 - P > (C[1])^0,5, иначе x = 0, и аналогично, y = 1, если (C[2]+10)^0,5 - P > (C[2])^0,5, иначе y = 0 и так далее.

Я не совсем уверен, с чего начать код, за исключением того, что может быть полезно использовать команду fminsearch. Какие-либо предложения?

Редактировать: я изменил вышеизложенное, возведя в степень, которая ближе к реальному примеру, который у меня есть. Я также предоставляю полный пример в ответ на комментарий: Пусть A такое же, как указано выше, и пусть C = [10, 1, 100, 1000, 1]. Тогда моя цель с кодом Matlab состояла бы в том, чтобы выбрать значение P, чтобы минимизировать различия между координатами векторов A и B, где B[1] = 1, если (10 + 10) ^ 0,5 - P > (10) ^ 0,5 и в противном случае B[1] = 0, и аналогично B[2] = 1, если (1 + 10) ^ 0,5 - P > (1) ^ 0,5 и в противном случае B [2] = 0 и т. д. Итак, я хочу выберите P, чтобы максимизировать вероятность того, что A[1] = B[1], A[2] = B[2] и т. д.

У меня есть следующая настройка в Matlab, где ds — это имя моего набора данных:

ds.B = zeros(size(ds,1),1);     % empty vector to fill
for i = 1:size(ds,1)
if ((ds.C(i) + 10)^(0.5) - P > (ds.C(i))^(0.5))
    ds.B(i) = 1;
else 
    ds.B(i) = 0;
end
end

Теперь я хочу выбрать значение P, чтобы минимизировать разницу между A и B. Как мне это сделать?

Обновлено: мне также интересно, как это сделать, когда неравенство похоже на (C[i]+10)^0,5 - P*D[i] > (C[i])^0,5, где D — другая переменная в мой набор данных. Теперь P — это скаляр, который умножается, а не просто складывается. Это кажется более сложным, поскольку я не могу точно определить P. Как мне решить проблему в этом случае?

Итак, если P<10 -> x = 1, иначе x = 0, независимо от значения C[1], правильно ли это? Не могли бы вы привести полный пример ожидаемого результата, полностью написав значения A, C и P, а также результирующее значение B?

picchiolu 11.01.2023 09:12

Я заметил, что вы разместили связанный вопрос после этого? Какое-то время это вертелось у меня в голове, и я только что нашел ответ. Но похоже вопрос снят? Если вы хотите сделать репост, я могу дать ответ через пару дней.

FragileX 26.01.2023 04:12

Спасибо. Я разместил его здесь: stackoverflow.com/questions/75194207/…

RK124 04.02.2023 02:48
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
150
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

РЕДАКТИРОВАТЬ 1: кажется, что fminbnd() не является оптимальным, вероятно, из-за ступенчатого характера функции индикатора. Я обновил, чтобы проверить средние точки всех областей между переворотами функции индикатора, а также конечные точки.

Обновлено еще раз: Обновлено, чтобы включить набор данных D в качестве коэффициента P.


Если вы можете упаковать расчет расстояния в одну функцию, основанную на P, вы можете найти его минимум.

arraySize = 1000;
ds.A = double(rand([arraySize,1]) > 0.5);
ds.C = rand(size(ds.A));
ds.D = rand(size(ds.A));
B = @(P)double((ds.C+10).^0.5 - P.*ds.D > ds.C.^0.5);

costFcn = @(P)sqrt(sum((ds.A-B(P)).^2));

% Solving the equation (C+10)^0.5 - P*D = C^0.5 for P, and sorting the results
BCrossingPoints = sort(((ds.C+10).^0.5-ds.C.^0.5)./ds.D);
% Taking the average of each crossing point with its neighbors
BMidpoints = (BCrossingPoints(1:end-1)+BCrossingPoints(2:end))/2;
% Appending endpoints onto the midpoints
PsToTest = [BCrossingPoints(1)-0.1; BMidpoints; BCrossingPoints(end)+0.1];
% Calculate the distance from A to B at each P to test
costResult = arrayfun(costFcn,PsToTest);
% Find the minimum cost
[~,lowestCostIndex] = min(costResult);
% Find the optimum P
optimumP = PsToTest(lowestCostIndex);

ds.B = B(optimumP);

semilogx(PsToTest,costResult)
xlabel('P')
ylabel('Distance from A to B')

Большое спасибо за ваш полезный ответ. У меня есть один уточняющий вопрос. Кажется, что даже когда я немного меняю функцию, например. изменяя мощность или добавляемую константу (10), я всегда получаю вектор ds.B, который либо содержит все 0, либо все единицы. Является ли это результатом того, как устроен код, или это характер конкретной функции, которую я выбрал? В идеале я хотел бы разрешить вариант, что элементы B могут отличаться.

RK124 11.01.2023 19:15

Вероятно, это результат работы входных данных и функции индикатора. Мне удалось получить B = [0 0 0 1 0] с C = [50 0 100 500 3] и функцией C+10-P>C.^0.5

FragileX 11.01.2023 19:33

Что ж, похоже, что fminbnd может не подойти для вашего приложения, вероятно, из-за ступенчатого характера функции расстояния. Я изменил свой ответ, чтобы использовать другой метод нахождения минимального расстояния.

FragileX 11.01.2023 21:45

Спасибо за редактирование. Когда я применяю это к своим данным, я получаю следующую ошибку, связанную со строкой PsToTest = [BCrossingPoints(1)-0.1, BMidpoints, BCrossingPoints(end)+0.1];Error using horzcat Dimensions of arrays being concatenated are not consistent. Не могли бы вы объяснить, как определяются BCrossingPoints и BMidpoints? Я еще не следую интуиции.

RK124 11.01.2023 22:57

@ RK124 Глядя на ваш пример выше, кажется, что вы используете векторы-столбцы, в то время как в моем примере использовались векторы-строки. Я отредактировал свой ответ, чтобы он соответствовал вашему, что означало замену запятых в массивах точками с запятой. Теперь он должен работать с вашими данными. Я также добавил комментарии к ответу, чтобы объяснить, для чего предназначен каждый шаг.

FragileX 11.01.2023 23:35

Еще раз спасибо за вашу помощь в этом. Мне интересно, могу ли я использовать аналогичный метод для решения значения, которое умножается на вектор (т.е. на одну из других переменных). Например, если уравнение имеет вид B = @(P)double((ds.C+10).^0,5 - P*ds.D > ds.C.^0,5), где ds.D — другая переменная в наборе данных . Когда я пытаюсь разделить все это на ds.D, чтобы определить BCrossingPoints (т.е. найти P), я получаю ошибку Requested 37885x37885 (21.4GB) array exceeds maximum array size preference (8.0GB). Есть ли у вас какие-либо предложения?

RK124 16.01.2023 02:23

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

FragileX 16.01.2023 05:56

Немного подумав об этом, я не уверен, что концептуально понимаю, как адаптировать вышеизложенное к случаю, когда B = @(P)double((ds.C+10).^0,5 - P*ds.D > ds.C.^0,5). Поскольку «деление вектора на другой вектор» на самом деле не определяется математически, я действительно не понимаю, как определить BCrossingPoints в этом случае ... Я отредактирую свой исходный вопрос, чтобы узнать об этом немного глубже.

RK124 16.01.2023 16:03

Я так понимаю, вы хотите, чтобы каждый элемент B зависел только от соответствующих ему партнеров в C и D? Вы захотите использовать поэлементное деление, а не матричное деление. Я отредактирую свой ответ выше, чтобы приспособиться. Вы можете узнать больше здесь.

FragileX 16.01.2023 16:12

1.- x предполагается только положительным действительным, потому что с x<0 появляются комплексные значения.

Поскольку в вопросе нет комментариев, кажется разумным предположить только x real и x>0.

В соответствии с запросом P 'параметр' является скаляром, P имеет только 2 значимых состояния >0 или <0, давайте посмотрим, как это:

2.- Следующие строки генерируют случайные числа A и C.

Затем выполняется развертка p и вычисляются расстояния d1 и d2.

d1 — евклидово расстояние, а d2 — абсолютная разница между A и B при преобразовании из двоичного в десятичное:

N=10
% A=[1 0 0 1 0]
A=randi([0 1],1,N);
% C=[10 1 1e2 1e3 1]
C=randi([0 1e3],1,N)

p=[-1e4:1:1e4];  % parameter to optimize

B=zeros(1,numel(A));

d1=zeros(1,numel(p));  % euclidean distance
d2=zeros(1,numel(p));  % difference distance

for k1=1:1:numel(p)
    B=(C+10).^.5-p(k1)>C.^.5;
        d1(k1)=(sum((B-A).^2))^.5;
    d2(k1)=abs(sum(A.*2.^[numel(A)-1:-1:0])-sum(B.*2.^[numel(A)-1:-1:0]));
end

figure;
plot(p,d1)
grid on
xlabel('p');title('d1')

figure
plot(p,d2)
grid on
xlabel('p');title('d2')

Единственная степень свободы для оптимизации, по-видимому, — это знак P независимо от |P| ценить.

3.- f(p,x) либо не имеет корня, либо имеет только один корень, в зависимости от p

Пороговая функция

if f(x)>0 then B(k)==1 else B(k)==0

Это

f(p,x)=(x+10)^.5-p-x^.5

Сейчас

(x+10).^.5-p>x.^.5 такое же, как (x+10).^.5-x.^.5>p

Существует диапазон p, который сохраняет f(p,x)=0 без какого-либо (настоящего) корня.

Для частного случая p=0 тогда (x+10).^.5 и x.^.5 не пересекаются (пока Inf не достигнуто = пересечения нет)

figure;plot(x,(x+10).^.5,x,x.^.5);grid on
[![][3]][3]
    
y2=diff((x+10).^.5-x.^.5)
figure;plot(x(2:end),y2);
grid on;xlabel('x')
title('y2=diff((x+10).^.5-x.^.5)')
[![][3]][3]
% 005

Это означает, что условие f(x)>0 всегда истинно, если все биты B=1. При B=1 d(A,B) превращается в d(A,1), константу.

Однако для определенного значения p есть один корень, а f(x)>0 всегда ложно, сохраняя все биты B=0.

В этом случае d(A,B) функция стоимости превращается в d(A,0), а это и есть сама A.

4.- P как вектор

Оптимизация выигрывает в степенях свободы, если вместо скаляра P рассматривать P как вектор.

Для данного x существует значение p, которое переключает B(k) с 0 на 1.

Любое значение p ниже этого порога сохраняет B(k)=0.

Эквивалентно, инвертирование f(x) :

g(p)=(10-p^2)^2/(4*p^2)>x

Значения x ниже этого порога приближают B к A, потому что для каждого элемента B оно переворачивается на значение элемента A.

Поэтому удобно рассматривать P как вектор, а не как скаляр, и:

Чтобы все или как можно больше (насколько это возможно) элементов C соответствовали c(k)<(10-p^2)^2/(4*p^2), чтобы получить C=A или минимизировать d(A,C)

5.- корни f(p,x)

syms t positive
p=[-1000:.1:1000];
zp=NaN*ones(1,numel(p));
sol=zeros(1,numel(p));
for k1=1:1:numel(p)
  p(k1)
    eq1=(t+10)^.5-p(k1)-t^.5-p(k1)==0;
    s1=solve(eq1,t);
    if ~isempty(s1) 
        zp(k1)=s1;
    end
end

nzp=~isnan(zp);
zp(nzp)

возвращается

 =
  
  620.0100  151.2900   64.5344   34.2225   20.2500   12.7211
 
    8.2451    5.4056    3.5260    2.2500    1.3753    0.7803
 
    0.3882    0.1488    0.0278

Ваш пункт № 2 страдает от отсутствия разрешения выборки. Если вы измените на p=[0:.01:2];, вы увидите интересное поведение.

FragileX 16.01.2023 17:04

Я не уверен, что полностью понял пункт № 3. При p==0 я вижу, что B всегда будет ложным. Однако при положительном P наличие корня означает, что при малых значениях C результат функции будет слева от этого корня и, следовательно, истинен, а при больших значениях C результат функции будет справа от этого корня и, следовательно, ложен. Затем, учитывая массив независимых значений C, вы получите массив независимых значений B.

FragileX 16.01.2023 18:21

Предлагаемое уменьшение шага для увеличения разрешения остается за автором вопроса. Иногда может потребоваться улучшение данного ответа, но решение указывает на правильное направление. Почему бы нам не оставить автору вопроса, если он заинтересован, добавить дополнительные комментарии?

John BG 28.01.2023 01:53

Напротив, тот факт, что существует область P, где функция стоимости возвращает расстояния, отличные от экстремумов, делает ваш вывод в пункте 2 просто неверным. На самом деле не имеет значения, замечаю ли это я или ОП. Кроме того, это на самом деле ведет в неправильном направлении, предполагая, что можно просто выбрать положительное или отрицательное P и сделать это, когда фактический минимум (который искал ОП) обычно находится в этой небольшой средней области.

FragileX 28.01.2023 03:45

Другие вопросы по теме