كيفية تناسب منحنى سلس إلى البيانات الخاصة بي في "ص" ؟

StackOverflow https://stackoverflow.com/questions/3480388

  •  28-09-2019
  •  | 
  •  

سؤال

أحاول رسم منحنى سلس في R.لدي لعبة بسيطة البيانات:

> x
 [1]  1  2  3  4  5  6  7  8  9 10
> y
 [1]  2  4  6  8  7 12 14 16 18 20

الآن عندما مؤامرة مع معيار الأمر يبدو وعرة و منفعل ، بالطبع:

> plot(x,y, type='l', lwd=2, col='red')

كيف يمكنني جعل منحنى سلس بحيث 3 حواف مدورة باستخدام يقدر القيم ؟ أعرف أن هناك العديد من الأساليب لتناسب منحنى سلس ولكن لست متأكد أي واحد من شأنها أن تكون أكثر ملاءمة لهذا النوع من منحنى كيف يمكنك أن تكتب في R.

هل كانت مفيدة؟

المحلول

انا يعجبني loess() الكثير لتنعيم:

x <- 1:10
y <- c(2,4,6,8,7,12,14,16,18,20)
lo <- loess(y~x)
plot(x,y)
lines(predict(lo), col='red', lwd=2)

يحتوي كتاب Venables and Ripley's Mass على قسم كامل عن التنعيم الذي يغطي أيضًا الحشرات والحيوية - ولكن loess() هو مجرد مفضل للجميع.

نصائح أخرى

ربما smooth.spline هو خيار ، يمكنك تعيين معلمة تجانس (عادة بين 0 و 1) هنا

smoothingSpline = smooth.spline(x, y, spar=0.35)
plot(x,y)
lines(smoothingSpline)

يمكنك أيضًا استخدام التنبؤ على كائنات smooth.spline. تأتي الوظيفة مع قاعدة R ، انظر؟ Smooth.spline للحصول على التفاصيل.

من أجل الحصول عليها حقا smoooth ...

x <- 1:10
y <- c(2,4,6,8,7,8,14,16,18,20)
lo <- loess(y~x)
plot(x,y)
xl <- seq(min(x),max(x), (max(x) - min(x))/1000)
lines(xl, predict(lo,xl), col='red', lwd=2)

يستفيد هذا النمط من الكثير من النقاط الإضافية ويحصل على منحنى سلس للغاية. يبدو أيضًا أن النهج الذي يتطلبه GgPlot. إذا كان المستوى القياسي للنعومة جيدًا ، فيمكنك استخدامه فقط.

scatter.smooth(x, y)

ال qplot () الوظيفة في حزمة GGPLOT2 بسيطة للغاية للاستخدام وتوفر حلًا أنيقًا يتضمن نطاقات الثقة. على سبيل المثال،

qplot(x,y, geom='smooth', span =0.5)

ينتج عنهenter image description here

لوس هو نهج جيد للغاية ، كما قال ديرك.

خيار آخر هو استخدام Bezier Splines ، والتي قد تعمل في بعض الحالات بشكل أفضل من LOESS إذا لم يكن لديك العديد من نقاط البيانات.

هنا ستجد مثالاً: http://rosettacode.org/wiki/cubic_bezier_curves#r

# x, y: the x and y coordinates of the hull points
# n: the number of points in the curve.
bezierCurve <- function(x, y, n=10)
    {
    outx <- NULL
    outy <- NULL

    i <- 1
    for (t in seq(0, 1, length.out=n))
        {
        b <- bez(x, y, t)
        outx[i] <- b$x
        outy[i] <- b$y

        i <- i+1
        }

    return (list(x=outx, y=outy))
    }

bez <- function(x, y, t)
    {
    outx <- 0
    outy <- 0
    n <- length(x)-1
    for (i in 0:n)
        {
        outx <- outx + choose(n, i)*((1-t)^(n-i))*t^i*x[i+1]
        outy <- outy + choose(n, i)*((1-t)^(n-i))*t^i*y[i+1]
        }

    return (list(x=outx, y=outy))
    }

# Example usage
x <- c(4,6,4,5,6,7)
y <- 1:6
plot(x, y, "o", pch=20)
points(bezierCurve(x,y,20), type="l", col="red")

إجابات أخرى كلها جيدة النهج.ومع ذلك ، هناك عدد قليل من الخيارات الأخرى في R التي لم يتم ذكرها ، بما في ذلك lowess و approx, التي قد تعطي أفضل يناسب أو أداء أسرع.

مزايا أكثر أظهرت بسهولة مع بديل dataset:

sigmoid <- function(x)
{
  y<-1/(1+exp(-.15*(x-100)))
  return(y)
}

dat<-data.frame(x=rnorm(5000)*30+100)
dat$y<-as.numeric(as.logical(round(sigmoid(dat$x)+rnorm(5000)*.3,0)))

هنا هي البيانات مضافين مع السيني المنحنى الذي ولدت به:

Data

هذا النوع من البيانات هو شائع عند النظر في الثنائية السلوك بين السكان.على سبيل المثال, قد تكون هذه مؤامرة ما إذا كان أو لم يكن العميل بشراء شيء (ثنائي 1/0 على محور y) مقابل كمية الوقت الذي يقضيه على الموقع (x-axis).

عدد كبير من النقاط تستخدم لإظهار أفضل أداء الاختلافات من هذه الوظائف.

Smooth, spline, ، smooth.spline كل إنتاج رطانة على مجموعة بيانات من هذا القبيل مع أي مجموعة من المعلمات حاولت ، ربما بسبب ميلها إلى خريطة كل نقطة التي لا تعمل صاخبة البيانات.

على loess, lowess, ، approx وظائف جميع تنتج النتائج قابلة للاستخدام ، على الرغم بالكاد على approx.هذا هو رمز لكل بخفة باستخدام معايير محسنة:

loessFit <- loess(y~x, dat, span = 0.6)
loessFit <- data.frame(x=loessFit$x,y=loessFit$fitted)
loessFit <- loessFit[order(loessFit$x),]

approxFit <- approx(dat,n = 15)

lowessFit <-data.frame(lowess(dat,f = .6,iter=1))

و النتائج:

plot(dat,col='gray')
curve(sigmoid,0,200,add=TRUE,col='blue',)
lines(lowessFit,col='red')
lines(loessFit,col='green')
lines(approxFit,col='purple')
legend(150,.6,
       legend=c("Sigmoid","Loess","Lowess",'Approx'),
       lty=c(1,1),
       lwd=c(2.5,2.5),col=c("blue","green","red","purple"))

Fits

كما ترون ، lowess تنتج بالقرب مثاليا الأصلي توليد منحنى. Loess قريب ولكن تجارب غريبة الانحراف في كل من ذيول.

على الرغم من أن البيانات سوف تكون مختلفة جدا, لقد وجدت أن مجموعات بيانات أخرى تؤدي على نحو مماثل ، مع كل loess و lowess قادرة على إنتاج نتائج جيدة.الاختلافات تصبح أكثر أهمية عند النظر في المعايير:

> microbenchmark::microbenchmark(loess(y~x, dat, span = 0.6),approx(dat,n = 20),lowess(dat,f = .6,iter=1),times=20)
Unit: milliseconds
                           expr        min         lq       mean     median        uq        max neval cld
  loess(y ~ x, dat, span = 0.6) 153.034810 154.450750 156.794257 156.004357 159.23183 163.117746    20   c
            approx(dat, n = 20)   1.297685   1.346773   1.689133   1.441823   1.86018   4.281735    20 a  
 lowess(dat, f = 0.6, iter = 1)   9.637583  10.085613  11.270911  11.350722  12.33046  12.495343    20  b 

Loess بطيئة للغاية ، مع 100x طالما approx. Lowess تنتج نتائج أفضل من approx, في حين لا تزال تعمل إلى حد ما بسرعة (15 مرة أسرع من اللوس).

Loess كما تزداد مستنقع عدد من النقاط يزيد ، أصبحت غير صالحة للاستعمال حوالي 50 ، 000.

تحرير:بحوث إضافية تبين أن loess يعطي أفضل يناسب بعض البيانات.إذا كنت تتعامل مع مجموعة صغيرة من البيانات أو الأداء لا اعتبار حاول كل الوظائف و مقارنة النتائج.

في GGPLOT2 ، يمكنك القيام بالأسلحة بعدة طرق ، على سبيل المثال:

library(ggplot2)
ggplot(mtcars, aes(wt, mpg)) + geom_point() +
  geom_smooth(method = "gam", formula = y ~ poly(x, 2)) 
ggplot(mtcars, aes(wt, mpg)) + geom_point() +
  geom_smooth(method = "loess", span = 0.3, se = FALSE) 

enter image description here enter image description here

لم أر هذه الطريقة معروضة ، لذا إذا كان شخص آخر يتطلع إلى القيام بذلك ، فقد وجدت أن وثائق GGPLOT تقترح تقنية لاستخدام gam الطريقة التي أنتجت نتائج مماثلة ل loess عند العمل مع مجموعات البيانات الصغيرة.

library(ggplot2)
x <- 1:10
y <- c(2,4,6,8,7,8,14,16,18,20)

df <- data.frame(x,y)
r <- ggplot(df, aes(x = x, y = y)) + geom_smooth(method = "gam", formula = y ~ s(x, bs = "cs"))+geom_point()
r

أولاً مع طريقة LOESS وصيغة السيارات الثانية مع طريقة GAM مع الصيغة المقترحة

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top