Как найти наиболее подходящий круг/эллипс с помощью R?

Я читал о нескольких методах сопоставления круга с данными (например, это). Я хотел бы посмотреть, как методы работают с реальными данными, и подумал об использовании R для этого. Я попытался найти в rseek пакеты, которые могут помочь в этом, но ничего полезного не нашел.

Итак, существуют ли пакеты, которые помогают легко вычислить наиболее подходящий круг для заданного набора данных (аналогично тому, как lm() подгонит линейную модель к набору данных)? Иначе как можно было бы выполнить такую ​​задачу в R?


person mauna    schedule 27.11.2014    source источник
comment
взгляните на эту статью onthelambda.com/2014/07/24/ И это блестящее приложение tonyfischetti.shinyapps.io/InteractiveLogisticRegression   -  person Pork Chop    schedule 27.11.2014
comment
Методы, описанные в статье, которую вы цитируете, не выглядят слишком сложными для реализации. Есть только три параметра (x, y, r), и метод с решениями в закрытой форме даже не нуждается в оптимизации. Попробуйте программировать их, вы узнаете много навыков R. Сделать пакет...   -  person Spacedman    schedule 27.11.2014
comment
Поскольку эллипсы не являются однозначными, вы не можете использовать инструменты линейной (или даже нелинейной) подгонки, поскольку они почти всегда предполагают однозначные функции. Таким образом, делайте то, что говорит @Spacedman. Черт возьми, если вы этого не сделаете, я сделаю это только потому, что это выглядит весело :-)   -  person Carl Witthoft    schedule 27.11.2014
comment
Голосование за повторное открытие, потому что я не вижу, чтобы вычисление ограничивающего эллипса действительно соответствовало этому вопросу. Даже если вы вычислите 50% ограничивающий эллипс, не сразу ясно, что он окажется (например, методом наименьших квадратов) наилучшим образом подходящим для самих точек.   -  person Carl Witthoft    schedule 04.12.2014


Ответы (2)


Вот довольно наивная реализация функции, которая минимизирует SS(a,b,r) из этой статьи:

fitSS <- function(xy,
                  a0=mean(xy[,1]),
                  b0=mean(xy[,2]),
                  r0 = mean(sqrt((xy[,1]-a0)^2 + (xy[,2]-b0)^2)),
                  ...){
    SS <- function(abr){
        sum((abr[3] - sqrt((xy[,1]-abr[1])^2 + (xy[,2]-abr[2])^2))^2)
    }
    optim(c(a0,b0,r0), SS, ...)
}

Я написал пару вспомогательных функций для генерации случайных данных о кругах и построения кругов. Следовательно:

> xy = sim_circles(10)
> f = fitSS(xy)

Значение fit$par представляет собой вектор xcenter, ycenter, радиуса.

> plot(xy,asp=1,xlim=c(-2,2),ylim=c(-2,2))
> lines(circlexy(f$par))

точки и окружность

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

Код для построения и создания кругов выглядит следующим образом:

circlexy <- function(xyr, n=180){
    theta = seq(0,2*pi,len=n)
    cbind(xyr[1] + xyr[3]*cos(theta),
          xyr[2] + xyr[3]*sin(theta)
          )
}
sim_circles <- function(n,x=0,y=0,r=1,sd=0.05){
    theta = runif(n, 0, 2*pi)
    r = r + rnorm(n, mean=0, sd=sd)
    cbind(x + r*cos(theta),
          y + r*sin(theta)
      )
}
person Spacedman    schedule 27.11.2014
comment
Эй, я думал, ты сказал SO написать пакет :-) - person Carl Witthoft; 27.11.2014
comment
Знал, что найду это где-нибудь (наконец-то): plotrix::draw.circle похоже делает то же, что и твой lines(circlexy(foo)). - person Carl Witthoft; 01.12.2014
comment
Я полагаю, что где-то в sim_circles есть runif(n. -pi, pi). Возможно function(n=10, radius=1, var=radius/10){angle=runif(n. -pi, pi);list(x=radius*sin(angle)+var*runif(n), y=radius*cos(angle)+var*runif(n))} - person IRTFM; 12.12.2014
comment
какая библиотека требуется для 'xy = sim_circles(10)', набор данных недоступен?? и как получить из него радиус - person Kumar; 26.02.2020

Взгляните сюда: колонка R-blogger написал код для эллипсов и кругов. Его код, который я не буду публиковать здесь, основан на предыдущей работе, выполненной Радимом Халиржем и Яном Флюссером в Matlab. Его код включает (прокомментирован) исходные строки Matlab для сравнения.

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

http://www.emis.de/journals/BBMS/Bulletin/sup962/gander.pdf

http://ralph.cs.cf.ac.uk/papers/Geometry/fit.pdf

http://autotrace.sourceforge.net/WSCG98.pdf

Последующее редактирование: я запустил код Spacedman со связанным R-кодом для подгонки эллипсов, используя в качестве входных данных тот же «зашумленный» набор из 1e5 точек на окружности. Результаты:

testcircle<-create.test.ellipse(Rx=200,Ry=200,Rot=.56,Noise=5.5,leng=100000)
 dim(testcircle)
[1] 100000      2

microbenchmark(fitSS(testcircle),fit.ellipse(testcircle))
Unit: milliseconds
                    expr       min        lq    median        uq       max
       fitSS(testcircle) 649.98245 704.05751 731.61282 787.84212 2053.7096
 fit.ellipse(testcircle)  25.74518  33.87718  38.87143  95.23499  256.2475
 neval
   100
   100

Для справки, выходные данные двух подгоночных функций были следующими:

От SSfit, список

ssfit
$par
[1] 249.9530 149.9927 200.0512

$value
[1] 185.8195

$counts
function gradient 
     134       NA 

$convergence
[1] 0

$message
NULL

Из fit.ellipse получаем

ellfit
$coef
            a             b             c             d             e 
-7.121109e-01 -1.095501e-02 -7.019815e-01  3.563866e+02  2.136497e+02 
            f 
-3.195427e+04 

$center
       x        y 
249.0769 150.2326 

$major
[1] 201.7601

$minor
[1] 199.6424

$angle
[1] 0.412268

Вы можете видеть, что коэффициенты эллиптического уравнения близки к нулю для членов, которые «отклоняются» от окружности; построение двух результатов дает почти неразличимые кривые.

person Carl Witthoft    schedule 11.12.2014