Analisis Regresi Linier Berganda dengan Python

Regresi Linier Berganda Python

Analisis regresi linier berganda adalah analisis statistika inferensia yang digunakan untuk memodelkan hubungan antara satu variabel dependen (respon) dengan dua atau lebih variabel independen (prediktor).

Pada tutorial ini, kita akan mempraktikan tahap demi tahap analisis regresi berganda menggunakan bahasa Python. Tutorial ini fokus pada analisis regresi berganda untuk inferensia, sehingga tidak akan membahas pada tahapan melatih model dengan pembagian data latih dan data uji, validasi silang ataupun melakukan prediksi data baru.

[Tutorial ini juga tersedia dalam Bahasa R: Analisis Regresi Linier Berganda dengan R]

Penyiapan Data

Data yang akan digunakan dalam tutorial ini adalah data Indeks Pembangunan Manusia (IPM) Tahun 2018 dari 119 Kabupaten/Kota di Pulau Jawa. Terdapat 16 kolom (selain kolom ID) dimana Nilai IPM akan menjadi peubah respon dan 15 lainnya sebagai peubah penjelas (merupakan indikator hasil agregasi data Potensi Desa 2018) dan seluruhnya bertipe numerik. Keterangan masing-masing kolom adalah sebagai berikut:

  • ID: Kode Kab/Kota (4 digit Kode BPS)
  • IPM: Nilai IPM
  • PR_NO_LIS: Proporsi keluarga yang tidak menggunakan listrik baik PLN maupun non-PLN
  • PR_SAMPAH: Proporsi desa/kelurahan pada kabupaten/kota dimana sebagian besar warganya membuang sampah di sungai/saluran irigasi/danau/laut serta got/selokan dan lainnya
  • PR_TINJA: Proporsi desa/kelurahan pada kabupaten/kota dimana tempat pembuangan akhir tinja sebagian besar warganya adalah sawah/kolam/sungai/danau/laut atau pantai/tanah lapang/kebun, lubang tanah dan lainnya
  • PR_MKM_SUNGAI: Proporsi desa/kelurahan di kabupaten/kota yang memiliki pemukiman di bantaran sungai
  • PR_SUNGAI_LMBH: Proporsi desa/kelurahan di kabupaten/kota yang memiliki sungai yang tercemar limbah
  • PR_KUMUH: Proporsi desa/kelurahan di kabupaten/kota yang memiliki pemukiman kumuh
  • PRA_1000: Jumlah PAUD dan TK per 1000 penduduk
  • SD_1000: Jumlah SD/MI per 1000 penduduk
  • SM_1000: Jumlah sekolah menengah (SMP/MTs, SMA/MA, SMK) per 1000 penduduk
  • RS_PKS_PDK_1000: Jumlah rumah sakit, puskesmas, puskesmas pembantu, poliklinik, praktek dokter per 1000 penduduk
  • LIN_BID_POS_1000: Jumlah rumah bersalin, praktek bidan, posyandu, polindes per 1000 penduduk
  • APT_OBT_1000: Jumlah apotek dan toko obat per 1000 penduduk
  • DOK_DRG_1000: Jumlah dokter dan dokter gigi per 1000 penduduk
  • BID_1000: Jumlah bidan per 1000 penduduk
  • GZ_BURUK_1000: Jumlah kejadian gizi buruk per 1000 penduduk

Python

# Membaca data
import pandas as pd
import numpy as np

url = "https://raw.githubusercontent.com/sainsdataid/dataset/main/data_ipm_jawa_2018.csv"
data = pd.read_csv(url)

# Melihat struktur data
print(data.info())

# Menghapus kolom id karena tidak diperlukan
data = data.drop(columns='id')
# OUTPUT

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 119 entries, 0 to 118
Data columns (total 17 columns):
 #   Column              Non-Null Count  Dtype  
---  ------              --------------  -----  
 0   id                  119 non-null    int64  
 1   ipm_2018            119 non-null    float64
 2   PR_NO_LIS           119 non-null    float64
 3   PR_SAMPAH           119 non-null    float64
 4   PR_TINJA            119 non-null    float64
 5   PR_MKM_SUNGAI       119 non-null    float64
 6   PR_SUNGAI_LMBH      119 non-null    float64
 7   PR_KUMUH            119 non-null    float64
 8   PRA_1000            119 non-null    float64
 9   SD_1000             119 non-null    float64
 10  SM_1000             119 non-null    float64
 11  RS_PKS_PDK_1000     119 non-null    float64
 12  LIN_BID_POS_P_1000  119 non-null    float64
 13  APT_OBT_1000        119 non-null    float64
 14  DOK_DRG_1000        119 non-null    float64
 15  BID_1000            119 non-null    float64
 16  GZ_BURUK_1000       119 non-null    float64
dtypes: float64(16), int64(1)
memory usage: 15.9 KB

Analisis Data Eksploratif

Ringkasan Data

Sebelum masuk ke tahap pemodelan, sangat disarankan untuk melakukan eksplorasi data untuk lebih memahami kondisi data. Terdapat beberapa hal yang akan kita lakukan dan dimulai dengan mengecek ringkasan data. Hasil ringkasan data, memberikan sedikit gambaran bagaimana karakteristik masing-masing peubah. Misalkan untuk peubah respon kita yaitu ipm_2018, nilai terkecil pada data adalah 61,00 dan nilai terbesar adalah 86,11 denga nilai rataan adalah 71,23.

Kita juga perlu memastikan tidak ada data hilang. Jika ternyata terdapat data hilang, maka perlu dilakukan penanganan, entah dengan menghapus baris, kolom atau melakukan imputasi. Pada dataset yang kita gunakan kebetulan tidak terdapat data hilang sehingga dapat dilanjutkan dengan pengecekan lainnya.

Python

# Melihat summary data
print(data.describe())

# Pengecekan missing value
cek_na = data.isna().sum()

# Merubah menjadi dataframe agar lebih rapi
cek_na_df = pd.DataFrame({
    'Variabel': cek_na.index,
    'Jumlah NA': cek_na.values
})

print(cek_na_df)
# OUTPUT

          ipm_2018   PR_NO_LIS   PR_SAMPAH  ...
count  119.000000  119.000000  119.000000   ...       
mean    71.980504    0.001514    0.074437   ...
std      5.459299    0.003732    0.083234   ...
min     61.000000    0.000000    0.000000   ...
25%     67.905000    0.000000    0.000000   ...
50%     71.230000    0.000131    0.049822   ...
75%     74.915000    0.001023    0.105149   ...
max     86.110000    0.024648    0.358896   ...


              Variabel  Jumlah NA
0             ipm_2018          0
1            PR_NO_LIS          0
2            PR_SAMPAH          0
3             PR_TINJA          0
..                 ...          .
14            BID_1000          0
15       GZ_BURUK_1000          0

Boxplot Sebaran Variabel Numerik

Semua variabel pada daset bertipe numerik, sehingga kita dapat membuat boxplot untuk masing-masing variabel. melalui boxplot kita dapat memperoleh informasi bagaimana data menyebar dan juga dapat digunakan unutk mengidentifikasi keberadaan outlier.

Dengan memanfaatkan subplots kita dapat membuat sekaligus semua boxplot dengan beberapa baris kode saja. Hasil visualisasi boxplot di bawah ini menunjukkan bahwa masing-masing variabel memiliki pola sebaran yang beragam. Sebagian besar terdapat titik-titik data yang diindikasikan sebagai outlier. Tentunya hal ini perlu dilihat dengan lebih seksama. Jika memang kondisi tersebut sesuatu yang wajar berarti tidak ada masalah. Namun jika dianggap ada yang tidak sesuai maka perlu dilakukan pengecekan dan penanganan kondisi tersebut.

Di sini, kita akan menganggap semua kondisi ini sesuai dengan fakta lapangan dan tidak akan melakukan penanganan apapun.

Python

import matplotlib.pyplot as plt
import seaborn as sns

# Mengatur ukuran grid
ncols = 4
nrows = (len(data.columns) // ncols) + (len(data.columns) % ncols > 0)

# Membuat plot
fig, axes = plt.subplots(nrows=nrows, ncols=ncols, figsize=(12, 8))
axes = axes.flatten()

for i, var in enumerate(data.columns):
    sns.boxplot(data=data[var], ax=axes[i], color="orange", orient="h", width=0.5)

plt.tight_layout()
plt.show()
Boxplot Peubah Penjelas dan Respon

Boxplot Sebaran nilai masing-masing peubah (gambar: penulis)

Korelasi Antar Variabel

Melihat koerelasi antar variabel merupakan bagian penting. Hal ini dapat menjadi indikasi awal apakah terdapat kondisi multikolinieritas pada data yang kita miliki. Tentunya lebih jauh kita dapat melihat nilai VIF untuk lebih meyakinkan.

Dari plot korelasi berikut, terlihat beberapa kolom memiliki nilai korelasi yang tinggi, sehingga mungkin akan terdapat kondisi multikolinieritas. Adapun untuk korelasi antara peubah penjelas dengan peubah respon, terlihat beberapa peubah memiliki korelasi yang cukup tinggi seperti DOK_DRG_1000SD_1000PR_TINJA dan sebagainya.

Selain itu, korelasi ini dapat menjadi informasi awal untuk melihat bagaimana hubungan antara setiap variabe penjelas dengan variabel respon. Sebagai contoh, cukup mengejutkan melihat korelasi beberapa data yang tampak agak “aneh”. Misal, korelasi SD_1000 atau SM_1000 dengan nilai IPM memiliki korelasi yang negatif. Semakin banyak SD_1000 maka nilai IPM di Kabupaten/Kota tersebut semakin rendah. Sebaliknya Korelasi PR_KUMUH serta PR_SUNGAI_LMBH terhadap nilai IPM bernilai positif. Dimana artinya, semakin tinggi proporsi pemukiman kumuh, atau proporsi sungai yang tercemar limbah maka nilai IPM di kabupaten tersebut cenderung lebih tinggi juga.

Tentunya banyak hal yang mungkin menyebabkan kondisi tersebut terjadi, dan tentunya perlu dikaji secara lebih komprehensif. Namun untuk tulisan singkkat ini, kita tidak akan melihat jauh di luar teknis analisis regresi.

Python

# Menghitung korelasi antar kolom
corr_matrix = data.corr().round(2)

# Membuat mask untuk menghapus segitiga atas
mask = np.triu(np.ones_like(corr_matrix, dtype=bool))

# Membuat plot korelasi
plt.figure(figsize=(10, 8))
sns.heatmap(
    corr_matrix,
    annot=True,
    fmt=".2f",
    mask=mask,
    cmap="coolwarm",
    linewidths=0.5,
    linecolor="white",
)

plt.xticks(rotation=45, ha="right", fontsize=10)
plt.yticks(fontsize=10)
plt.tight_layout()
plt.show()
Plot Korelasi

Plot korelasi antar variabel (gambar: penulis)

Model Regresi

Jika kondisi data sudah ‘clean’, maka kita dapat masuk ke tahap pembuatan model regresi linier berganda. Library statsmodels menyediakan fungsi OLS yang dapat kita gunakan secara cepat dan sederhana untuk model regresi linier. Terdapat beberapa library lain, namun untuk saat ini kita hanya akan menggunakan fungsi OLS saja. Parameter yang perlu ditentukan pada fungsi OLS adalah variabel dependen (y) dan variabel independen (X). Variabel independen harus ditambahkan konstanta menggunakan add_constant dari statsmodels.

Output dari model dapat dilihat dengan menggunakan metode summary.

Python

import statsmodels.api as sm

# Memisahkan variabel independen (X) dan dependen (y)
X = data.drop(columns=['ipm_2018'])
y = data['ipm_2018']

# Menambahkan konstanta ke variabel independen
X = sm.add_constant(X)

# Melatih model regresi linear
model_reg = sm.OLS(y, X).fit()

# Menampilkan ringkasan output model
print(model_reg.summary())
# OUTPUT

                            OLS Regression Results                            
==============================================================================
Dep. Variable:               ipm_2018   R-squared:                       0.847
Model:                            OLS   Adj. R-squared:                  0.825
Method:                 Least Squares   F-statistic:                     38.14
Date:                Sat, 20 Jul 2024   Prob (F-statistic):           3.48e-35
Time:                        14:41:51   Log-Likelihood:                -258.46
No. Observations:                 119   AIC:                             548.9
Df Residuals:                     103   BIC:                             593.4
Df Model:                          15                                         
Covariance Type:            nonrobust                                         
======================================================================================
                         coef    std err          t      P>|t|      [0.025      0.975]
--------------------------------------------------------------------------------------
const                 77.6934      1.616     48.089      0.000      74.489      80.898
PR_NO_LIS            -54.1662     72.840     -0.744      0.459    -198.628      90.295
PR_SAMPAH            -12.3238      3.342     -3.687      0.000     -18.952      -5.696
PR_TINJA              -3.8587      1.637     -2.358      0.020      -7.104      -0.613
PR_MKM_SUNGAI         -0.3064      2.239     -0.137      0.891      -4.746       4.133
PR_SUNGAI_LMBH        -0.0665      1.710     -0.039      0.969      -3.457       3.324
PR_KUMUH               1.1478      1.876      0.612      0.542      -2.572       4.868
PRA_1000              -1.4733      1.359     -1.084      0.281      -4.169       1.223
SD_1000               -8.4772      2.239     -3.785      0.000     -12.919      -4.036
SM_1000               -3.5570      2.852     -1.247      0.215      -9.214       2.100
RS_PKS_PDK_1000        5.0663      3.635      1.394      0.166      -2.142      12.275
LIN_BID_POS_P_1000     2.9505      2.038      1.448      0.151      -1.091       6.992
APT_OBT_1000          -7.7274      2.887     -2.677      0.009     -13.452      -2.002
DOK_DRG_1000          13.5001      2.481      5.441      0.000       8.579      18.421
BID_1000              -2.2206      1.528     -1.453      0.149      -5.251       0.810
GZ_BURUK_1000          0.6344      1.567      0.405      0.686      -2.472       3.741
==============================================================================
Omnibus:                        0.704   Durbin-Watson:                   1.636
Prob(Omnibus):                  0.703   Jarque-Bera (JB):                0.336
Skew:                           0.080   Prob(JB):                        0.845
Kurtosis:                       3.206   Cond. No.                         563.
==============================================================================

Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

Output yang disajikan di atas menampilkan berbagai nilai-nilai yang biasa diintepretasikan dari hasil pemodelan. Beberapa di antaranya adalah:

Koefisien Regresi

Nilai ini menunjukkan nilai koefisien regresi ($\hat{\beta_i}$) untuk masing-masing variabel. Misalkan, untuk variabel PR_NO_LIS memiliki nilai koefisien -54,166 dan untuk DOK_DRG_1000 bernilai 13,50. Tanda positif menunjukkan hubungan yang positif antara variabel penjelas dan responnya, sebaliknya tanda negatif menunjukkan hubungan negatif antara keduanya.

Statistik uji t

Komponen ini (P>|t|) menunjukkan variabel penjelas mana saja yang signifikan. Jika nilai p-value lebih kecil dari nilai $\alpha$ tertentu, misal 0,05 maka peubah tersebut siginifikan pada tingkat keyakinan $100- $\alpha$. Sebagai contoh menggunakan $\alpha=0.05$, nilai p-value untuk PR_SAMPAH adalah 0,000 < 0,05 sehingga termasuk variabel yang signifikan. Hal ini juga dapat dilihat melalui selang kepercayaan nilai koefisiennya yang memiliki batas-batas nilai dengan tanda yang sama yaitu -18,952 sampai -5,696. Sebaliknya, variabel PR_KUMUH memiliki nilai p-value sebesar 0,542 > 0,05 sehingga termasuk variabel yang tidak signifikan. Hasil ini dapat dilihat juga berdasarkan selang kepercayaan nilai keofisiennya yang berada antara -2,572 sampai 4,868 (mengandung nilai 0).

Statistik uji F

Jika statistik uji $t$ menunjukkan secara parsial signifikansi masing-masing variabel, maka statistik uji $F$ mengukur signifikansi model secara keseluruhan. Pada contoh ini, nilai statistik F adalah 38,14 dengan p-value $≈$ 0 ($p-value: = 3.48e-35$) menunjukkan model signifikan (bahkan dengan tingkat kesalahan yang sangat kecil, misal $alpha=0.00001$ atau lebih kecil lagi) . Dengan kata lain, dapat disimpulkan bahwa terdapat setidaknya 1 variabel penjelas yang signifikan (atau setidaknya terdapat satu $i$ untuk $\text{i=1,2…,15}$ di mana nilai $\beta_i\neq0$. Hal ini tentunya juga sudah sesuai dengan hasil uji parsial sebelumnya.

Koefisien Determinasi ($R^2$)

Nilai $R^2$ menunjukkan besarnya keragaman pada variabel respon yang dapat dijelaskan oleh variabel penjelas. Pada contoh ini nilai $R^2=0.847$ artinya variabel-variabel penjelas pada model mampu menjelaskan sekitar 84,7 persen keragaman pada nilai IPM.

Adjusted $R^2$

Nilai adjusted $R^2$ adalah nilai $R^2$ yang diberikan penalti berupa banyaknya variabel penjelas yang digunakan. Ukuran ini biasanya digunakan saat membandingkan kinerja antar model dengan tetap mempertimbangkan kompleksitas model. Model yang lebih sederhana akan di penalti lebih kecil dibandingkan model yang kompleks. Sebagai contoh, Model A dengan 15 variabel memiliki nilai $R^2=0.84$ dan model B dengan hanya 5 variabel memiliki niai $R^2=0.82$. Jika dihitung nilai adjusted $R^2$, bisa jadi Model B akan memberikan nilai yang lebih tinggi dibandingkan Model A. Hal ini dapat dimaknai, dengan pengurangan kompleksitas model yang besar (dari 15 variabel menjadi hanya 5 variabel) model tetap memiliki kinerja yang baik dan hanya sedikit saja mengurangi $R^2$ (dari 0,84 menjadi 0,82). Jika terjadi situasi seperti ini mungkin kita akan lebih cenderung memilih model B dibandingkan A.

Pengecekan Asumsi

Normalitas

Analisis regresi linier berganda mengasumsikan bahwa residual (perbedaan antara nilai yang diamati dan nilai yang diprediksi) terdistribusi secara normal. Asumsi ini dapat dinilai dengan memeriksa histogram atau Q-Q plot dari residual, atau melalui uji statistik seperti uji Kolmogorov-Smirnov, Shapiro-Wilk dan sebagainya.

Pada hasil qq plot maupun uji formal menggunakan uji K-S (tidak tolak $H_0$ karena $p-value > 0,05$), residual model memenuhi asumsi normalitas yaitu menyebar $\text{Normal}(0, \sigma^2)$.

Python

from scipy import stats

# Mendapatkan residual dari model
model_res = model_reg.resid

mean_res = round(np.mean(model_res), 4)
sd_res = round(np.std(model_res), 4)

print("Nilai tengah residual:", mean_res)
print("Simpangan baku residual:", sd_res)

# Membuat QQ plot dari residual
stats.probplot(model_res, dist="norm", plot=plt)
plt.title("QQ-Plot")
plt.xlabel("Theoritical Quantiles")
plt.ylabel("Quantiles of sample data")

plt.show()

# Melakukan uji Kolmogorov-Smirnov pada residual
ks_result = stats.kstest(model_res, "norm", args=(mean_res, sd_res))
print(ks_result)
# OUTPUT

Nilai tengah residual: 0.0
Simpangan baku residual: 2.1234

KstestResult(statistic=0.04931017440679053, 
             pvalue=0.9205685084687579, 
             statistic_location=0.07301368423065924, 
             statistic_sign=1)
Normal QQ Plot Analisis Regresi Linier Berganda
Plot normal quantile-quantile (gambar: penulis)

Homoskedastisitas

Ragam dari residual harus konsisten di seluruh tingkat variabel penjelas. Scatterplot dari residual versus nilai prediksi tidak boleh menampilkan pola yang terlihat, seperti distribusi berbentuk kerucut ataupun corong, yang artinya menunjukkan heteroskedastisitas. Jika diperlukan, terdapat pula uji-uji statistik yang dgunakan untuk mengecek asumsi ini seperti uji Breusch-Pagan, uji White dan sebagainya. Jika terdapat kondisi heteroskedastisitas, maka dapat juga dilakukan penanganan melalui transformasi data.

Pada kasus ini, berdasarkan uji BP (tidak tolak $H_0$ karena $p-value > 0,05$) dan plot sebaran nilai residual terlihat relatif menyebar acak untuk setiap nilai prediksi dan tidak ada kecenderungan membentuk pola kerucut. Dengan demikian dapat dikatakan tidak terdapat heteroskedastisitas.

Python

from statsmodels.stats.diagnostic import het_breuschpagan

# Melakukan uji Breusch-Pagan
bp_test = het_breuschpagan(model_res, model_reg.model.exog)
bp_test_result = dict(
    zip(["Lagrange multiplier statistic", "p-value", "f-value", "f p-value"], bp_test)
)
print(bp_test_result)

# Membuat plot residual vs nilai prediksi
plt.scatter(model_reg.fittedvalues, model_res, color='red', s=30)
plt.axhline(y=0, color='blue', linestyle='--')
plt.xlabel('Fitted Values')
plt.ylabel('Residuals')
plt.title('Residuals vs Fitted Values')
plt.show()
# OUTPUT

{'Lagrange multiplier statistic': 15.259972345570015, 
 'p-value': 0.4328581329533153, 
 'f-value': 1.0100743734967204, 
 'f p-value': 0.45101887238802657}
Plot Residual Regresi Linier Berganda

Plot residual vs fitted value (gambar: penulis)

Non-Multikolinieritas

Multikolinieritas (Ini sebenarnya bukanlah sebuah asumsi) merupakan masalah yang perlu ditangani. Analisis model dengan keberadaan multikolinieritas bisa menjadi tidak tepat. Ragam penduga menjadi lebih besar sehingga juga akan memperlebar selang kepercayaannya. Dampak dari selang kepercayaan yang lebih lebar adalah uji dapat menjadi tidak signifikan meskipun seharusnya variabel tersebut memiliki pengaruh kuat. Hal ini juga tidak menutup kemungkinan sampai menyebabkan penduga keofisien menjadi berubah tanda (positif menjadi negatif atau sebaliknya). Jika terjadi demikian tentu hasil analisis menjadi tidak reliable untuk digunakan.

Keberadaan masalah multikolinieritas dapat dilihat dengan cara berikut:

  • Matriks korelasi, di mana batas koefisien korelasi 0,80 dapat menjadi ‘warning’. Pada bagian sebelumnya, kita sudah menyajikan matriks korelasi dan menunjukkan beberapa variabel penjelas dengan korelasi cukup tinggi.
  • Variance Inflation Factor (VIF), dengan nilai VIF > 10 menunjukkan adanya masalah multikolinieritas.

Python

from statsmodels.stats.outliers_influence import variance_inflation_factor

# Menghitung VIF untuk setiap variabel dalam model
vif_data = pd.DataFrame()
vif_data['Variable'] = X.columns
vif_data['VIF'] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]

print(vif_data)
# OUTPUT

              Variable        VIF
0                const  59.630453 
1            PR_NO_LIS   1.674004
2            PR_SAMPAH   1.752889
3             PR_TINJA   3.883222
4        PR_MKM_SUNGAI   2.519156
5       PR_SUNGAI_LMBH   2.248597
6             PR_KUMUH   2.945363
7             PRA_1000   1.840095
8              SD_1000   4.638975
9              SM_1000   2.323137
10     RS_PKS_PDK_1000   5.283640
11  LIN_BID_POS_P_1000   3.867567
12        APT_OBT_1000   3.014481
13        DOK_DRG_1000   4.545848
14            BID_1000   2.377227
15       GZ_BURUK_1000   1.272896

Jika terdapat masalah multikolinieritas tersebut kita mungkin perlu mengeluarkan salah satu atau lebih variabel-variabel dengan korelasi yang kuat.

Berdasarkan hasil di atas, ternyata tidak terdapat indikasi masalah multikolinieritas antar variabel penjelas (abaikan nilai untuk konstanta). Hal ini dapat meyakinkan kita bahwa analisis regresi linier berganda yang kita lakukan sudah memenuhi asumsi-asumsi serta tidak terdapat masalah yang dapat mengganggu hasil dan interpretasinya.

Referensi

  • Agresti, A., Franklin, C., Klingenberg, B. 2018. StatisticsThe Art and Science of Learning from Data. 4th Edition. Essex: Pearson Education Limited
  • Caitlin C. Mothes, PhD and Katie Willi. 2023. Introduction to Data Analysis in. [Introduction to Data Analysis in R (rossyndicate.github.io)]
  • Weisberg, S. 2005. Applied Linier Regression, 3𝑡ℎ Edition. New Jersey : John Wiley & Sons

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

Daftar Isi