# Penjelasan Komprehensif Proyek Analisis Turbin Angin
## Daftar Isi
1. [Dataset dan Permasalahan](#dataset-dan-permasalahan)
2. [Data Preprocessing](#data-preprocessing)
3. [Feature Engineering](#feature-engineering)
4. [Introduction to Machine Learning](#introduction-to-machine-learning)
5. [Supervised Method: Regression](#supervised-method-regression)
6. [Model Performance Evaluation](#model-performance-evaluation)
7. [Kesimpulan dan Rekomendasi](#kesimpulan-dan-rekomendasi)
## Dataset dan Permasalahan
### Deskripsi Dataset
Dataset ini berisi data operasional dari turbin angin dengan 50.530 baris dan 5 kolom. Variabel-variabel yang terdapat dalam dataset:
- **Date/Time**: Waktu pengambilan data (timestamp)
- **LV ActivePower (kW)**: Daya aktif yang dihasilkan oleh turbin dalam kilowatt
- **Wind Speed (m/s)**: Kecepatan angin dalam meter per detik
- **Theoretical_Power_Curve (KWh)**: Kurva daya teoretis berdasarkan spesifikasi produsen
- **Wind Direction (°)**: Arah angin dalam derajat (0-360°)
### Permasalahan
Permasalahan utama yang ingin diselesaikan adalah memprediksi **LV ActivePower (kW)** berdasarkan variabel-variabel lain. Hal ini penting untuk pemeliharaan prediktif turbin angin, optimalisasi operasi, dan mendeteksi anomali kinerja.
## Data Preprocessing
### Load Data
```python
import pandas as pd
from sklearn.preprocessing import StandardScaler
# Load data
df = pd.read_csv('T1.csv')
# Display the first 5 rows of the dataframe
print("First 5 rows of the dataframe:")
print(df.head(5))
```
Data awal menunjukkan struktur dataset dengan kolom Date/Time, LV ActivePower (kW), Wind Speed (m/s), Theoretical_Power_Curve (KWh), dan Wind Direction (°).
### Konversi Tipe Data
```python
df['Date/Time'] = pd.to_datetime(df['Date/Time'], dayfirst=True, errors='coerce')
```
Konversi kolom Date/Time ke format datetime sangat penting untuk analisis deret waktu. Parameter `dayfirst=True` mengasumsikan format tanggal DD/MM/YYYY, dan `errors='coerce'` mengubah nilai yang tidak valid menjadi NaT (Not a Time).
### Pengecekan Missing Values
```python
print("\n Missing values in the dataframe:")
df.isnull().sum()
```
Hasil: Tidak ditemukan missing values di dataset ini, yang menunjukkan kualitas data yang baik.
### Pengecekan Duplikasi
```python
df.duplicated().sum()
```
Hasil: Tidak ditemukan data duplikat, yang kembali menunjukkan kualitas data yang baik.
### Deteksi dan Penanganan Outlier
Outlier dideteksi menggunakan metode Interquartile Range (IQR):
```python
def detect_outliers_iqr(df, column, factor=1.5):
Q1 = df[column].quantile(0.25)
Q3 = df[column].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - factor * IQR
upper_bound = Q3 + factor * IQR
outliers = df[(df[column] < lower_bound) | (df[column] > upper_bound)]
return outliers, lower_bound, upper_bound
```
Metode IQR mendefinisikan outlier sebagai nilai yang berada di luar rentang:
- Lower bound: Q1 - 1.5 × IQR
- Upper bound: Q3 + 1.5 × IQR
Hasil deteksi outlier:
- LV ActivePower (kW): 0 outlier (0.00%)
- Wind Speed (m/s): 423 outlier (0.84%)
- Theoretical_Power_Curve (KWh): 0 outlier (0.00%)
- Wind Direction (°): 0 outlier (0.00%)
Penanganan outlier dilakukan dengan menghapus 423 baris data yang mengandung outlier pada kolom Wind Speed (m/s).
### Standardisasi Data
Standardisasi menggunakan StandardScaler mengubah data menjadi distribusi dengan mean=0 dan standar deviasi=1:
```python
scaler = StandardScaler()
df_standardized[numeric_columns] = scaler.fit_transform(df_cleaned[numeric_columns])
```
Standardisasi penting untuk:
1. Menyamakan skala antar variabel
2. Meningkatkan konvergensi algoritma machine learning
3. Membantu algoritma yang sensitif terhadap skala seperti KNN atau SVM
Formula standardisasi: $z = \frac{x - \mu}{\sigma}$
## Feature Engineering
Feature engineering adalah salah satu tahap paling krusial dalam machine learning yang dapat secara signifikan meningkatkan performa model. Pada proyek ini, beberapa teknik feature engineering yang diimplementasikan:
### 1. Feature Selection dengan Mutual Information
Mutual Information (MI) digunakan untuk mengukur seberapa banyak informasi yang diberikan suatu variabel tentang variabel lain:
```python
mi_scores = mutual_info_regression(X, y, discrete_features='auto')
mi_df = pd.DataFrame({'Feature': X.columns, 'Mutual Info': mi_scores})
```
Hasil MI score:
```
Feature Mutual Info
Wind Speed (m/s) 0.212088
LV ActivePower (kW) 0.195244
Theoretical_Power_Curve (KWh) 0.187432
```
Interpretasi:
- `Wind Speed (m/s)` memiliki skor MI tertinggi (0.21), menjadikannya fitur paling informatif untuk memprediksi variabel target
- `LV ActivePower (kW)` dan `Theoretical_Power_Curve (KWh)` juga memberikan informasi signifikan
### 2. Feature Creation: Binning
Binning dilakukan untuk mengubah variabel kontinu menjadi kategorikal:
```python
bin_col = numeric_cols[0]
kbins = KBinsDiscretizer(n_bins=4, encode='ordinal', strategy='quantile')
df_cleaned[bin_col + '_binned'] = kbins.fit_transform(df_cleaned[[bin_col]])
```
Parameter penting:
- `n_bins=4`: Membagi data menjadi 4 kategori
- `encode='ordinal'`: Menghasilkan encoding ordinal (0, 1, 2, 3)
- `strategy='quantile'`: Membagi berdasarkan quantile (jumlah data sama di setiap bin)
Keuntungan binning:
1. Menangkap hubungan non-linear
2. Mengurangi pengaruh outlier
3. Menangkap threshold effect pada data
### 3. Transformasi Variabel Siklikal (Arah Angin)
Arah angin adalah variabel siklikal, dimana 0° dan 360° secara fungsional adalah arah yang sama. Pendekatan standar menggunakan transformasi sine dan cosine:
```python
wind_dir_rad = np.radians(df_cleaned['Wind Direction (°)'])
df_cleaned['Wind_Direction_Sin'] = np.sin(wind_dir_rad)
df_cleaned['Wind_Direction_Cos'] = np.cos(wind_dir_rad)
```
Transformasi ini memetakan sudut ke koordinat pada lingkaran satuan, mempertahankan sifat siklikal dari variabel arah.
### 4. Categorical Encoding untuk Arah Mata Angin
Mengubah derajat arah angin menjadi arah mata angin dan kemudian membuat variabel dummy:
```python
def get_cardinal_direction(degrees):
# Define direction boundaries (N, NE, E, SE, S, SW, W, NW)
boundaries = np.array([0, 45, 90, 135, 180, 225, 270, 315, 360])
directions = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N']
# Find the appropriate cardinal direction
index = np.digitize(degrees, boundaries) - 1
return directions[index]
df_cleaned['Wind_Direction_Cardinal'] = df_cleaned['Wind Direction (°)'].apply(get_cardinal_direction)
# Create dummy variables for cardinal directions
cardinal_dummies = pd.get_dummies(df_cleaned['Wind_Direction_Cardinal'], prefix='Dir')
df_cleaned = pd.concat([df_cleaned, cardinal_dummies], axis=1)
```
Teknik ini menghasilkan fitur kategorikal yang lebih bermakna dan interpretable.
### 5. Feature Interaction
Feature interaction dibuat untuk menangkap hubungan non-linear antara kecepatan angin dan arahnya:
```python
df_cleaned['Wind_Speed_x_Sin'] = df_cleaned['Wind Speed (m/s)'] * df_cleaned['Wind_Direction_Sin']
df_cleaned['Wind_Speed_x_Cos'] = df_cleaned['Wind Speed (m/s)'] * df_cleaned['Wind_Direction_Cos']
```
Fitur interaksi ini mampu membantu model untuk lebih memahami bagaimana kombinasi dari kecepatan angin dan arah mempengaruhi daya yang dihasilkan.
### Dampak Feature Engineering
Melalui proses feature engineering ini, model yang dihasilkan memiliki akses ke representasi data yang lebih kaya dan bermakna, yang terbukti meningkatkan performa prediksi seperti yang ditunjukkan dalam evaluasi model.
## Introduction to Machine Learning
### Konsep Dasar Machine Learning
Machine Learning (ML) adalah cabang dari Artificial Intelligence yang memungkinkan sistem untuk belajar dan meningkatkan pengalaman secara otomatis tanpa diprogram secara eksplisit. Dalam konteks proyek ini, ML digunakan untuk memprediksi daya keluaran turbin angin (LV ActivePower) berdasarkan variabel-variabel seperti kecepatan angin, arah angin, dan kurva daya teoretis.
### Jenis-jenis Machine Learning
1. **Supervised Learning**:
- Digunakan dalam proyek ini
- Model dilatih pada data berlabel (dengan target yang diketahui)
- Bertujuan memprediksi nilai target berdasarkan fitur input
- Contoh: Regresi (digunakan di proyek ini), Klasifikasi
2. **Unsupervised Learning**:
- Tidak digunakan dalam proyek ini
- Model dilatih pada data tanpa label
- Bertujuan menemukan pola atau struktur dalam data
- Contoh: Clustering, Dimensionality Reduction
3. **Reinforcement Learning**:
- Tidak digunakan dalam proyek ini
- Model belajar melalui trial and error, dengan reward dan punishment
- Biasa digunakan untuk game, robotika, dan optimasi kontrol
### Dataset Split
Dataset dibagi menjadi 3 bagian untuk menghindari overfitting dan mengevaluasi performa model secara objektif:
```python
X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.3, random_state=42)
X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)
```
- **Training set (70%)**: Digunakan untuk melatih model
- **Validation set (15%)**: Digunakan untuk tuning hyperparameter dan pemilihan model
- **Test set (15%)**: Digunakan untuk evaluasi final performa model
Parameter penting:
- `test_size=0.3`: 30% data dipisahkan untuk validasi dan test
- `random_state=42`: Menjamin reproducibility dengan menggunakan seed yang konsisten
- Splitting kedua membagi data test dan validation dengan rasio 50:50
## Supervised Method: Regression
Dalam proyek ini, diimplementasikan beberapa algoritma regresi untuk memprediksi LV ActivePower (kW). Fokus utamanya adalah pada empat model regresi:
### 1. Linear Regression
```python
linear_model = LinearRegression()
linear_results, y_val_pred_linear = evaluate_model(linear_model, X_train, X_val, y_train, y_val)
```
**Konsep:** Linear Regression memodelkan hubungan linear antara variabel dependen (y) dan satu atau lebih variabel independen (X).
**Formula:**
$$\hat{y} = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \beta_3 x_3 + \ldots + \beta_n x_n$$
**Kelebihan:**
- Sederhana dan mudah diinterpretasi
- Komputasi yang efisien
- Bekerja baik untuk hubungan yang memang linear
**Keterbatasan:**
- Tidak dapat menangkap hubungan non-linear
- Sensitif terhadap outlier
- Asumsi independensi error dan homoskedastisitas
### 2. Ridge Regression
```python
ridge_model = Ridge(alpha=1.0)
ridge_results, y_val_pred_ridge = evaluate_model(ridge_model, X_train, X_val, y_train, y_val)
```
**Konsep:** Ridge Regression adalah variasi dari Linear Regression yang menambahkan regularisasi L2 untuk mengatasi masalah multikolinearitas dan overfitting.
**Formula:**
$$\min_{\beta} \left\{ \sum_{i=1}^{n} (y_i - \beta_0 - \sum_{j=1}^{p} \beta_j x_{ij})^2 + \alpha \sum_{j=1}^{p} \beta_j^2 \right\}$$
**Kelebihan:**
- Mengurangi overfitting dengan regularisasi
- Menangani multikolinearitas dengan lebih baik
- Koefisien yang lebih stabil
**Keterbatasan:**
- Tetap tidak bisa menangkap non-linearitas
- Memerlukan tuning parameter alpha
- Feature selection tidak sebaik Lasso
### 3. Decision Tree Regressor
```python
dt_model = DecisionTreeRegressor(max_depth=10, random_state=42)
dt_results, y_val_pred_dt = evaluate_model(dt_model, X_train, X_val, y_train, y_val)
```
**Konsep:** Decision Tree membagi ruang fitur menjadi region berdasarkan aturan keputusan dan menetapkan nilai prediksi untuk tiap region.
**Parameter penting:**
- `max_depth=10`: Membatasi kedalaman maksimum pohon untuk mencegah overfitting
- `random_state=42`: Menjamin reproducibility
**Kelebihan:**
- Dapat menangkap hubungan non-linear
- Feature importance yang explisit
- Mudah divisualisasikan dan diinterpretasi
**Keterbatasan:**
- Mudah overfitting jika tidak di-prune
- Tidak robust terhadap perubahan kecil pada data
- Prediksi yang "patah-patah" (tidak smooth)
Dalam proyek, Decision Tree menunjukkan performa terbaik dengan RMSE=147.4839 dan R²=0.9874 pada validation set.
### 4. K-Nearest Neighbors (KNN)
```python
knn_model = KNeighborsRegressor(n_neighbors=5)
knn_results, y_val_pred_knn = evaluate_model(knn_model, X_train, X_val, y_train, y_val)
```
**Konsep:** KNN memprediksi nilai target dengan merata-ratakan nilai dari k tetangga terdekat dalam ruang fitur.
**Parameter penting:**
- `n_neighbors=5`: Jumlah tetangga terdekat yang dipertimbangkan
**Kelebihan:**
- Non-parametrik, tidak membuat asumsi tentang distribusi data
- Sederhana dan intuitif
- Dapat menangkap hubungan lokal yang kompleks
**Keterbatasan:**
- Komputasi yang berat untuk dataset besar
- Sensitif terhadap skala fitur
- Rentan terhadap "curse of dimensionality"
### Perbandingan Hasil Model Regresi
```
model_name train_rmse val_rmse train_r2 val_r2 train_mape val_mape
LinearRegression 255.9713 255.5445 0.9619 0.9621 13.2042 13.2856
Ridge 255.9712 255.5446 0.9619 0.9621 13.2042 13.2855
DecisionTreeRegressor 40.4404 147.4839 0.9990 0.9874 1.6322 5.5837
KNeighborsRegressor 153.1285 257.7099 0.9864 0.9613 5.8237 12.9098
```
**Analisis hasil:**
1. **Decision Tree Regressor** menunjukkan performa terbaik pada data validasi (RMSE=147.48, R²=0.9874)
2. **Linear Regression** dan **Ridge Regression** menunjukkan hasil yang hampir identik, menunjukkan bahwa regularisasi tidak memberikan dampak signifikan (kemungkinan multikolinearitas tidak menjadi masalah)
3. **KNN** memiliki performa terburuk pada data validasi
4. Decision Tree menunjukkan gap antara metrik training dan validasi, mengindikasikan sedikit overfitting
## Model Performance Evaluation
Evaluasi performa model adalah langkah krusial untuk memahami seberapa baik model memprediksi data yang belum pernah dilihat sebelumnya. Dalam proyek ini, digunakan beberapa metrik evaluasi:
### 1. Root Mean Squared Error (RMSE)
RMSE mengukur akar kuadrat dari rata-rata kesalahan kuadrat antara nilai prediksi dan nilai aktual:
$$RMSE = \sqrt{\frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2}$$
**Interpretasi:**
- Satuan sama dengan variabel target (kW)
- Semakin kecil nilainya, semakin baik model
- Memberikan penalti lebih besar pada error besar
- Decision Tree memiliki RMSE validasi terbaik (147.48)
### 2. Coefficient of Determination (R²)
R² mengukur proporsi variasi dalam variabel dependen yang dapat dijelaskan oleh model:
$$R^2 = 1 - \frac{\sum_{i=1}^{n} (y_i - \hat{y}_i)^2}{\sum_{i=1}^{n} (y_i - \bar{y})^2}$$
**Interpretasi:**
- Rentang 0-1, semakin tinggi semakin baik
- Decision Tree memiliki R² validasi tertinggi (0.9874)
- Nilai R² yang tinggi menunjukkan model mampu menangkap hampir semua variance dalam data
### 3. Modified Mean Absolute Percentage Error (MAPE)
MAPE mengukur persentase rata-rata kesalahan absolut relatif terhadap nilai aktual:
```python
def calculate_modified_mape(y_true, y_pred, epsilon=1.0):
y_true_safe = np.maximum(np.abs(y_true), epsilon)
mape = np.mean(np.abs((y_true - y_pred) / y_true_safe)) * 100
return mape
```
**Interpretasi:**
- Satuan dalam persentase (%)
- Mudah diinterpretasi: "rata-rata kesalahan model adalah x%"
- Dimodifikasi dengan epsilon untuk menghindari pembagian dengan nol
- Decision Tree memiliki MAPE validasi terbaik (5.58%)
### Visualisasi Evaluasi Model
#### 1. Actual vs Predicted Plot
```python
plt.figure(figsize=(10, 6))
plt.scatter(y_val, best_predictions, alpha=0.5)
plt.plot([min_val, max_val], [min_val, max_val], 'r--')
plt.xlabel('Actual Values')
plt.ylabel('Predicted Values')
plt.title(f'Prediksi vs Aktual untuk {best_model_name}')
```
**Interpretasi:**
- Semakin dekat titik dengan garis diagonal, semakin akurat prediksi
- Pola titik yang teragregasi menunjukkan pola daya bi-modal
- Decision Tree mampu memprediksi dengan akurasi tinggi di sebagian besar nilai
#### 2. Residual Plot
```python
residuals = y_val - best_predictions
plt.figure(figsize=(10, 6))
plt.scatter(best_predictions, residuals, alpha=0.5)
plt.axhline(y=0, color='r', linestyle='--')
```
**Interpretasi:**
- Residual seharusnya terdistribusi secara acak di sekitar garis nol
- Pola pada residual mengindikasikan bahwa model belum menangkap semua pola dalam data
- Decision Tree menunjukkan residual yang kecil untuk sebagian besar prediksi
#### 3. Feature Importance
```python
importances = dt_model.feature_importances_
indices = np.argsort(importances)[::-1]
plt.figure(figsize=(10, 6))
plt.bar(range(X_train.shape[1]), importances[indices], align='center')
plt.xticks(range(X_train.shape[1]), [feature_names[i] for i in indices], rotation=45)
```
**Interpretasi dari Feature Importance:**
1. `Theoretical_Power_Curve (KWh)`: 0.3141 ± 0.0102
2. `Wind Speed (m/s)`: 0.1968 ± 0.0079
3. `Wind_Direction_Cos`: 0.0387 ± 0.0030
4. `Wind_Direction_Sin`: 0.0314 ± 0.0035
5. `Wind_Speed_x_Cos`: 0.0182 ± 0.0021
6. `Wind_Speed_x_Sin`: 0.0109 ± 0.0018
Kurva daya teoretis dan kecepatan angin adalah faktor terpenting dalam memprediksi daya aktual.
#### 4. Learning Curve
```python
train_sizes, train_scores, test_scores = learning_curve(
estimator, X, y, cv=5, scoring='neg_mean_squared_error',
train_sizes=np.linspace(0.1, 1.0, 10), random_state=42)
train_scores = np.sqrt(-train_scores)
test_scores = np.sqrt(-test_scores)
```
**Interpretasi Learning Curve:**
- Gap antara training dan validation score mengindikasikan seberapa besar overfitting
- Trend validation score menunjukkan apakah lebih banyak data akan membantu
- Decision Tree menunjukkan konvergensi yang baik dengan sekitar 20.000 sampel
### Evaluasi Final pada Test Set
Model terbaik (Decision Tree) dievaluasi pada test set yang sebelumnya tidak terlihat:
```python
y_test_pred = best_model.predict(X_test)
test_rmse = np.sqrt(mean_squared_error(y_test, y_test_pred))
test_r2 = r2_score(y_test, y_test_pred)
test_mape = calculate_modified_mape(y_test, y_test_pred)
```
**Hasil:**
```
Model: DecisionTreeRegressor
Test RMSE: 146.2741
Test R²: 0.9876
Test MAPE: 5.5095%
```
Performa pada test set sangat mirip dengan validation set, menunjukkan bahwa model memiliki generalisasi yang baik dan tidak overfitting.
## Kesimpulan dan Rekomendasi
### Kesimpulan
1. **Kualitas Data**: Dataset yang digunakan memiliki kualitas yang baik dengan tidak ada missing values dan minimal outlier (hanya 0.84% pada kecepatan angin).
2. **Feature Engineering**:
- Transformasi variabel siklikal untuk arah angin menggunakan sine dan cosine
- Feature interaction antara kecepatan dan arah angin
- Kategorisasi arah angin menjadi arah mata angin
Teknik-teknik ini berkontribusi signifikan terhadap performa model.
3. **Model Terbaik**: Decision Tree Regressor menunjukkan performa terbaik (R² = 0.9876, RMSE = 146.27 kW) karena kemampuannya menangkap pola non-linear antara kecepatan angin, arah angin, dan daya keluaran.
4. **Feature Importance**:
- Kurva daya teoretis dan kecepatan angin adalah faktor terpenting
- Transformasi arah angin (sine dan cosine) memiliki pengaruh moderat
- Fitur interaksi memiliki pengaruh yang lebih kecil namun tetap bermakna
5. **Pola Operasional**:
- Turbin beroperasi dalam dua mode utama: daya rendah atau kapasitas penuh
- Arah angin dominan (timur laut dan barat daya) menghasilkan daya tertinggi
### Rekomendasi
1. **Optimasi Operasional**:
- Sesuaikan orientasi turbin berdasarkan arah angin dominan
- Optimalkan jadwal pemeliharaan saat prediksi angin lemah
2. **Pemeliharaan Prediktif**:
- Implementasikan sistem deteksi anomali berdasarkan model prediktif
- Fokus monitoring pada periode dengan angin kencang (>15 m/s)
3. **Pengembangan Model**:
- Eksplorasi model ensemble (Random Forest, Gradient Boosting)
- Pertimbangkan deep learning untuk penangkapan pola kompleks
- Integrasikan variabel cuaca tambahan (kelembaban, tekanan atmosfer)
4. **Analisis Lanjutan**:
- Investigasi performa turbin di berbagai kondisi cuaca
- Analisis degradasi performa turbin dari waktu ke waktu
- Prediksi sisa umur komponen kritis berdasarkan data operasional
Model prediktif ini diharapkan dapat meningkatkan efisiensi operasional, mengurangi downtime, dan mengoptimalkan produksi energi dari turbin angin.