Лучшее (нелинейное) бинирование

Последний вопрос, который я задал, касался сортировки данных по координате x. Решение было простым и элегантным, и мне стыдно, что я его не увидел. Этот вопрос может быть сложнее (или я просто слепой).

Я начал с примерно 140000 точек данных и разделил их на 70 групп, равномерно распределенных по оси x. Затем я взял среднее положение (x_avg, y_avg) каждой группы и построил их; появился красивый изгиб. К сожалению, есть две проблемы. Во-первых, ребра заполнены гораздо меньше, чем центр графа; Во-вторых, некоторые области меняются больше, чем другие, и поэтому требуется лучшее разрешение.

Таким образом, у меня есть два конкретных вопроса и общее приглашение высказывать предложения:

Есть ли в Matlab встроенный способ разбиения матрицы на фиксированное количество меньших матриц или меньших матриц фиксированного размера?

Есть ли алгоритм (или функция Matlab, но я считаю это маловероятным) для более точного определения границ, необходимых для объединения интересующих областей?

В более общем плане, есть ли лучший способ собрать десятки тысяч точек данных в аккуратный тренд?

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

Ответы 2

Я никогда не использовал Matlab, но, глядя на ваш предыдущий вопрос, я подозреваю, что вы ищете что-то вроде Kdtree или его варианта.

Разъяснение: Поскольку здесь, кажется, есть некоторая путаница, я думаю, что пример псевдокода уместен.

// Some of this shamelessly borrowed from the wikipedia article
function kdtree(points, lower_bound, upper_bound) {
    // lower_bound and upper_bound are the boundaries of your bucket
    if (points is empty) {
        return nil
    }
    // It's a trivial exercise to control the minimum size of a partition as well
    else {
        // Sort the points list and choose the median element
        select median from points.x

        node.location = median;

        node.left = kdtree(select from points where lower_bound < points.x <= median, lower_bound, median);
        node.right = kdtree(select from points where median < points.x <= upper_bound, median, upper_bound);

        return node
    }
}

kdtree(points, -inf, inf)

// or alternatively

kdtree(points, min(points.x), max(points.x))

Я не думаю, что мне нужно дерево k-d; Я не сортирую по оси y. Может быть, простое двоичное дерево может работать, но я не понимаю, как это сделать.

Alex R 09.01.2009 11:50

k-d деревья - это бинарные деревья с добавлением плоскости разделения, прикрепленной к каждому узлу. Они также масштабируются независимо от количества имеющихся у вас размеров, поэтому вы можете просто игнорировать компонент y, отсортировать по компоненту x, и плоскости, которые вы получите, должны быть близки к оптимальным границам для ваших сегментов.

Kevin Loney 09.01.2009 20:21

Даже если у меня есть двоичное дерево, я не понимаю, что бы я сделал для определения границ.

Alex R 09.01.2009 22:30
Ответ принят как подходящий

Похоже, вы хотите использовать ячейки, размер которых различается в зависимости от плотности значений x. Я думаю, вы все еще можете использовать функцию HISTC, как в ответе на ваш предыдущий пост, но вам просто нужно придать ей другой набор граней.

Я не знаю, хотите ли вы именно этого, но вот одно предложение: вместо разделения оси x на 70 групп с равным интервалом разделите отсортированные данные x на 70 равных групп и определите значения границ. Я думаю, что этот код должен работать:

% Start by assuming x and y are vectors of data:

nBins = 70;
nValues = length(x);
[xsort,index] = sort(x);  % Sort x in ascending order
ysort = y(index);         % Sort y the same way as x
binEdges = [xsort(1:ceil(nValues/nBins):nValues) xsort(nValues)+1];

% Bin the data and get the averages as in previous post (using ysort instead of y):

[h,whichBin] = histc(xsort,binEdges);

for i = 1:nBins
    flagBinMembers = (whichBin == i);
    binMembers = ysort(flagBinMembers);
    binMean(i) = mean(binMembers);
end

Это должно дать вам ячейки, размер которых зависит от плотности данных.


ОБНОВЛЕНИЕ: Другая версия ...

Вот еще одна идея, которую я придумал после нескольких комментариев. С помощью этого кода вы устанавливаете порог (maxDelta) для разницы между соседними точками данных в x. Любые значения x, которые отличаются от их более крупного соседа на величину, большую или равную maxDelta, вынуждены находиться в их собственном бункере (все из-за их одиночества). Вы по-прежнему выбираете значение для nBins, но окончательное количество ячеек будет больше, чем это значение, когда точки распределения перемещаются в свои собственные ячейки.

% Start by assuming x and y are vectors of data:

maxDelta = 10; % Or whatever suits your data set!
nBins = 70;
nValues = length(x);
[xsort,index] = sort(x);  % Sort x in ascending order
ysort = y(index);         % Sort y the same way as x

% Create bin edges:

edgeIndex = false(1,nValues);
edgeIndex(1:ceil(nValues/nBins):nValues) = true;
edgeIndex = edgeIndex | ([0 diff(xsort)] >= maxDelta);
nBins = sum(edgeIndex);
binEdges = [xsort(edgeIndex) xsort(nValues)+1];

% Bin the data and get the y averages:

[h,whichBin] = histc(xsort,binEdges);

for i = 1:nBins
    flagBinMembers = (whichBin == i);
    binMembers = ysort(flagBinMembers);
    binMean(i) = mean(binMembers);
end

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

Я обдумывал это и попробую. У меня есть две проблемы: я боюсь потерять поведение на краях, где данные не очень плотные; И все же могут быть разделы, в которых мне нужна более высокая концентрация.

Alex R 09.01.2009 20:40

Я бы попробовал приведенный выше код с кучей разных значений для nBins. Если вы сделаете nBins больше, это приведет к уменьшению размера всех ваших корзин. Это даст вам более высокую концентрацию ящиков, в которых у вас много данных. Что касается «проигрыша по краям», я не совсем понимаю, что вы имеете в виду.

gnovice 09.01.2009 21:39

Рядом с минимальным и максимальным значениями координаты x гораздо меньше точек данных. Это отодвинет среднее значение от экстремумов, и если есть интересное поведение около экстремумов, оно может быть неочевидным.

Alex R 09.01.2009 22:20

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