Dalam notebook ini, kita akan mengimplementasikan neural network untuk data tabular menggunakan TensorFlow. Contoh ini menunjukkan langkah-langkah lengkap dari persiapan data hingga evaluasi model.
1. Import Library yang Diperlukan
Pertama, kita perlu mengimpor library-library yang akan digunakan dalam proyek ini.
# Import library yang diperlukanimport numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport seaborn as snsimport tensorflow as tffrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScaler, OneHotEncoderfrom sklearn.compose import ColumnTransformerfrom sklearn.pipeline import Pipelinefrom sklearn.impute import SimpleImputerfrom sklearn.metrics import mean_squared_error, mean_absolute_error, r2_scorefrom sklearn.metrics import accuracy_score, classification_report, confusion_matrix# Memeriksa versi TensorFlowprint(f"TensorFlow version: {tf.__version__}")# Set random seed untuk reproducibilitynp.random.seed(42)tf.random.set_seed(42)
WARNING:tensorflow:From c:\Users\derik\anaconda3\Lib\site-packages\keras\src\losses.py:2976: The name tf.losses.sparse_softmax_cross_entropy is deprecated. Please use tf.compat.v1.losses.sparse_softmax_cross_entropy instead.
TensorFlow version: 2.15.0
2. Memuat dan Mengeksplorasi Dataset
Untuk contoh ini, kita akan menggunakan dataset California Housing dari scikit-learn, yang merupakan contoh data tabular untuk masalah regresi.
# Memuat dataset California Housingfrom sklearn.datasets import fetch_california_housinghousing = fetch_california_housing()X = pd.DataFrame(housing.data, columns=housing.feature_names)y = housing.target# Melihat beberapa data awalprint("Shape of features:", X.shape)print("Shape of target:", y.shape)print("\nFeature names:", housing.feature_names)print("\nSample data:")display(X.head())# Statistik deskriptifprint("\nStatistik deskriptif:")display(X.describe())# Histogram target variableplt.figure(figsize=(10, 6))plt.hist(y, bins=30)plt.title('Distribusi Harga Rumah')plt.xlabel('Nilai Median Rumah (dalam $100,000)')plt.ylabel('Frekuensi')plt.show()
Mari kita analisis korelasi antara fitur dan target.
# Analisis korelasidata_corr = pd.DataFrame(X.copy())data_corr['PRICE'] = yplt.figure(figsize=(12, 10))correlation_matrix = data_corr.corr()sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', fmt='.2f')plt.title('Matriks Korelasi')plt.tight_layout()plt.show()# Plot scatter untuk beberapa fitur terhadap hargafig, axes = plt.subplots(2, 4, figsize=(20, 10))axes = axes.flatten()for i, feature inenumerate(housing.feature_names): axes[i].scatter(X[feature], y, alpha=0.5) axes[i].set_xlabel(feature) axes[i].set_ylabel('Price') axes[i].set_title(f'{feature} vs Price')plt.tight_layout()plt.show()
4. Pra-pemrosesan Data
Sebelum melatih model, kita perlu memisahkan data menjadi set pelatihan dan pengujian, serta melakukan normalisasi fitur.
# Memisahkan data menjadi set pelatihan dan pengujianX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# Membuat pipeline untuk pra-pemrosesan numeriknumeric_features = X.columns.tolist()numeric_transformer = Pipeline(steps=[ ('imputer', SimpleImputer(strategy='median')), ('scaler', StandardScaler())])# Membuat preprocessor dengan ColumnTransformerpreprocessor = ColumnTransformer( transformers=[ ('num', numeric_transformer, numeric_features) ])# Menerapkan preprocessingX_train_processed = preprocessor.fit_transform(X_train)X_test_processed = preprocessor.transform(X_test)print("Shape setelah preprocessing:")print("X_train:", X_train_processed.shape)print("X_test:", X_test_processed.shape)
Shape setelah preprocessing:
X_train: (16512, 8)
X_test: (4128, 8)
5. Membangun Model Neural Network
Sekarang, kita akan membangun model neural network menggunakan TensorFlow dan Keras.
# Fungsi untuk membuat model neural networkdef build_model(input_shape, layers=[64, 32], activation='relu', learning_rate=0.001, dropout_rate=0.2): model = tf.keras.Sequential()# Input layer model.add(tf.keras.layers.InputLayer(input_shape=input_shape))# Hidden layersfor units in layers: model.add(tf.keras.layers.Dense(units, activation=activation)) model.add(tf.keras.layers.BatchNormalization()) model.add(tf.keras.layers.Dropout(dropout_rate))# Output layer (untuk regresi) model.add(tf.keras.layers.Dense(1))# Kompilasi model model.compile( optimizer=tf.keras.optimizers.Adam(learning_rate=learning_rate), loss='mse', metrics=['mae'] )return model# Membangun modelinput_shape = (X_train_processed.shape[1],)model = build_model(input_shape, layers=[128, 64, 32], dropout_rate=0.3)# Menampilkan ringkasan arsitektur modelmodel.summary()
Selanjutnya, kita akan melatih model dengan data yang telah diproses.
# Mengonfigurasi early stopping untuk mencegah overfittingearly_stopping = tf.keras.callbacks.EarlyStopping( monitor='val_loss', patience=10, restore_best_weights=True)# Mengonfigurasi model checkpoint untuk menyimpan model terbaikmodel_checkpoint = tf.keras.callbacks.ModelCheckpoint('best_model.h5', monitor='val_loss', save_best_only=True, verbose=1)# Proses pelatihan modelhistory = model.fit( X_train_processed, y_train, epochs=100, batch_size=32, validation_split=0.2, callbacks=[early_stopping, model_checkpoint], verbose=1)
Epoch 1/100
WARNING:tensorflow:From c:\Users\derik\anaconda3\Lib\site-packages\keras\src\utils\tf_utils.py:492: The name tf.ragged.RaggedTensorValue is deprecated. Please use tf.compat.v1.ragged.RaggedTensorValue instead.
WARNING:tensorflow:From c:\Users\derik\anaconda3\Lib\site-packages\keras\src\engine\base_layer_utils.py:384: The name tf.executing_eagerly_outside_functions is deprecated. Please use tf.compat.v1.executing_eagerly_outside_functions instead.
403/413 [============================>.] - ETA: 0s - loss: 2.9026 - mae: 1.3022
Epoch 1: val_loss improved from inf to 0.70579, saving model to best_model.h5
413/413 [==============================] - 2s 2ms/step - loss: 2.8669 - mae: 1.2926 - val_loss: 0.7058 - val_mae: 0.6160
Epoch 2/100
49/413 [==>...........................] - ETA: 0s - loss: 1.3317 - mae: 0.8827
c:\Users\derik\anaconda3\Lib\site-packages\keras\src\engine\training.py:3103: UserWarning: You are saving your model as an HDF5 file via `model.save()`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')`.
saving_api.save_model(
Terakhir, kita akan menyimpan model terbaik kita dan menunjukkan cara memuatnya kembali.
# Menyimpan model terbaikmodel.save('housing_price_model.h5')print("Model telah disimpan sebagai 'housing_price_model.h5'")# Memuat model yang telah disimpanloaded_model = tf.keras.models.load_model('housing_price_model.h5')print("Model berhasil dimuat kembali!")# Verifikasi performa model yang dimuaty_pred_loaded = loaded_model.predict(X_test_processed).flatten()rmse_loaded = np.sqrt(mean_squared_error(y_test, y_pred_loaded))print(f"RMSE dari model yang dimuat: {rmse_loaded:.4f}")
Model telah disimpan sebagai 'housing_price_model.h5'
c:\Users\derik\anaconda3\Lib\site-packages\keras\src\engine\training.py:3103: UserWarning: You are saving your model as an HDF5 file via `model.save()`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')`.
saving_api.save_model(
Model berhasil dimuat kembali!
129/129 [==============================] - 0s 574us/step
129/129 [==============================] - 0s 574us/step
RMSE dari model yang dimuat: 0.5842
RMSE dari model yang dimuat: 0.5842
11. Contoh Implementasi: Memprediksi Harga Baru
Mari kita buat sebuah fungsi untuk memprediksi harga berdasarkan fitur-fitur baru.
# Fungsi untuk memprediksi harga rumah barudef predict_house_price(model, preprocessor, features):""" Memprediksi harga rumah berdasarkan fitur yang diberikan. Parameters: ----------- model : model Keras Model neural network yang telah dilatih preprocessor : ColumnTransformer Preprocessor data yang telah dilatih features : dict Dictionary berisi fitur rumah dengan format {nama_fitur: nilai} Returns: -------- float : Prediksi harga rumah (dalam $100,000) """# Konversi fitur ke DataFrame features_df = pd.DataFrame([features])# Preprocessor fitur processed_features = preprocessor.transform(features_df)# Prediksi prediction = model.predict(processed_features).flatten()[0]return prediction# Contoh fitur rumah barunew_house_features = {'MedInc': 3.5, # Median income'HouseAge': 25.0, # Usia rumah'AveRooms': 5.0, # Rata-rata jumlah ruangan'AveBedrms': 2.0, # Rata-rata jumlah kamar tidur'Population': 1500.0, # Populasi'AveOccup': 3.0, # Rata-rata penghuni'Latitude': 34.0, # Latitude'Longitude': -118.0# Longitude}# Prediksi hargapredicted_price = predict_house_price(model, preprocessor, new_house_features)print(f"Harga rumah yang diprediksi: ${predicted_price *100000:.2f}")# Coba beberapa variasi inputvariations = [ {'MedInc': 8.0, 'HouseAge': 5.0, 'AveRooms': 7.0, 'AveBedrms': 3.0, 'Population': 1000.0, 'AveOccup': 2.5, 'Latitude': 34.0, 'Longitude': -118.0}, {'MedInc': 2.0, 'HouseAge': 40.0, 'AveRooms': 4.0, 'AveBedrms': 1.5, 'Population': 2000.0, 'AveOccup': 4.0, 'Latitude': 34.0, 'Longitude': -118.0}, {'MedInc': 5.0, 'HouseAge': 15.0, 'AveRooms': 6.0, 'AveBedrms': 2.0, 'Population': 1500.0, 'AveOccup': 3.0, 'Latitude': 37.0, 'Longitude': -122.0}]for i, var inenumerate(variations): price = predict_house_price(model, preprocessor, var)print(f"Variasi {i+1}: ${price *100000:.2f}")
Dalam notebook ini, kita telah: 1. Mengimplementasikan neural network untuk data tabular menggunakan TensorFlow 2. Melakukan exploratory data analysis pada dataset perumahan California 3. Memproses dan membagi data untuk training dan testing 4. Membangun, melatih, dan mengevaluasi model neural network 5. Melakukan eksperimen dengan hyperparameter untuk meningkatkan performa 6. Menyimpan dan memuat model yang telah dilatih 7. Menunjukkan cara membuat prediksi dengan model yang telah dilatih
Untuk peningkatan lebih lanjut, kita bisa: - Mencoba arsitektur model yang lebih kompleks - Menerapkan cross-validation untuk evaluasi yang lebih robust - Menggunakan teknik regularisasi yang lebih canggih - Mencoba teknik feature engineering lanjutan
9a. Eksperimen dengan Fungsi Aktivasi
Mari kita coba berbagai fungsi aktivasi untuk melihat bagaimana pengaruhnya terhadap performa model.
Fungsi aktivasi yang akan kita coba: 1. ReLU (Rectified Linear Unit) - Default 2. Sigmoid 3. Tanh (Hyperbolic Tangent) 4. ELU (Exponential Linear Unit) 5. LeakyReLU 6. SELU (Scaled Exponential Linear Unit)
# Fungsi untuk eksperimen dengan fungsi aktivasidef experiment_activation(activation, custom_layer=None):""" Eksperimen dengan berbagai fungsi aktivasi Parameters: ----------- activation : str atau callable Nama fungsi aktivasi atau fungsi aktivasi khusus custom_layer : object, optional Layer khusus jika diperlukan (misalnya untuk LeakyReLU) Returns: -------- dict : Dictionary berisi hasil eksperimen """# Nama untuk displayifisinstance(activation, str): activation_name = activationelse: activation_name = activation.__name__ifhasattr(activation, '__name__') else'Custom'print(f"\nPerlatihan model dengan aktivasi: {activation_name}")# Membangun model dengan fungsi aktivasi yang diberikanif custom_layer:# Cara khusus untuk layer seperti LeakyReLUdef build_custom_model(input_shape, layers=[64, 32], learning_rate=0.001, dropout_rate=0.2): model = tf.keras.Sequential() model.add(tf.keras.layers.InputLayer(input_shape=input_shape))for units in layers: model.add(tf.keras.layers.Dense(units))# Menambahkan layer aktivasi khusus model.add(custom_layer) model.add(tf.keras.layers.BatchNormalization()) model.add(tf.keras.layers.Dropout(dropout_rate)) model.add(tf.keras.layers.Dense(1)) model.compile( optimizer=tf.keras.optimizers.Adam(learning_rate=learning_rate), loss='mse', metrics=['mae'] )return model model = build_custom_model( input_shape=(X_train_processed.shape[1],), layers=[128, 64], dropout_rate=0.3 )else:# Untuk fungsi aktivasi standard model = build_model( input_shape=(X_train_processed.shape[1],), layers=[128, 64], activation=activation, dropout_rate=0.3 )# Melatih model history = model.fit( X_train_processed, y_train, epochs=30, # Mengurangi epochs untuk eksperimen batch_size=32, validation_split=0.2, callbacks=[early_stopping], verbose=1 )# Evaluasi model y_pred = model.predict(X_test_processed).flatten() mse = mean_squared_error(y_test, y_pred) rmse = np.sqrt(mse) mae = mean_absolute_error(y_test, y_pred) r2 = r2_score(y_test, y_pred)return {'activation': activation_name,'mse': mse,'rmse': rmse,'mae': mae,'r2': r2,'best_val_loss': min(history.history['val_loss']),'best_val_mae': min(history.history['val_mae']),'epochs_trained': len(history.history['loss']),'history': history }# Daftar fungsi aktivasi yang akan diujiactivation_experiments = [ experiment_activation('relu'), experiment_activation('sigmoid'), experiment_activation('tanh'), experiment_activation('elu'), experiment_activation(None, custom_layer=tf.keras.layers.LeakyReLU(alpha=0.1)), experiment_activation('selu')]# Membuat DataFrame hasilactivation_results = pd.DataFrame([ {k: v for k, v in exp.items() if k !='history'} for exp in activation_experiments])# Tampilkan hasilprint("\n=== Hasil Eksperimen Fungsi Aktivasi ===")display(activation_results[['activation', 'rmse', 'r2', 'mae', 'epochs_trained']])# Visualisasi perbandingan RMSEplt.figure(figsize=(12, 6))plt.bar(activation_results['activation'], activation_results['rmse'])plt.title('RMSE untuk Berbagai Fungsi Aktivasi')plt.ylabel('RMSE (Root Mean Squared Error)')plt.xlabel('Fungsi Aktivasi')plt.xticks(rotation=45)plt.grid(axis='y')plt.tight_layout()plt.show()# Visualisasi perbandingan R²plt.figure(figsize=(12, 6))plt.bar(activation_results['activation'], activation_results['r2'])plt.title('R² Score untuk Berbagai Fungsi Aktivasi')plt.ylabel('R² Score')plt.xlabel('Fungsi Aktivasi')plt.xticks(rotation=45)plt.grid(axis='y')plt.tight_layout()plt.show()# Plot learning curves untuk fungsi aktivasi terbaik dan terburukplt.figure(figsize=(15, 10))# Mencari indeks fungsi aktivasi terbaik dan terburuk berdasarkan RMSEbest_idx = activation_results['rmse'].idxmin()worst_idx = activation_results['rmse'].idxmax()best_activation = activation_experiments[best_idx]worst_activation = activation_experiments[worst_idx]# Learning curve untuk lossplt.subplot(2, 2, 1)plt.plot(best_activation['history'].history['loss'], label=f"Training ({best_activation['activation']})")plt.plot(best_activation['history'].history['val_loss'], label=f"Validation ({best_activation['activation']})")plt.plot(worst_activation['history'].history['loss'], label=f"Training ({worst_activation['activation']})", linestyle='--')plt.plot(worst_activation['history'].history['val_loss'], label=f"Validation ({worst_activation['activation']})", linestyle='--')plt.title('Learning Curves: Loss')plt.xlabel('Epoch')plt.ylabel('Loss (MSE)')plt.legend()plt.grid(True)# Learning curve untuk MAEplt.subplot(2, 2, 2)plt.plot(best_activation['history'].history['mae'], label=f"Training ({best_activation['activation']})")plt.plot(best_activation['history'].history['val_mae'], label=f"Validation ({best_activation['activation']})")plt.plot(worst_activation['history'].history['mae'], label=f"Training ({worst_activation['activation']})", linestyle='--')plt.plot(worst_activation['history'].history['val_mae'], label=f"Validation ({worst_activation['activation']})", linestyle='--')plt.title('Learning Curves: MAE')plt.xlabel('Epoch')plt.ylabel('Mean Absolute Error')plt.legend()plt.grid(True)# Visualisasi prediksi untuk fungsi aktivasi terbaikplt.subplot(2, 2, 3)plt.scatter(y_test, best_activation['history'].model.predict(X_test_processed).flatten(), alpha=0.5)plt.plot([min(y_test), max(y_test)], [min(y_test), max(y_test)], color='red', linestyle='--')plt.title(f'Prediksi dengan {best_activation["activation"]} (Terbaik)')plt.xlabel('Nilai Sebenarnya')plt.ylabel('Prediksi')plt.grid(True)# Visualisasi prediksi untuk fungsi aktivasi terburukplt.subplot(2, 2, 4)plt.scatter(y_test, worst_activation['history'].model.predict(X_test_processed).flatten(), alpha=0.5)plt.plot([min(y_test), max(y_test)], [min(y_test), max(y_test)], color='red', linestyle='--')plt.title(f'Prediksi dengan {worst_activation["activation"]} (Terburuk)')plt.xlabel('Nilai Sebenarnya')plt.ylabel('Prediksi')plt.grid(True)plt.tight_layout()plt.show()print(f"\nFungsi aktivasi terbaik berdasarkan RMSE: {best_activation['activation']} (RMSE = {best_activation['rmse']:.4f})")print(f"Fungsi aktivasi terburuk berdasarkan RMSE: {worst_activation['activation']} (RMSE = {worst_activation['rmse']:.4f})")