import numpy as np
import pandas as pd
import [Link] as plt
import seaborn as sns
from scipy import stats
from [Link] import mean_absolute_error, mean_squared_error
# Function to fit and transform data to uniform marginals
def fit_marginals(data):
shape, loc, scale = [Link](data['Rainfall'])
data['Rainfall_U'] = [Link](data['Rainfall'], shape, loc, scale)
mu, std = [Link](data['Temperature'])
data['Temperature_U'] = [Link](data['Temperature'], mu, std)
return data, (shape, loc, scale), (mu, std)
# Normal Copula Implementation
class NormalCopula:
def __init__(self, correlation_matrix):
self.correlation_matrix = correlation_matrix
def sample(self, n):
# Generate samples from multivariate normal distribution
mean = [Link](len(self.correlation_matrix))
samples = [Link].multivariate_normal(mean, self.correlation_matrix,
size=n)
# Apply the CDF to transform to uniform marginals
u_samples = [Link](samples)
return u_samples
# Generate synthetic data
[Link](42)
rainfall = [Link](2, 15, 1000)
temperature = [Link](20, 5, 1000)
data = [Link]({
'Rainfall': rainfall,
'Temperature': temperature
})
# Fit marginals and transform to uniform
data, gamma_params, norm_params = fit_marginals(data)
# Create the correlation matrix
correlation_matrix = [Link](data['Rainfall_U'], data['Temperature_U'])
# Initialize and sample from the Normal Copula
copula = NormalCopula(correlation_matrix)
samples = [Link](1000)
# Transform back to original scale using inverse CDF
def transform_samples(samples, gamma_params, norm_params):
df = [Link](samples, columns=['Rainfall_U', 'Temperature_U'])
df['Rainfall'] = [Link](df['Rainfall_U'], *gamma_params)
df['Temperature'] = [Link](df['Temperature_U'], *norm_params)
return df
samples_normal_df = transform_samples(samples, gamma_params, norm_params)
# Visualization
[Link](figsize=(12, 6))
[Link](data['Rainfall'], data['Temperature'], alpha=0.5, color='blue',
label='Original Data')
[Link](samples_normal_df['Rainfall'], samples_normal_df['Temperature'],
alpha=0.5, color='orange', label='Normal Copula Samples')
[Link]('Original Data vs. Normal Copula Samples')
[Link]('Rainfall')
[Link]('Temperature')
[Link]()
[Link]()
[Link]()
# Kernel Density Estimates for Rainfall
[Link](figsize=(12, 5))
[Link](data['Rainfall'], label='Original Rainfall', color='blue', fill=True,
alpha=0.5)
[Link](samples_normal_df['Rainfall'], label='Normal Copula', color='orange',
linestyle='--', fill=True, alpha=0.5)
[Link]('Rainfall Distribution Comparison')
[Link]('Rainfall')
[Link]('Density')
[Link]()
[Link]()
[Link]()
# Kernel Density Estimates for Temperature
[Link](figsize=(12, 5))
[Link](data['Temperature'], label='Original Temperature', color='blue',
fill=True, alpha=0.5)
[Link](samples_normal_df['Temperature'], label='Normal Copula',
color='orange', linestyle='--', fill=True, alpha=0.5)
[Link]('Temperature Distribution Comparison')
[Link]('Temperature')
[Link]('Density')
[Link]()
[Link]()
[Link]()
# Comparison metrics for rainfall and temperature
def calculate_metrics(original, simulated):
mae_rainfall = mean_absolute_error(original['Rainfall'], simulated['Rainfall'])
mse_rainfall = mean_squared_error(original['Rainfall'], simulated['Rainfall'])
rmse_rainfall = [Link](mse_rainfall)
mae_temperature = mean_absolute_error(original['Temperature'],
simulated['Temperature'])
mse_temperature = mean_squared_error(original['Temperature'],
simulated['Temperature'])
rmse_temperature = [Link](mse_temperature)
return mae_rainfall, mse_rainfall, rmse_rainfall, mae_temperature,
mse_temperature, rmse_temperature
mae_rainfall, mse_rainfall, rmse_rainfall, mae_temperature, mse_temperature,
rmse_temperature = calculate_metrics(data, samples_normal_df)
# Print comparison metrics
print(f'Comparison Metrics for Normal Copula:')
print(f'Mean Absolute Error (MAE) - Rainfall: {mae_rainfall:.2f}')
print(f'Mean Squared Error (MSE) - Rainfall: {mse_rainfall:.2f}')
print(f'Root Mean Squared Error (RMSE) - Rainfall: {rmse_rainfall:.2f}')
print(f'Mean Absolute Error (MAE) - Temperature: {mae_temperature:.2f}')
print(f'Mean Squared Error (MSE) - Temperature: {mse_temperature:.2f}')
print(f'Root Mean Squared Error (RMSE): {rmse_temperature:.2f}')
# AIC and BIC calculations
def calculate_aic_bic(original, simulated):
n = len(original)
rss = [Link]((original - simulated) ** 2)
k = 2 # number of parameters in the model (simplified)
aic = n * [Link](rss/n) + 2 * k
bic = n * [Link](rss/n) + k * [Link](n)
return aic, bic
aic_rainfall, bic_rainfall = calculate_aic_bic(data['Rainfall'],
samples_normal_df['Rainfall'])
aic_temperature, bic_temperature = calculate_aic_bic(data['Temperature'],
samples_normal_df['Temperature'])
# Print AIC and BIC
print(f'\nAIC and BIC for Normal Copula:')
print(f'AIC - Rainfall: {aic_rainfall:.2f}, BIC: {bic_rainfall:.2f}')
print(f'AIC - Temperature: {aic_temperature:.2f}, BIC: {bic_temperature:.2f}')
# Print parameters of the copula
print(f'\nNormal Copula Parameters:')
print(f'Correlation Matrix:\n{correlation_matrix}')