Seringkali, Anda memiliki ide tentang bentuk fungsi untuk sebuah model dan Anda perlu memilih parameter yang akan membuat fungsi model cocok untuk observasi. Proses pemilihan parameter untuk mencocokkan pengamatan disebut model fitting .

Sebagai ilustrasi, data dalam file “utilities.csv” mencatat suhu rata-rata setiap bulan (dalam derajat F) serta penggunaan gas alam bulanan (dalam kaki kubik, ccf). Ada, seperti yang Anda duga, hubungan yang kuat antara keduanya.

Sebagai ilustrasi, data dalam file “utilities.csv” mencatat suhu rata-rata setiap bulan (dalam derajat F) serta penggunaan gas alam bulanan (dalam kaki kubik, ccf). Ada, seperti yang Anda duga, hubungan yang kuat antara keduanya.

library(mosaicCalc)
## Loading required package: mosaic
## Registered S3 method overwritten by 'mosaic':
##   method                           from   
##   fortify.SpatialPolygonsDataFrame ggplot2
## 
## The 'mosaic' package masks several functions from core packages in order to add 
## additional features.  The original behavior of these functions should not be affected by this.
## 
## Attaching package: 'mosaic'
## The following objects are masked from 'package:dplyr':
## 
##     count, do, tally
## The following object is masked from 'package:Matrix':
## 
##     mean
## The following object is masked from 'package:ggplot2':
## 
##     stat
## The following objects are masked from 'package:stats':
## 
##     binom.test, cor, cor.test, cov, fivenum, IQR, median, prop.test,
##     quantile, sd, t.test, var
## The following objects are masked from 'package:base':
## 
##     max, mean, min, prod, range, sample, sum
## Loading required package: mosaicCore
## 
## Attaching package: 'mosaicCore'
## The following objects are masked from 'package:dplyr':
## 
##     count, tally
## 
## Attaching package: 'mosaicCalc'
## The following object is masked from 'package:stats':
## 
##     D
Utils <- read.csv("http://www.mosaic-web.org/go/datasets/utilities.csv")
gf_point(ccf ~ temp, data = Utils) %>%
  gf_labs(y = "Natural gas usage (ccf/month)", 
          x = "Average outdoor temperature (F)")

Banyak jenis fungsi yang berbeda dapat digunakan untuk mewakili data ini. Salah satu yang paling sederhana dan paling umum digunakan dalam pemodelan adalah fungsi garis lurus F(x) + Ax + B. Dalam fungsi F(x) variabel x singkatan dari input, sedangkan A dan B adalah parameter. Penting untuk diingat apa nama input dan output saat menyesuaikan model dengan data – Anda perlu mengatur agar namanya cocok dengan data yang sesuai.

Dengan data utilitas, masukannya adalah suhu, suhu. Keluaran yang akan dimodelkan adalah ccf. Untuk menyesuaikan fungsi model dengan data, tuliskan rumus dengan nama input, parameter, dan output yang sesuai di tempat yang tepat:

library(mosaicCalc)
f <- fitModel(ccf ~ A * temp + B, data = Utils)

Keluaran dari fitModel()adalah fungsi dengan bentuk matematika yang sama seperti yang Anda tentukan di argumen pertama (di sini, ccf ~ A * temp + B) dengan nilai numerik spesifik yang diberikan ke parameter untuk membuat fungsi paling cocok dengan data. Bagaimana cara fitModel()mengetahui besaran mana dalam bentuk matematika yang merupakan variabel dan mana yang merupakan parameter? Apa pun yang terkandung dalam data yang digunakan untuk pemasangan adalah variabel (di sini temp); hal-hal lain (di sini, Adan B) adalah parameter.

gf_point(ccf ~ temp, data = Utils) %>%
  slice_plot(f(temp) ~ temp)

Anda dapat menambahkan fungsi lain ke dalam campuran dengan mudah. Misalnya, Anda mungkin berpikir itu sqrt(temp)berhasil di sana.

f2 <- fitModel(
  ccf ~ A * temp + B + C *sqrt(temp),
  data = Utils)
gf_point(
  ccf ~ temp, data = Utils) %>%
  slice_plot(f2(temp) ~ temp)

Contoh ini hanya melibatkan satu variabel input. Sepanjang ilmu alam dan sosial, teknik yang sangat penting dan banyak digunakan adalah menggunakan banyak variabel dalam sebuah proyeksi. Sebagai ilustrasi, lihat data “used-hondas.csv”harga mobil Honda bekas.

Hondas <- read.csv("http://www.mosaic-web.org/go/datasets/used-hondas.csv")
head(Hondas)
##   Price Year Mileage Location Color Age
## 1 20746 2006   18394  St.Paul  Grey   1
## 2 19787 2007       8  St.Paul Black   0
## 3 17987 2005   39998  St.Paul  Grey   2
## 4 17588 2004   35882  St.Paul Black   3
## 5 16987 2004   25306  St.Paul  Grey   3
## 6 16987 2005   33399  St.Paul Black   2

Seperti yang Anda lihat, kumpulan data menyertakan variabel Price, Age, dan Mileage. Tampaknya masuk akal untuk berpikir bahwa harga akan bergantung pada jarak tempuh dan usia mobil. Inilah model yang sangat sederhana yang menggunakan kedua variabel:

carPrice1 <- fitModel(
  Price ~ A + B * Age + C * Mileage, data = Hondas)

Anda dapat menggunakan plot fungsi yang sesuai:

contour_plot(
  carPrice1(Age = age, Mileage = miles) ~ age + miles,
  domain(age=2:8, miles=range(0, 60000)))

Sebagai contoh, mari kita fokus pada kontur seharga $17.000. Setiap kombinasi usia dan mil yang jatuh pada kontur ini menghasilkan harga mobil yang sama: $17.000. Kemiringan kontur memberi tahu Anda pertukaran antara jarak tempuh dan usia. Lihatlah dua titik pada kontur yang berbeda 10.000 mil. Perbedaan usia yang sesuai adalah sekitar 1,5 tahun. Jadi, saat membandingkan dua mobil dengan harga yang sama, penurunan jarak tempuh sebesar 10.000 diimbangi dengan peningkatan usia 1,5 mil.

Model yang agak lebih canggih mungkin mencakup apa yang disebut interaksi antara usia dan jarak tempuh, dengan menyadari bahwa pengaruh usia mungkin berbeda bergantung pada jarak tempuh.

carPrice2 <- fitModel(
  Price ~ A + B * Age + C * Mileage + D * Age * Mileage,
  data = Hondas)

Sekali lagi, setelah fungsi dipasang ke data, Anda dapat memplotnya dengan cara biasa:

contour_plot(
  carPrice2(Age=age, Mileage=miles) ~ age + miles,
  domain(age = range(0, 8), miles = range(0, 60000)))

Operator fitModel()membuatnya sangat mudah untuk menemukan parameter dalam model apa pun yang membuat model mendekati data paling dekat. Pekerjaan dalam pemodelan adalah memilih bentuk model yang tepat (Istilah interaksi atau tidak? Apakah akan memasukkan variabel baru atau tidak?) dan menginterpretasikan hasilnya.

Kurva dan Model Linear

Sepintas, istilah “linier” dan “kurva” mungkin tampak kontradiktif. Garis lurus, kurva tidak.

Kata linier dalam “model linier” mengacu pada “kombinasi linier”, bukan “garis lurus”. Seperti yang akan Anda lihat, Anda dapat membuat kurva rumit dengan mengambil kombinasi fungsi linier, dan menggunakan operasi proyeksi aljabar linier untuk mencocokkan kurva ini sedekat mungkin dengan data. Proses pencocokan itu disebut “pas”.

Sebagai ilustrasi, data dalam file “utilities.csv”merekam suhu rata-rata setiap bulan (dalam derajat F) serta penggunaan gas alam bulanan (dalam kaki kubik, ccf). Ada, seperti yang Anda duga, hubungan yang kuat antara keduanya.

Utils <- read.csv("http://www.mosaic-web.org/go/datasets/utilities.csv")
gf_point(ccf ~ temp, data = Utils) %>%
  gf_labs(y = "Natural gas usage (ccf/month)", 
          x = "Average outdoor temperature (F)")

Dengan data utilitas, masukannya adalah suhu, suhu. Keluaran yang akan dimodelkan adalah ccf. Untuk menyesuaikan fungsi model dengan data, tuliskan rumus dengan nama input, parameter, dan output yang sesuai di tempat yang tepat:

f <- fitModel(ccf ~ A * temp + B, data = Utils)

Keluaran dari fitModel()adalah fungsi dengan bentuk matematika yang sama seperti yang Anda tentukan di argumen pertama (di sini, ccf ~ A * temp + B) dengan nilai numerik spesifik yang diberikan ke parameter untuk membuat fungsi paling cocok dengan data. Bagaimana cara fitModel()mengetahui besaran mana dalam bentuk matematika yang merupakan variabel dan mana yang merupakan parameter? Apa pun yang terkandung dalam data yang digunakan untuk pemasangan adalah variabel (di sini temp); hal-hal lain (di sini, Adan B) adalah parameter.

gf_point(ccf ~ temp, data = Utils) %>%
  slice_plot(f(temp) ~ temp)

Anda dapat menambahkan fungsi lain ke dalam campuran dengan mudah. Misalnya, Anda mungkin berpikir itu sqrt(temp)berhasil di sana.

f2 <- fitModel(
  ccf ~ A * temp + B + C *sqrt(temp),
  data = Utils)
gf_point(
  ccf ~ temp, data = Utils) %>%
  slice_plot(f2(temp) ~ temp)

Contoh ini hanya melibatkan satu variabel input. Sepanjang ilmu alam dan sosial, teknik yang sangat penting dan banyak digunakan adalah menggunakan banyak variabel dalam sebuah proyeksi. Sebagai ilustrasi, lihat data “used-hondas.csv”harga mobil Honda bekas.

Hondas <- read.csv("http://www.mosaic-web.org/go/datasets/used-hondas.csv")
head(Hondas)
##   Price Year Mileage Location Color Age
## 1 20746 2006   18394  St.Paul  Grey   1
## 2 19787 2007       8  St.Paul Black   0
## 3 17987 2005   39998  St.Paul  Grey   2
## 4 17588 2004   35882  St.Paul Black   3
## 5 16987 2004   25306  St.Paul  Grey   3
## 6 16987 2005   33399  St.Paul Black   2

Seperti yang Anda lihat, kumpulan data menyertakan variabel Price, Age, dan Mileage. Tampaknya masuk akal untuk berpikir bahwa harga akan bergantung pada jarak tempuh dan usia mobil. Inilah model yang sangat sederhana yang menggunakan kedua variabel:

project(Price ~ Age + Mileage + 1, data = Hondas)
##   (Intercept)           Age       Mileage 
##  2.133049e+04 -5.382931e+02 -7.668922e-02

Anda dapat memplotnya sebagai fungsi matematika:

car_price <- makeFun(21330-5.383e2*age-7.669e-2*miles ~ age & miles)
contour_plot(car_price(age, miles) ~ age + miles,
  domain(age=range(2, 8), miles=range(0, 60000))) %>%
  gf_labs(title = "Miles per gallon")

Model yang agak lebih canggih mungkin menyertakan apa yang disebut “interaksi” antara usia dan jarak tempuh, menyadari bahwa pengaruh usia mungkin berbeda tergantung pada jarak tempuh.

project(Price ~ Age + Mileage + Age*Mileage + 1, data = Hondas)
##   (Intercept)           Age       Mileage   Age:Mileage 
##  2.213744e+04 -7.494928e+02 -9.413962e-02  3.450033e-03
car_price2 <- makeFun(22137 - 7.495e2*age - 9.414e-2*miles +
                         3.450e-3*age*miles ~ age & miles)
contour_plot(
  car_price2(Age, Mileage) ~ Age + Mileage,  
  domain(Age = range(0, 10), Mileage = range(0, 100000))) %>%
  gf_labs(title = "Price of car (USD)")

Fungsi dengan parameter nonlinier

Teknik aljabar linier dapat digunakan untuk mencari kombinasi linier terbaik dari suatu himpunan fungsi. Namun, seringkali, ada parameter dalam fungsi yang muncul secara nonlinier. Menemukan parameter nonlinier ini tidak dapat dilakukan secara langsung menggunakan aljabar linier, meskipun metode aljabar linier memang membantu menyederhanakan situasi.

Untungnya, gagasan bahwa jarak antar fungsi dapat diukur berfungsi dengan baik ketika ada parameter nonlinear yang terlibat. Jadi kita akan terus menggunakan “jumlah residu kuadrat” saat mengevaluasi seberapa dekat perkiraan fungsi dengan sekumpulan data.

Sebagai ilustrasi, pertimbangkan “Income-Housing.csv”data yang menunjukkan hubungan eksponensial antara fraksi keluarga dengan dua mobil dan pendapatan:

Families <- read.csv("http://www.mosaic-web.org/go/datasets/Income-Housing.csv")
gf_point(TwoVehicles ~ Income, data = Families)

Pola data menunjukkan “pembusukan” eksponensial terhadap hampir 100% keluarga yang memiliki dua kendaraan. Aljabar linier memungkinkan kita menemukan parameter linier terbaik A dan C untuk mencocokkan data. Tapi bagaimana menemukan k?

Misalkan Anda menebak K. Tebakan tidak harus benar-benar acak; Anda dapat melihat dari datanya sendiri bahwa “waktu paruh” adalah sekitar $25.000. Parameter Kadalah sesuai dengan paruh, itu di (0.5)/setengah hidup, jadi inilah tebakan yang bagus untuk kadalah di (0.5)/2500

kguess <- log(0.5) / 25000
kguess
## [1] -2.772589e-05

Dimulai dengan tebakan tersebut, Anda dapat menemukan nilai terbaik dari parameter linier A dan C melalui teknik aljabar linier:

project( TwoVehicles ~ 1 + exp(Income*kguess), data = Families)
##          (Intercept) exp(Income * kguess) 
##             110.4263            -101.5666

Anda dapat membuat fungsi yang merupakan kombinasi linier terbaik dengan menambahkan kedua fungsi secara eksplisit:

f <- makeFun( 110.43 - 101.57*exp(Income * k) ~ Income, k = kguess)
gf_point(TwoVehicles ~ Income, data = Families) %>%
  slice_plot(f(Income) ~ Income) 

Grafik berjalan sangat dekat dengan titik data. Tapi Anda juga bisa melihat nilai numerik dari fungsi untuk setiap pendapatan:

f(Income = 10000)
## [1] 33.45433
f(Income = 50000)
## [1] 85.0375

Sangat informatif untuk melihat nilai fungsi untuk Incomelevel tertentu dalam data yang digunakan untuk pemasangan, yaitu data frame Families:

Results <- Families %>% 
  dplyr::select(Income, TwoVehicles) %>%
  mutate(model_val = f(Income = Income),
         resids = TwoVehicles - model_val)
Results
##   Income TwoVehicles model_val     resids
## 1   3914        17.3  19.30528 -2.0052822
## 2  10817        34.3  35.17839 -0.8783904
## 3  21097        56.4  53.84097  2.5590313
## 4  34548        75.3  71.45680  3.8432013
## 5  51941        86.6  86.36790  0.2320981
## 6  72079        92.9  96.66273 -3.7627306

Residual adalah perbedaan antara nilai model ini dan nilai sebenarnya dari kumpulanTwoVehicles data.

Kolom residsmemberikan sisa untuk setiap baris. Tapi Anda juga bisa memikirkan residskolom sebagai vektor. Ingatlah bahwa panjang kuadrat vektor adalah jumlah residu kuadrat

sum(Results$resids^2)
## [1] 40.32358

Panjang persegi vektor ini residsmerupakan cara penting untuk mengukur seberapa cocok model dengan data.

Mengoptimalkan tebakan Perlu diingat bahwa jumlah residu kuadrat adalah fungsi dari k. Nilai di atas hanya untuk tebakan khusus kita $k = $ kguess. Daripada hanya menggunakan satu tebakan untuk k, Anda dapat melihat berbagai kemungkinan. Untuk melihat semuanya pada saat yang sama, mari kita gambarkan jumlah residu kuadrat sebagai fungsi dari k. Kita akan melakukan ini dengan membuat fungsi yang menghitung jumlah sisa kuadrat untuk nilai tertentu dari k

sum_square_resids <- Vectorize(function(k) {
  sum((Families$TwoVehicles - f(Income=Families$Income, k)) ^ 2)
})
slice_plot(
   sum_square_resids(k) ~ k, 
   domain(k = range(log(0.5)/40000,log(0.5)/20000)))

Daftar Pustaka: Kaplan, Daniel. 2020. Computer-age Calculus with R.

https://dtkaplan.github.io/RforCalculus/fitting-functions-to-data.html