วิธีทำนายหมายเลขถัดไปถัดไปตามลำดับใน R

ฉันต้องการสร้างฟังก์ชันเพื่อทำนายตัวเลขถัดไปในลำดับของลำดับทางเรขาคณิตเช่นสิ่งเหล่านี้หรือตัวคูณที่ n อื่นๆ:

1 2 4 8 16 32 64
2 4 8 16 32 64 128
3 6 12 24 48 96 192

1 3 9 27 81 243 729
2 6 18 54 162 486 1458
3 9 27 81 243 729 2187

ฉันได้ลองใช้วิธีนี้แล้ว (วิธีรับหมายเลขถัดไป ลำดับใน R) แต่ดูเหมือนว่าจะใช้ได้กับลำดับเชิงเส้นเท่านั้น นอกจากนี้ จะใช้คำสั่ง IF เพื่อตรวจสอบว่าลำดับนั้นเป็นลำดับเรขาคณิตและไม่ใช่ลำดับประเภทอื่น ๆ เช่นเชิงเส้นได้อย่างไร


person Bethan Huish    schedule 25.08.2019    source แหล่งที่มา


คำตอบ (2)


สำหรับอนุกรมเรขาคณิต อัตราส่วนของค่าที่ต่อเนื่องกันจะเป็นค่าคงที่ ดังนั้นการคูณอัตราส่วนนั้นด้วยค่าปัจจุบันจะได้ค่าถัดไป

เพื่อตรวจสอบว่าอนุกรมเป็นเรขาคณิตหรือไม่ เราสามารถหาอัตราส่วนของคู่ค่าแต่ละคู่ที่ต่อเนื่องกันในอนุกรมนั้น และหากอัตราส่วนเหล่านั้นเท่ากันทั้งหมด แสดงว่าอนุกรมนั้นเป็นเรขาคณิต เนื่องจากนั่นเทียบเท่ากับการตรวจสอบว่าความแปรปรวนเป็นศูนย์หรือไม่ เราจึงทำได้ง่ายๆ โดยใช้ var เนื่องจากเลขคณิตทศนิยมไม่แม่นยำ เราจึงตรวจสอบว่าความแปรปรวนน้อยกว่า eps หรือไม่

โปรดทราบว่า is.geo ส่งคืน NA สำหรับชุดข้อมูลความยาว 1 หรือ 2 และ nextValue ส่งคืน NA หาก is.geo ไม่ส่งคืน TRUE

nextValue <- function(x) {
  if (!isTRUE(is.geo(x))) NA
  else {
    y <- tail(x, 2)
    y[2]^2 / y[1]
  }
}

is.geo <- function(x, eps = 1e-5) var(x[-1] / x[-length(x)]) < eps

ทดสอบ

การใช้ m ที่กำหนดไว้ในหมายเหตุในตอนท้ายทำให้เราสามารถผนวกค่าถัดไปเป็นคอลัมน์ใหม่ได้:

cbind(m, apply(m, 1, nextValue))

ให้:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]    1    2    4    8   16   32   64  128
[2,]    2    4    8   16   32   64  128  256
[3,]    3    6   12   24   48   96  192  384
[4,]    1    3    9   27   81  243  729 2187
[5,]    2    6   18   54  162  486 1458 4374
[6,]    3    9   27   81  243  729 2187 6561

นอกจากนี้เรายังสามารถทดสอบแต่ละแถวของ m เพื่อตรวจสอบว่าเป็นเรขาคณิตหรือไม่:

apply(m, 1, is.geo)
## [1] TRUE TRUE TRUE TRUE TRUE TRUE

is.geo(c(1, 2, 4, 12))
## [1] FALSE

ใช้ lm

ถ้าตามวิธีของลิงค์ที่แสดงในคำถามหมายถึงการใช้ lm เราก็สามารถใช้ lm ได้ ถ้าอนุกรมนั้นเป็นบวกอย่างเคร่งครัด โดยสังเกตว่า log ของอนุกรมเรขาคณิตนั้นเป็นเลขคณิต ดังนั้น เราจึงสามารถใส่บันทึกของอนุกรมให้เป็น 1 ได้ 2, 3, ... . ถ้าค่าคงเหลือเป็นศูนย์ซึ่งเกิดขึ้นเมื่อความเบี่ยงเบนเป็นศูนย์ ก็จะเป็นไปตามนี้

fit <- function(x) {
    ix <- seq_along(x)
    lm(log(x) ~ ix)
}

nextValue2 <- function(x) {
  if (!isTRUE(is.geo2(x))) NA
  else exp( predict(fit(x), list(ix = length(x) + 1)) )
}

is.geo2 <- function(x, eps = 1.e-5) {
  if (length(x) <= 2) NA
  else deviance(fit(x)) < eps
}

บันทึก

m <- matrix(c(1L, 2L, 3L, 1L, 2L, 3L, 2L, 4L, 6L, 3L, 6L, 9L, 4L, 
8L, 12L, 9L, 18L, 27L, 8L, 16L, 24L, 27L, 54L, 81L, 16L, 32L, 
48L, 81L, 162L, 243L, 32L, 64L, 96L, 243L, 486L, 729L, 64L, 128L, 
192L, 729L, 1458L, 2187L), 6)
person G. Grothendieck    schedule 25.08.2019
comment
ด้วยความอยากรู้อยากเห็น !isTRUE แตกต่างจาก isFALSE หรือไม่ - person NelsonGon; 25.08.2019
comment
พวกเขาจะแตกต่างกันถ้าอาร์กิวเมนต์เป็น NA !isTRUE(NA) เป็น TRUE แต่ ' isFALSE(NA) เป็น FALSE - person G. Grothendieck; 25.08.2019
comment
@ G. Grothendieck เราสามารถทำเช่นเดียวกันสำหรับอนุกรมเรขาคณิตย้อนกลับเช่น (256 128 64 32 16)? - person Bethan Huish; 26.08.2019
comment
นั่นยังคงเป็นเรขาคณิต - person G. Grothendieck; 26.08.2019
comment
@จี Grothendieck ในที่สุดฉันก็มีโอกาสทดสอบวิธีแก้ปัญหาของคุณ เมื่อรันฟังก์ชัน is.geo บนลำดับเช่น (90,93,96,99,102,105) มันจะคืนค่า TRUE แม้ว่าจะเป็นลำดับเชิงเส้นก็ตาม - person Bethan Huish; 26.08.2019
comment
ใช้ค่าที่น้อยกว่าสำหรับ eps เช่น is.geo(x, eps = 1e-10) - person G. Grothendieck; 27.08.2019

หากเป็นเพียงลำดับเรขาคณิต คุณสามารถค้นหาตัวประกอบได้ด้วย factor <- seq[2]/seq[1] หากคุณไม่ทราบประเภทของลำดับ คุณจะไม่สามารถค้นหาสูตรในกรณีทั่วไปได้

อย่างไรก็ตาม คุณทราบสูตรทั่วไปของลำดับ ดังนั้นคุณจึงมีตัวแปรบางตัวที่สามารถคำนวณได้จากเทอมบางเทอมของลำดับ ตัวอย่างเช่น สำหรับลำดับเรขาคณิต เรารู้ว่า a_n = factor * a_{n-1} ดังนั้น โดยการแทนที่พจน์บางพจน์ของลำดับ เราก็สามารถหาตัวประกอบได้ที่นี่ เป็นสมการตัวแปรหนึ่ง เราพูดได้เลยว่า factor = a_n / a_{n-1}

อีกตัวอย่างหนึ่ง สมมติว่าเรารู้ว่าสูตรลำดับชอบ a_n = alpha * a_{n-1} + beta * a_{n-2} ตอนนี้ เราสามารถหา alpha และ beta ได้โดยใช้เงื่อนไขสี่ประการของลำดับ (a_1, a_2, a_3 และ `a_4)

ในกรณีสุดท้าย คุณสามารถมีรูปแบบทั่วไปของลำดับโดยไม่มีตัวแปรใดๆ เช่น a_n = a_{n-1} + n หากคุณมีสิ่งนี้ คุณสามารถทำนายเทอมสุดท้ายได้อย่างง่ายดายโดยอิงจากเทอมสุดท้ายของลำดับที่ต้องการ

person OmG    schedule 25.08.2019
comment
ขอบคุณมาก ในกรณีนี้ ฉันคิดว่าบางสิ่งที่เรียบง่ายอย่าง geoSolve ‹- function(){ factor ‹- seq[2]/seq[1]; ส่วนท้าย (seq, n=1) * ปัจจัย; } สามารถให้วิธีแก้ปัญหาได้ใช่ไหม? - person Bethan Huish; 25.08.2019
comment
@BethanHuish ใช่แล้ว คุณต้องเพิ่มผลลัพธ์สุดท้ายลงใน data frame เพื่อให้ getNext ทำงานได้อย่างถูกต้อง - person OmG; 25.08.2019
comment
ขออภัย ฉันไม่ค่อยแน่ใจว่าฉันเข้าใจสิ่งที่คุณหมายถึง ฉันใช้โค้ดนี้แล้วและดูเหมือนว่าจะทำงานได้ดี มีบางอย่างที่ฉันขาดหายไปหรือไม่? - person Bethan Huish; 25.08.2019
comment
@BethanHuish ใช่แล้ว ถูกต้อง. อย่างไรก็ตาม คุณต้องเพิ่มผลลัพธ์สุดท้ายลงในลำดับเพื่อให้การทำนายครั้งต่อไปถูกต้อง - person OmG; 25.08.2019
comment
อ่า โอเค ฉันเข้าใจแล้ว - person Bethan Huish; 26.08.2019