Search code examples
matlabclassclassificationnon-linear-regression

Separate Double Moon Classification with A Line in Matlab


I have some Matlab code lines for drawing Double Moon Classification:

    function data=dm(r,w,ts,d)
clear all; close all;
if nargin<4, w=6;end
if nargin<3, r=10;end
if nargin<2, d=-4;end
if nargin < 1, ts=1000; end
ts1=10*ts;
done=0; tmp1=[];

while ~done, 
    tmp=[2*(r+w/2)*(rand(ts1,1)-0.5) (r+w/2)*rand(ts1,1)];
    tmp(:,3)=sqrt(tmp(:,1).*tmp(:,1)+tmp(:,2).*tmp(:,2)); 
    idx=find([tmp(:,3)>r-w/2] & [tmp(:,3)<r+w/2]);
    tmp1=[tmp1;tmp(idx,1:2)];
    if length(idx)>= ts, 
        done=1;
    end
end

data=[tmp1(1:ts,:) zeros(ts,1);
    [tmp1(1:ts,1)+r -tmp1(1:ts,2)-d ones(ts,1)]];
plot(data(1:ts,1),data(1:ts,2),'.r',data(ts+1:end,1),data(ts+1:end,2),'.b');
title(['Perceptron with the double-moon set at distance d = ' num2str(d)]),
axis([-r-w/2 2*r+w/2 -r-w/2-d r+w/2])
save dm r w ts d data;

Results: enter image description here

My question is how to put a line into the Double Moon Classification so that can separate both classification in Matlab code?


Solution

  • I have made a simulation of your problem and wrote a pragmatic solution based on the steps

    1. generates a grid of points fine enough(step size as small as possible)
    2. find which of these points are in the space between both points groups
    3. find which points have an equal distance to both groups
    4. plot points

    The main part (without my data generation code and the plot I did) of the code is

    PBlues = data(1:ts,:);
    PReds = data(ts+1:end,:);
    Xs = linspace( min(data(:,1)), max(data(:,1)), 100);
    Ys = linspace( min(data(:,2)), max(data(:,2)), 100);
    [Xs,Ys] = meshgrid( Xs, Ys);
    
    %% compute point relative distance to each point set (ble and red)
    bCouldbeInbetween = false(size(Xs));
    minDistsb = zeros(size(Xs));
    minDistsr = zeros(size(Xs));
    for p=1:numel(Xs)
        distb = sqrt( (Xs(p)- PBlues(:,1)).^2+(Ys(p)- PBlues(:,2)).^2);
        distr = sqrt( (Xs(p)- PReds(:,1)).^2+(Ys(p)- PReds(:,2)).^2);
        minDistsb(p) = min(distb);
        minDistsr(p) = min(distr);
        i = find(distb == minDistsb(p));
        j = find(distr == minDistsr(p));
        bCouldbeInbetween(p) = (sign(PBlues(i,1)-Xs(p)) ~= sign(PReds(j,1)-Xs(p))) || ...
            (sign(PBlues(i,2)-Ys(p)) ~= sign(PReds(j,2)-Ys(p)));
        if bCouldbeInbetween(p)
    
        end
    end
    % point distance difference to each point set
    DistDiffs = abs(minDistsb - minDistsr);
    % point with equal distance using proportional decision strategy
    bCandidates = DistDiffs./ max(minDistsb,minDistsr) < 0.05;
    medianLine = [Xs(bCandidates),Ys(bCandidates)];
    [~,I] = sort(medianLine(:,1));
    medianLine(:,1) = medianLine(I,1);
    medianLine(:,2) = medianLine(I,2);
    

    I hope this helps I have just made a submission which can be downloaded here: https://de.mathworks.com/matlabcentral/fileexchange/66618-linebetweentwopointsgroups-exchange--