আর-তে আমার ডেটাতে কীভাবে মসৃণ বাঁকানো যায়?


88

আমি একটি মসৃণ বক্ররেখা আঁকতে চেষ্টা করছি 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


4
এটি সম্পূর্ণরূপে নির্ভর করে আপনার ডেটা কী এবং আপনি কেন এটি মসৃণ করছেন! তথ্য গণনা করা হয়? ঘনত্ব? পরিমাপ? কোন ধরণের পরিমাপ ত্রুটি থাকতে পারে? আপনার গ্রাফটি দিয়ে আপনি কোন গল্পটি পাঠকদের বলার চেষ্টা করছেন? এই সমস্ত সমস্যা আপনাকে এবং কীভাবে আপনার ডেটা মসৃণ করা উচিত তা প্রভাবিত করে।
হারলান

এগুলি পরিমাপ করা ডেটা। এক্স মানগুলিতে 1, 2, 3, ..., 10 কিছু সিস্টেম 2, 4, 6, ..., 20 ত্রুটি করেছে। এই স্থানাঙ্কগুলি সম্ভবত ফিটিং অ্যালগরিদম দ্বারা পরিবর্তন করা উচিত নয়। তবে আমি অনুপস্থিত x মানগুলিতে ত্রুটিগুলি (y) অনুকরণ করতে চাই, উদাহরণস্বরূপ তথ্যগুলিতে f (4) = 8 এবং f (5) = 7, সুতরাং সম্ভবত f (4.5) 7 এবং 8 এর মধ্যে এমন কিছু যা ব্যবহার করে কিছু বহুবচন বা অন্যান্য স্মুথিং।
ফ্র্যাঙ্ক

4
সেক্ষেত্রে এক্স এর প্রতিটি মানের জন্য একক ডেটা পয়েন্ট সহ, আমি মোটেও মসৃণ করব না। আমার পরিমাপ করা ডেটা পয়েন্টগুলির জন্য আমার কাছে কেবল বড় বিন্দু থাকবে, পাতলা রেখাগুলি সংযুক্ত করে। অন্য যে কোনও কিছুই দর্শকদের পরামর্শ দেয় যে আপনি নিজের ডেটা সম্পর্কে আপনার চেয়ে বেশি জানেন।
হারলান

আপনি এই উদাহরণের জন্য সঠিক হতে পারে। এটি কীভাবে করবেন তা জেনে রাখা ভাল, এবং আমি পরে এটি অন্য কোনও ডেটাতে ব্যবহার করতে চাইব, উদাহরণস্বরূপ আপনার যদি হাজার হাজার খুব স্পাইকি ডেটা পয়েন্ট থাকে তবে এই ধরণের উপরের দিকে যেতে পারে তবে সাধারণ প্রবণতা রয়েছে উদাহরণস্বরূপ, এখানে যেমন উপরের দিকে যাওয়া: প্লট (seq (1,100) + রানিফ (100, 0,10), টাইপ = 'l')।
ফ্রাঙ্ক

এখানে একটি ভাল উপায়, stats.stackexchange.com/a/278666/134555
বেল্টার

উত্তর:


105

আমি 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)

ভেনেবলস এবং রিপলির এমএএসএস বইয়ের স্মুথিংয়ের পুরো বিভাগ রয়েছে যা স্প্লাইজ এবং বহুবর্ষগুলিও কভার করে - তবে loess()এটি সবার পছন্দের বিষয়।


আপনি কীভাবে এই ডেটা প্রয়োগ করবেন? আমি নিশ্চিত না কীভাবে কারণ এটি একটি সূত্র প্রত্যাশা করে। ধন্যবাদ!
ফ্রাঙ্ক

7
যেমন আমি আপনাকে উদাহরণে দেখিয়েছি যখন xএবং yযদি দৃশ্যমান ভেরিয়েবল হয়। যদি সেগুলি নামের কোনও ডেটাফ্রেমের কলাম হয় foo, আপনি কলটিতে একটি data=fooবিকল্প যুক্ত করুন loess(y ~ x. data=foo)- ঠিক যেমন আর এর অন্যান্য সমস্ত মডেলিং ফাংশনগুলির মতো
ডার্ক এডেলবুয়েটেল

4
আমি supsmu()আউট অফ দ্য বাক্স মসৃণ হিসাবে পছন্দ করি
এপিসকেপ

4
এক্স একটি তারিখের প্যারামিটার হলে কীভাবে কাজ করবে? যদি আমি এমন কোনও ডেটা টেবিল দিয়ে চেষ্টা করি যা কোনও সংখ্যার তারিখের মানচিত্র করে (ব্যবহার করে lo <- loess(count~day, data=logins_per_day) ) আমি এটি পাই:Error: NA/NaN/Inf in foreign function call (arg 2) In addition: Warning message: NAs introduced by coercion
উইশার্ট আক্কর্মান

4
@ উইচার্ট আক্কর্মান মনে হয় যে তারিখের ফর্ম্যাটটি বেশিরভাগ আর ফাংশন দ্বারা ঘৃণা করা হয়। আমি সাধারণত নতুন $ তারিখ = as.numeric (নতুন $ তারিখ, as. তারিখ ("2015-01-01"), ইউনিট = "দিন") এর মতো কিছু করি ( স্টেট.টিজ.সিচ / পিপারমেল / আর- তে বর্ণিত হিসাবে) সহায়তা / 2008-মে / 162719.html )
কার্যকলাপ হ্রাস

59

সম্ভবত স্মাইল.স্প্লাইন একটি বিকল্প, আপনি এখানে স্মুথিং প্যারামিটার সেট করতে পারেন (সাধারণত 0 এবং 1 এর মধ্যে)

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

আপনি মসৃণ.স্প্লাইন বস্তুগুলির উপর পূর্বাভাসও ব্যবহার করতে পারেন। ফাংশনটি বেস বেসের সাথে আসে, দেখুন বিস্তারিত জন্য মসৃণ.স্প্লাইন।


27

এটি সত্যই স্মুথ পেতে ...

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)

25

qplot () ggplot2 প্যাকেজের মধ্যে ফাংশন ব্যবহার করতে খুবই সহজ এবং একটি মার্জিত সমাধান আস্থা ব্যান্ড অন্তর্ভুক্ত প্রদান করে। এই ক্ষেত্রে,

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

উত্পাদন এখানে চিত্র বর্ণনা লিখুন


প্রশ্নটি ফাঁকি দেওয়ার জন্য নয়, তবে সন্দেহজনক হওয়ার জন্য আমি ধীরে ধীরে ফিট করার জন্য আর ^ 2 (বা সিউডো আর ^ 2) এর মান খুঁজে পাই। একটি মসৃণ ব্যান্ডউইথের হ্রাস হওয়ায় অগত্যা ডেটার আরও কাছে ফিট হয়ে যাবে।
আন্ডারমিনার

এটি সহায়তা করতে পারে: স্ট্যাকওভারফ্লো.com
প্রশ্নগুলি

হুম, আমি আপনার কোডটি শেষ পর্যন্ত আর 3.3.1 এ চালাতে পারিনি। আমি ggplot2সফলভাবে ইনস্টল করেছি বু চলতে পারে না qplotকারণ এটি ডেবিয়ান 8.5-তে ফাংশনটি খুঁজে পায় না।
লিও লোপোল্ড হার্টজ 준영

14

ডার্ক যেমন বলেছিলেন তেমন হ্রাস একটি খুব ভাল পদ্ধতি।

আরেকটি বিকল্প বেজিয়ার স্প্লাইস ব্যবহার করছে, যা আপনার কাছে অনেকগুলি ডেটা পয়েন্ট না থাকলে কিছু ক্ষেত্রে 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")

11

অন্যান্য উত্তরগুলি সমস্ত ভাল পন্থা। তবে আর-তে আরও কয়েকটি অপশন রয়েছে যা উল্লেখ করা হয়নি lowessএবং এর সাথে approxআরও ভাল ফিট বা দ্রুত পারফরম্যান্স দিতে পারে।

বিকল্প ডেটাসেটের সাহায্যে সুবিধাগুলি আরও সহজেই প্রদর্শিত হয়:

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)))

সিগময়েড বক্ররেখা যা এটি উত্পন্ন করে তা এখানে দেওয়া তথ্য রয়েছে:

ডেটা

জনসংখ্যার মধ্যে বাইনারি আচরণ দেখার সময় এই ধরণের ডেটা সাধারণ। উদাহরণস্বরূপ, কোনও গ্রাহক সাইটে কিছু পরিমাণ সময় (x- অক্ষ) ব্যয় করেছেন তার বিপরীতে কোনও কিছু (y- অক্ষের উপর বাইনারি 1/0) কিনেছিল কিনা তা এই প্লট হতে পারে।

এই ফাংশনগুলির পারফরম্যান্স পার্থক্যগুলি আরও ভালভাবে প্রদর্শন করতে প্রচুর পরিমাণে পয়েন্ট ব্যবহার করা হয়।

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"))

ফিট

আপনি দেখতে পাচ্ছেন, 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দ্রুত চলার সময় (লসের চেয়ে 15x দ্রুত) এর চেয়ে ভাল ফলাফল তৈরি করে ।

Loess পয়েন্ট সংখ্যা বৃদ্ধি পাওয়ায় ক্রমশ বোকা হয়ে যায়, প্রায় ৫০,০০০ অব্যবহৃত হয়ে পড়ে।

সম্পাদনা: অতিরিক্ত গবেষণা দেখায় যে loessনির্দিষ্ট ডেটাসেটের জন্য আরও ভাল ফিট করে। আপনি যদি একটি ছোট ডেটাसेट নিয়ে কাজ করছেন বা পারফরম্যান্স বিবেচনা না করে থাকেন তবে উভয় ফাংশন চেষ্টা করে ফলাফলের তুলনা করুন।


8

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) 

এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন


আরও প্রক্রিয়াগুলির জন্য এই জিওম_স্মোথ ব্যবহার করা কি সম্ভব?
বেন

3

আমি এই পদ্ধতিটি দেখায়নি, তাই অন্য কেউ যদি এটির সন্ধান করে তবে আমি দেখতে পেলাম যে 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

প্রথমে লোস পদ্ধতি এবং অটো সূত্রে দ্বিতীয় প্রস্তাবিত সূত্রের সাথে গ্যাম পদ্ধতিটি

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.