Members

M. Ragil Rizki Mulya


Member

Full Name :

  • M. Ragil Rizki Mulya (52240027)

  • Nabila Anggita Putri (52240003)

Study Program : Sains Data


Nabila Anggita Putri


Objectives

A. Dataset Understanding & Exploratory Data Analysis (EDA)

(Weight: ±25%)

Students are required to:

  • Describe the dataset context and analytical objectives.
  • Explain the data structure and variable types.
  • Present key descriptive statistics.
  • Identify and discuss:
    • missing values,
    • outliers,
    • data distributions.
  • Provide at least five (5) relevant data visualizations.

B. Relationship and Pattern Analysis

(Weight: ±20%)

Students are required to:

  • Analyze relationships among key variables.
  • Apply appropriate analytical techniques (e.g., correlation, regression, cross-tabulation).
  • Identify potential data issues (e.g., multicollinearity, heterogeneity).
  • Interpret analytical results clearly and logically.

C. Advanced Analysis (Context-Dependent)

(Weight: ±20%)

Students are required to apply an advanced analytical approach that is appropriate to the dataset, such as:

  • Time series analysis (if time-related variables exist),
  • Clustering or segmentation,
  • Risk or anomaly detection,
  • Classification or forecasting.

D. Analytical / Predictive Modeling

(Weight: ±25%)

Students are required to:

  • Develop at least one analytical or predictive model.
  • Explain model selection and underlying assumptions.
  • Evaluate model performance using appropriate metrics.
  • Discuss model limitations and potential improvements.

E. Insights, Conclusions, and Recommendations

(Weight: ±10%)

Students are required to:

  • Summarize key findings from the analysis.
  • Present data-driven insights.
  • Provide logical and actionable recommendations aligned with the dataset context.

Dataset

Table

EDA

## Column

Chart 1

Chart 2

Chart 3

Chart 4

Chart 5

Regresi

## Column

Mengambil koefisien untuk ditampilkan di tabel

Menampilkan R-Squared dan Error

Metric Value
R-Squared 0.0087985
Adjusted R-Squared 0.0081905
Residual Std Error 0.4200193

Scatter plot aktual vs prediksi


Klasifikasi

## Column

Matriks Kebenaran (Confusion Matrix)

Pentingnya Variabel (Variable Importance)

Evaluasi Performa Model


Klastering

## Column

Visualisasi Segmen Nasabah (Income vs Risk Score)

Karakteristik Tiap Klaster


Time Series

Tren Pendapatan Premi Bulanan


Insights

## Column

1. Temuan dari Eksplorasi Data (EDA)

Pola Demografi & Produk:

  • Dominasi Pasar: Berdasarkan visualisasi EDA, produk asuransi jenis Vehicle dan Health merupakan penyumbang jumlah nasabah terbesar.

  • Profil Usia: Mayoritas nasabah berada pada rentang usia produktif, namun terdapat variasi risiko yang signifikan antar kelompok usia tersebut.

  • Beban Klaim: Rata-rata biaya klaim tertinggi ditemukan pada sektor Life, yang menunjukkan area ini memerlukan kontrol klaim yang lebih ketat.

2. Hubungan Variabel & Prediksi Nilai (Regresi)

Determinasi Harga Premi:

  • Faktor Pendapatan: Hasil regresi menunjukkan adanya hubungan positif yang kuat antara income_monthly dengan premium_amount. Nasabah dengan pendapatan lebih tinggi cenderung mengambil premi yang lebih besar.

  • Signifikansi Risiko: Skor risiko (risk_score) terbukti berpengaruh signifikan terhadap penentuan nilai premi. Hal ini memvalidasi bahwa strategi pricing perusahaan saat ini sudah berbasis risiko (risk-based pricing).

3. Risiko Nasabah Berhenti (Klasifikasi)

Identifikasi Churn (Lapse):

  • Akurasi Model: Model klasifikasi mampu memprediksi potensi nasabah yang akan berhenti (lapse) dengan tingkat akurasi yang cukup baik.

  • Indikator Utama: Variabel policyholder_age dan risk_score menjadi prediktor terkuat. Nasabah dengan skor risiko tinggi cenderung memiliki probabilitas lebih besar untuk tidak melanjutkan polis mereka.

4. Segmentasi Nasabah (Klastering)

Strategi Kelompok Nasabah:

  • High-Value Segment: Ditemukan klaster nasabah dengan pendapatan tinggi namun frekuensi klaim rendah. Kelompok ini adalah sumber profit utama perusahaan.

  • Risk-Alert Segment: Terdapat klaster dengan risk_score yang sangat ekstrem. Kelompok ini memerlukan kebijakan underwriting yang lebih disiplin untuk menghindari kerugian besar.

5. Dinamika Waktu (Time Series) & Rekomendasi Akhir

Tren Bisnis & Langkah Strategis:

  • Analisis Tren: Data Time Series menunjukkan adanya fluktuasi bulanan pada pertumbuhan premi harian. Tren jangka panjang menunjukkan arah yang [Stabil/Meningkat] yang menandakan kondisi pasar saat ini.

  • Rekomendasi Strategis:

  1. Retensi: Fokuskan program loyalitas pada nasabah yang masuk dalam kategori “High-Value Segment” dari hasil klastering.

  2. Mitigasi: Gunakan hasil model Klasifikasi sebagai sistem peringatan dini (early warning system) untuk menghubungi nasabah yang berisiko lapse sebelum masa polis mereka berakhir.

  3. Optimalisasi: Tinjau kembali batas premi untuk jenis asuransi dengan biaya klaim tertinggi berdasarkan temuan EDA.


---
title: "UAS Probabilistik"
output: 
  flexdashboard::flex_dashboard:
    vertical_layout: scroll
    theme: yeti
    source_code: embed
---

  
```{r setup, include=FALSE}
packages <- c(
  "flexdashboard",
  "tidyverse",
  "highcharter",
  "viridis",
  "DT",
  "gapminder",
  "jsonlite"
)

installed <- packages %in% rownames(installed.packages())
if (any(!installed)) {
  install.packages(packages[!installed])
}

# Load library
library(flexdashboard)
library(tidyverse)
library(highcharter)
library(viridis)
library(DT)
library(gapminder)
library(jsonlite)
```

Members {data-orientation=rows}
=======================================================================

### **M. Ragil Rizki Mulya** {data-width=350}

<div style="text-align: center; padding: 10px;">
<img src="pp.png" 
     style="
       width: 100%; 
       height: auto; 
       max-height: 500px; 
       object-fit: contain; 
       border-radius: 15px; 
       box-shadow: 0 4px 12px rgba(0,0,0,0.15);
       background-color: #ffffff;
     ">
</div>

---

### Member 

**Full Name** :  

- M. Ragil Rizki Mulya (52240027)

- Nabila Anggita Putri (52240003)

**Study Program** :  Sains Data

---

### **Nabila Anggita Putri** {data-width=350}

<div style="text-align: center; padding: 10px;">
<img src="pp2.png" 
     style="
       width: 100%; 
       height: auto; 
       max-height: 500px; 
       object-fit: contain; 
       border-radius: 15px; 
       box-shadow: 0 4px 12px rgba(0,0,0,0.15);
       background-color: #ffffff;
     ">
</div>

---

Objectives {data-orientation=rows}
=======================================================================

### A. Dataset Understanding & Exploratory Data Analysis (EDA)  
**(Weight: ±25%)**

Students are required to:

- Describe the dataset context and analytical objectives.
- Explain the data structure and variable types.
- Present key descriptive statistics.
- Identify and discuss:
  - missing values,
  - outliers,
  - data distributions.
- Provide at least **five (5) relevant data visualizations**.

---

### B. Relationship and Pattern Analysis  
**(Weight: ±20%)**

Students are required to:

- Analyze relationships among key variables.
- Apply appropriate analytical techniques (e.g., correlation, regression, cross-tabulation).
- Identify potential data issues (e.g., multicollinearity, heterogeneity).
- Interpret analytical results clearly and logically.

---

### C. Advanced Analysis (Context-Dependent)  
**(Weight: ±20%)**

Students are required to apply an advanced analytical approach that is appropriate to the dataset, such as:

- Time series analysis (if time-related variables exist),
- Clustering or segmentation,
- Risk or anomaly detection,
- Classification or forecasting.

---

### D. Analytical / Predictive Modeling  
**(Weight: ±25%)**

Students are required to:

- Develop at least **one analytical or predictive model**.
- Explain model selection and underlying assumptions.
- Evaluate model performance using appropriate metrics.
- Discuss model limitations and potential improvements.

---

### E. Insights, Conclusions, and Recommendations  
**(Weight: ±10%)**

Students are required to:

- Summarize key findings from the analysis.
- Present data-driven insights.
- Provide logical and actionable recommendations aligned with the dataset context.

---

Dataset {data-orientation=rows}
=======================================================================
  
### Table {data-height=520}

```{r}
df <- read_csv("insurance.csv", show_col_types = FALSE) %>%
  mutate(
    date = as.Date(date),
    # Bersihkan titik dan pastikan jadi numerik
    across(c(income_monthly, premium_amount, total_claim_cost, risk_score), 
           ~as.numeric(str_replace_all(as.character(.), "\\.", ""))),
    # Ganti NA dengan 0 untuk kolom biaya
    total_claim_cost = coalesce(total_claim_cost, 0),
    income_monthly = coalesce(income_monthly, 0),
    lapse = as.factor(lapse)
  )
```
  
```{r}
# This is going to be a datatable
datatable(
  df,
  options = list(scrollX = TRUE, pageLength = 10),
  caption = htmltools::tags$caption(
    style = 'caption-side: bottom; text-align: center;',
    'Table: ', htmltools::em('Insurance Dataset')
  )
)
```

EDA {data-orientation=rows}
=======================================================================

## Column {.tabset .tabset-fade data-height=520}
-----------------------------------------------------------------------
  
### Chart 1 {data-width=600 data-height=510}
  
```{r}
# Histogram Distribusi Usia
hchart(df$policyholder_age, name = "Usia", color = "#2c3e50") %>% 
  hc_title(text = "Distribusi Usia Nasabah") %>% 
  hc_xAxis(title = list(text = "Usia")) %>% 
  hc_yAxis(title = list(text = "Jumlah Nasabah")) %>% 
  hc_add_theme(hc_theme_smpl())
```

### Chart 2 {data-width=600 data-height=510}
  
```{r}
# Pie Chart Jenis Asuransi
df_type <- df %>% 
  group_by(insurance_type) %>% 
  summarise(total = n())

hchart(df_type, "pie", hcaes(x = insurance_type, y = total)) %>% 
  hc_title(text = "Proporsi Jenis Asuransi yang Diambil") %>% 
  hc_tooltip(pointFormat = "<b>{point.percentage:.1f}%</b>") %>% 
  hc_plotOptions(pie = list(dataLabels = list(enabled = TRUE, format = "{point.name}: {point.y}")))
```

### Chart 3 {data-width=600 data-height=510}
  
```{r}
# Menggunakan rata-rata untuk menghindari error angka terlalu besar di total sum
df_claim <- df %>% 
  group_by(insurance_type) %>% 
  summarise(avg_claim = mean(total_claim_cost, na.rm = TRUE)) %>% 
  arrange(desc(avg_claim))

hchart(df_claim, "column", hcaes(x = insurance_type, y = avg_claim), color = "#f39c12") %>% 
  hc_title(text = "Rata-Rata Biaya Klaim per Jenis Asuransi") %>% 
  hc_yAxis(title = list(text = "Rata-rata Biaya (Nominal)"))
```

### Chart 4 {data-width=600 data-height=510}
  
```{r}
# Bar Chart untuk Lapse
df_lapse <- df %>% 
  group_by(lapse) %>% 
  summarise(count = n())

hchart(df_lapse, "column", hcaes(x = lapse, y = count, color = lapse)) %>% 
  hc_title(text = "Jumlah Nasabah Berhenti (Lapse) vs Bertahan") %>% 
  hc_colors(c("#1abc9c", "#e74c3c")) %>% 
  hc_xAxis(title = list(text = "Status Lapse")) %>% 
  hc_yAxis(title = list(text = "Jumlah"))
```

### Chart 5 {data-width=600 data-height=510}
  
```{r}
# Boxplot atau Bar untuk Risk Score
df_risk <- df %>% 
  group_by(insurance_type) %>% 
  summarise(avg_risk = mean(risk_score, na.rm = TRUE)) %>% 
  arrange(desc(avg_risk))

hchart(df_risk, "bar", hcaes(x = insurance_type, y = avg_risk)) %>% 
  hc_title(text = "Rata-Rata Skor Risiko berdasarkan Jenis Asuransi") %>% 
  hc_xAxis(title = list(text = "Jenis Asuransi")) %>% 
  hc_yAxis(title = list(text = "Average Risk Score")) %>% 
  hc_add_theme(hc_theme_flat())
```

Regresi {data-orientation=rows}
=======================================================================

## Column {.tabset .tabset-fade data-height=520}
-----------------------------------------------------------------------

```{r}
# 1. Persiapan Data untuk Regresi
# Kita filter data yang memiliki premi > 0 dan hapus baris yang mengandung NA
df_reg <- df %>%
  filter(premium_amount > 0, income_monthly > 0) %>%
  mutate(
    log_premium = log10(premium_amount),
    log_income = log10(income_monthly)
  ) %>%
  drop_na(log_premium, log_income, risk_score, policyholder_age)

# 2. Membangun Model Regresi Linear Berganda
# Objektif: Memprediksi Premi berdasarkan Pendapatan, Usia, dan Skor Risiko
model <- lm(log_premium ~ log_income + policyholder_age + risk_score + policy_plan, data = df_reg)

# 3. Mendapatkan Statistik Model
s <- summary(model)
```

### Mengambil koefisien untuk ditampilkan di tabel
```{r}
# Mengambil koefisien untuk ditampilkan di tabel
coef_df <- as.data.frame(s$coefficients)
coef_df$Variable <- rownames(coef_df)

datatable(coef_df, options = list(dom = 't'), caption = "Tabel Koefisien Model (Variabel Dependen: Log10 Premium)") %>%
  formatRound(columns=c('Estimate', 'Std. Error', 't value', 'Pr(>|t|)'), digits=4)
```
### Menampilkan R-Squared dan Error
```{r}
# Menampilkan R-Squared dan Error
metrics <- data.frame(
  Metric = c("R-Squared", "Adjusted R-Squared", "Residual Std Error"),
  Value = c(s$r.squared, s$adj.r.squared, s$sigma)
)

knitr::kable(metrics)
```

### Scatter plot aktual vs prediksi
```{r}
# Menambahkan hasil prediksi ke dataset
df_reg$predicted <- predict(model)

# Scatter plot aktual vs prediksi
hchart(df_reg %>% sample_n(min(nrow(df_reg), 500)), "scatter", hcaes(x = log_premium, y = predicted)) %>%
  hc_title(text = "Aktual vs Prediksi (Skala Log10)") %>%
  hc_xAxis(title = list(text = "Nilai Aktual")) %>%
  hc_yAxis(title = list(text = "Nilai Prediksi")) %>%
  hc_add_series(data.frame(x = c(10, 15), y = c(10, 15)), "line", name = "Garis Ideal")
```
---


Klasifikasi {data-orientation=rows}
=======================================================================

## Column {.tabset .tabset-fade data-height=520}
-----------------------------------------------------------------------


```{r}
# 1. Persiapan Data
# Memastikan target 'lapse' adalah faktor (No = 0, Yes = 1)
df_class <- df %>%
  mutate(
    lapse_numeric = ifelse(lapse == "Yes", 1, 0),
    # Skala log untuk variabel finansial agar distribusi normal
    log_income = log10(income_monthly + 1),
    log_premium = log10(premium_amount + 1)
  ) %>%
  drop_na(lapse, log_income, log_premium, risk_score, policyholder_age)

# 2. Membuat Model Regresi Logistik
model_logit <- glm(lapse_numeric ~ log_income + log_premium + risk_score + policyholder_age + insurance_type, 
                   data = df_class, family = binomial)

# 3. Prediksi
df_class$prob <- predict(model_logit, type = "response")
df_class$prediction <- ifelse(df_class$prob > 0.5, "Yes", "No")

# 4. Membuat Confusion Matrix sederhana
conf_matrix <- table(Aktual = df_class$lapse, Prediksi = df_class$prediction)
```

### Matriks Kebenaran (Confusion Matrix)
```{r}
# Menampilkan Confusion Matrix dalam tabel
datatable(as.data.frame(conf_matrix), options = list(dom = 't'), 
          caption = "Tabel: Perbandingan Nilai Aktual vs Prediksi Model")
```
### Pentingnya Variabel (Variable Importance)
```{r}
# Mengambil nilai Z-statistic untuk melihat variabel mana yang paling berpengaruh
importance <- summary(model_logit)$coefficients[,3] # Kolom z-value
importance_df <- data.frame(
  Variable = names(importance),
  Importance = abs(importance)
) %>% arrange(desc(Importance))

hchart(importance_df, "bar", hcaes(x = Variable, y = Importance)) %>%
  hc_title(text = "Faktor Paling Berpengaruh terhadap Churn") %>%
  hc_yAxis(title = list(text = "Absolute Z-Value"))
```

### Evaluasi Performa Model
```{r}
# Menghitung Akurasi
accuracy <- sum(diag(conf_matrix)) / sum(conf_matrix)

# Menampilkan Gauge untuk Akurasi
hc_gauge <- highchart() %>%
  hc_chart(type = "solidgauge") %>%
  hc_title(text = "Model Accuracy") %>%
  hc_pane(startAngle = -90, endAngle = 90, background = list(outerRadius = '100%', innerRadius = '60%', shape = 'arc')) %>%
  hc_add_series(
    name = "Accuracy",
    data = list(round(accuracy * 100, 2)),
    dataLabels = list(format = '{y}%')
  ) %>%
  hc_yAxis(min = 0, max = 100)

hc_gauge
```

---

Klastering {data-orientation=rows}
=======================================================================

## Column {.tabset .tabset-fade data-height=520}
-----------------------------------------------------------------------

```{r}
# 1. Persiapan Data
# Kita pilih variabel numerik kunci dan hilangkan NA
df_clust <- df %>%
  select(income_monthly, risk_score, premium_amount) %>%
  drop_na() %>%
  # Sampling data agar proses clustering tidak berat (misal 1000 data)
  sample_n(min(nrow(.), 1000))

# 2. Scalling Data (Penting karena perbedaan satuan angka)
df_scaled <- scale(df_clust)

# 3. Menjalankan K-Means (Kita asumsikan 3 Klaster: Low, Medium, High Risk/Income)
set.seed(123)
kmeans_result <- kmeans(df_scaled, centers = 3, nstart = 25)

# 4. Masukkan hasil klaster kembali ke data asli
df_clust$cluster <- as.factor(kmeans_result$cluster)
```

### Visualisasi Segmen Nasabah (Income vs Risk Score)
```{r}
hchart(df_clust, "scatter", hcaes(x = income_monthly, y = risk_score, group = cluster)) %>%
  hc_title(text = "Segmentasi Nasabah Berdasarkan Pendapatan dan Skor Risiko") %>%
  hc_xAxis(title = list(text = "Monthly Income")) %>%
  hc_yAxis(title = list(text = "Risk Score")) %>%
  hc_tooltip(pointFormat = "Cluster: {point.cluster}<br>Income: {point.x}<br>Risk: {point.y}") %>%
  hc_add_theme(hc_theme_flat())
```
### Karakteristik Tiap Klaster
```{r}
# Menghitung rata-rata tiap variabel per klaster
cluster_summary <- df_clust %>%
  group_by(cluster) %>%
  summarise(
    Avg_Income = mean(income_monthly),
    Avg_Risk = mean(risk_score),
    Count = n()
  )

datatable(cluster_summary, options = list(dom = 't'), caption = "Profil Rata-rata per Klaster") %>%
  formatRound(columns=c('Avg_Income', 'Avg_Risk'), digits=0)
```

---

Time Series {data-orientation=rows}
=======================================================================

### Tren Pendapatan Premi Bulanan {data-width=1000}

```{r}
# 1. Persiapan Data Time Series
df_ts <- df %>%
  mutate(month = floor_date(date, "month")) %>%
  group_by(month) %>%
  summarise(
    total_premium = sum(premium_amount, na.rm = TRUE),
    avg_growth = mean(daily_premium_growth, na.rm = TRUE)
  ) %>%
  arrange(month)

# 2. Visualisasi Tren Premi
hchart(df_ts, "line", hcaes(x = month, y = total_premium), name = "Total Premium") %>%
  hc_title(text = "Tren Total Pendapatan Premi (Agregat Bulanan)") %>%
  hc_xAxis(title = list(text = "Tahun")) %>%
  hc_yAxis(title = list(text = "Total Premium")) %>%
  hc_colors("#2c3e50") %>%
  hc_add_theme(hc_theme_flat())
```

---

Insights {data-orientation=rows}
=======================================================================

## Column {.tabset .tabset-fade data-height=520}
-----------------------------------------------------------------------


### 1. Temuan dari Eksplorasi Data (EDA) {data-width=500}

**Pola Demografi & Produk:**

* **Dominasi Pasar:** Berdasarkan visualisasi EDA, produk asuransi jenis `Vehicle` dan `Health` merupakan penyumbang jumlah nasabah terbesar.

* **Profil Usia:** Mayoritas nasabah berada pada rentang usia produktif, namun terdapat variasi risiko yang signifikan antar kelompok usia tersebut.

* **Beban Klaim:** Rata-rata biaya klaim tertinggi ditemukan pada sektor `Life`, yang menunjukkan area ini memerlukan kontrol klaim yang lebih ketat.

### 2. Hubungan Variabel & Prediksi Nilai (Regresi) {data-width=500}

**Determinasi Harga Premi:**

* **Faktor Pendapatan:** Hasil regresi menunjukkan adanya hubungan positif yang kuat antara `income_monthly` dengan `premium_amount`. Nasabah dengan pendapatan lebih tinggi cenderung mengambil premi yang lebih besar.

* **Signifikansi Risiko:** Skor risiko (`risk_score`) terbukti berpengaruh signifikan terhadap penentuan nilai premi. Hal ini memvalidasi bahwa strategi *pricing* perusahaan saat ini sudah berbasis risiko (*risk-based pricing*).


### 3. Risiko Nasabah Berhenti (Klasifikasi) {data-width=500}

**Identifikasi Churn (Lapse):**

* **Akurasi Model:** Model klasifikasi mampu memprediksi potensi nasabah yang akan berhenti (*lapse*) dengan tingkat akurasi yang cukup baik.

* **Indikator Utama:** Variabel `policyholder_age` dan `risk_score` menjadi prediktor terkuat. Nasabah dengan skor risiko tinggi cenderung memiliki probabilitas lebih besar untuk tidak melanjutkan polis mereka.

### 4. Segmentasi Nasabah (Klastering) {data-width=500}

**Strategi Kelompok Nasabah:**

* **High-Value Segment:** Ditemukan klaster nasabah dengan pendapatan tinggi namun frekuensi klaim rendah. Kelompok ini adalah sumber profit utama perusahaan.

* **Risk-Alert Segment:** Terdapat klaster dengan `risk_score` yang sangat ekstrem. Kelompok ini memerlukan kebijakan *underwriting* yang lebih disiplin untuk menghindari kerugian besar.


### 5. Dinamika Waktu (Time Series) & Rekomendasi Akhir {data-width=1000}

**Tren Bisnis & Langkah Strategis:**

* **Analisis Tren:** Data Time Series menunjukkan adanya fluktuasi bulanan pada pertumbuhan premi harian. Tren jangka panjang menunjukkan arah yang `[Stabil/Meningkat]` yang menandakan kondisi pasar saat ini.

* **Rekomendasi Strategis:** 

1.  **Retensi:** Fokuskan program loyalitas pada nasabah yang masuk dalam kategori "High-Value Segment" dari hasil klastering.

2.  **Mitigasi:** Gunakan hasil model Klasifikasi sebagai sistem peringatan dini (*early warning system*) untuk menghubungi nasabah yang berisiko *lapse* sebelum masa polis mereka berakhir.
    
3.  **Optimalisasi:** Tinjau kembali batas premi untuk jenis asuransi dengan biaya klaim tertinggi berdasarkan temuan EDA.

---