Cara memprediksi angka berikutnya secara berurutan di R

Saya ingin membuat fungsi untuk memprediksi bilangan berikutnya dalam barisan barisan geometri seperti ini atau kelipatan ke-n lainnya:

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

Saya sudah mencoba menggunakan metode ini (Cara mendapatkan nomor berikutnya di sequence di R) namun sepertinya hanya berfungsi dengan sequence linear. Juga bagaimana pernyataan IF dapat diimplementasikan untuk memeriksa apakah barisan tersebut merupakan barisan geometri dan bukan jenis barisan lainnya misalnya linier?


person Bethan Huish    schedule 25.08.2019    source sumber


Jawaban (2)


Untuk deret geometri, rasio nilai-nilai yang berurutan adalah konstan sehingga mengalikan rasio tersebut dengan nilai saat ini akan menghasilkan nilai berikutnya.

Untuk memeriksa apakah deret tersebut geometris, kita dapat mengambil rasio dari setiap pasangan nilai yang berurutan dalam deret tersebut dan jika rasio tersebut semuanya sama maka deret tersebut adalah deret geometri. Karena ini setara dengan memeriksa apakah variansnya nol, kita dapat melakukannya dengan mudah menggunakan var. Karena aritmatika floating point tidak eksak, kami memeriksa apakah variansnya kurang dari eps .

Perhatikan bahwa is.geo mengembalikan NA untuk rangkaian dengan panjang 1 atau 2 dan nextValue mengembalikan NA jika is.geo tidak mengembalikan 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

Tes

Menggunakan m yang didefinisikan dalam Catatan di bagian akhir, kita dapat menambahkan nilai berikutnya sebagai kolom baru:

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

memberi:

     [,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

Kita juga dapat menguji setiap baris m untuk memeriksa apakah berbentuk geometris:

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

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

Menggunakan lm

Jika dengan metode tautan yang ditunjukkan pada pertanyaan berarti menggunakan lm maka kita dapat menggunakan lm jika deret tersebut benar-benar positif dengan mencatat bahwa log dari deret geometri tersebut adalah aritmatika sehingga kita dapat memasukkan log deret tersebut ke 1, 2, 3, ... . Jika residunya nol yang terjadi ketika penyimpangannya nol maka memenuhi hal tersebut.

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
}

Catatan

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
Hanya ingin tahu, apakah !isTRUE berbeda dengan isFALSE? - person NelsonGon; 25.08.2019
comment
Beda kalau argumentasinya NA. !isTRUE(NA) BENAR tetapi` isFALSE(NA) SALAH. - person G. Grothendieck; 25.08.2019
comment
@ G. Grothendieck apakah kita juga dapat melakukan hal yang sama untuk deret geometri terbalik mis. (256 128 64 32 16)? - person Bethan Huish; 26.08.2019
comment
Itu masih geometris - person G. Grothendieck; 26.08.2019
comment
@G. Grothendieck jadi saya akhirnya mendapat kesempatan untuk menguji solusi Anda, ketika menjalankan fungsi is.geo pada urutan seperti (90,93,96,99,102,105) ia mengembalikan TRUE meskipun merupakan urutan linier - person Bethan Huish; 26.08.2019
comment
gunakan nilai yang lebih kecil untuk eps, mis. is.geo(x, eps = 1e-10) - person G. Grothendieck; 27.08.2019

Jika hanya barisan geometri, faktornya dapat dicari dengan factor <- seq[2]/seq[1]. Jika Anda tidak mengetahui jenis barisan, tidak mungkin menemukan rumus dalam kasus umum.

Namun, Anda mengetahui rumus umum barisan tersebut, sehingga Anda memiliki beberapa variabel yang dapat dihitung dengan beberapa suku barisan tersebut. Misalnya untuk barisan geometri kita mengetahui bahwa a_n = factor * a_{n-1}. Oleh karena itu, dengan mengganti beberapa suku suatu barisan, kita dapat mencari faktornya di sini. Ini adalah satu persamaan variabel. Kita dapat mengatakan bahwa factor = a_n / a_{n-1}.

Contoh lain, misalkan kita mengetahui rumus barisan seperti a_n = alpha * a_{n-1} + beta * a_{n-2}. Sekarang, kita dapat mencari alpha dan beta menggunakan empat suku barisan tersebut (a_1, a_2, a_3, dan `a_4).

Untuk kasus terakhir, Anda dapat memiliki bentuk umum barisan tanpa variabel apa pun seperti a_n = a_{n-1} + n. Jika sudah memilikinya, Anda dapat memprediksi suku terakhir dengan mudah berdasarkan suku terakhir yang diperlukan dari barisan tersebut.

person OmG    schedule 25.08.2019
comment
Terima kasih banyak, dalam hal ini saya memikirkan sesuatu yang sederhana seperti geoSolve ‹- function(){ factor ‹- seq[2]/seq[1]; ekor(seq, n=1) * faktor; } bisa kasih solusinya kan? - person Bethan Huish; 25.08.2019
comment
@BethanHuish ya, agaknya. Anda perlu menambahkan hasil terakhir ke bingkai data agar getNext berfungsi dengan baik. - person OmG; 25.08.2019
comment
maaf saya tidak begitu yakin saya mengerti maksud Anda, saya telah menjalankan kode ini dan sepertinya berfungsi dengan baik. Apakah ada sesuatu yang saya lewatkan? - person Bethan Huish; 25.08.2019
comment
@BethanHuish Ya. Itu benar. Namun, Anda perlu menambahkan hasil terakhir ke urutannya, untuk mendapatkan prediksi berikutnya yang benar. - person OmG; 25.08.2019
comment
ah baiklah aku mengerti - person Bethan Huish; 26.08.2019