0% found this document useful (0 votes)
13 views4 pages

Erroe Metrics

The document describes a Python script that simulates rainfall data using a Markov Chain model with Gumbel copula functions. It generates realistic rainfall data, computes transition probabilities, and evaluates the performance of the simulated rainfall against observed data using various metrics. The script also includes visualizations comparing observed and simulated rainfall patterns.

Uploaded by

gunjanc080
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views4 pages

Erroe Metrics

The document describes a Python script that simulates rainfall data using a Markov Chain model with Gumbel copula functions. It generates realistic rainfall data, computes transition probabilities, and evaluates the performance of the simulated rainfall against observed data using various metrics. The script also includes visualizations comparing observed and simulated rainfall patterns.

Uploaded by

gunjanc080
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 4

import numpy as np

import matplotlib.pyplot as plt


from scipy.stats import spearmanr
from numpy import random
from sklearn.metrics import r2_score
import pandas as pd
# ------------------------------
# 1. Generate realistic rainfall data with more dry days
# ------------------------------
np.random.seed(42)

# Generate dry and wet spell lengths using a geometric distribution


dry_spell_lengths = np.random.geometric(p=0.9, size=50) # More frequent dry spells
wet_spell_lengths = np.random.geometric(p=0.2, size=10) # Less frequent wet spells

# Construct rainfall time series with float values (rainfall in mm)


rainfall_data = []
for dry, wet in zip(dry_spell_lengths, wet_spell_lengths):
rainfall_data.extend([0] * dry) # Add dry days (0 mm)
rainfall_data.extend(np.random.uniform(0, 50, size=wet)) # Add wet days
(continuous rainfall)
rainfall_data = np.array(rainfall_data)

df1 = pd.read_csv('D:\\pythonProject1\\venv\\Rain_imd\\IMD_DataSET\\annual.csv')
d2 = np.array(df1)

rainfall_data = d2[:, 7]
print("Observed Rainfall Data:")
print(rainfall_data, len(rainfall_data))

# ------------------------------
# 2. Compute transition probabilities
# ------------------------------
n = len(rainfall_data) - 1 # number of transitions
dry_prev = rainfall_data[:-1] == 0
wet_prev = rainfall_data[:-1] > 0
dry_curr = rainfall_data[1:] == 0
wet_curr = rainfall_data[1:] > 0

P_00 = np.sum(dry_prev & dry_curr) / n


P_01 = np.sum(dry_prev & wet_curr) / n
P_10 = np.sum(wet_prev & dry_curr) / n
P_11 = np.sum(wet_prev & wet_curr) / n

print("\nTransition Probabilities:")
print(f"P_00 (Dry-Dry): {P_00:.3f}")
print(f"P_01 (Dry-Wet): {P_01:.3f}")
print(f"P_10 (Wet-Dry): {P_10:.3f}")
print(f"P_11 (Wet-Wet): {P_11:.3f}")

# ------------------------------
# 3. Compute empirical CDFs
# ------------------------------
def empirical_cdf(data, x):
return np.count_nonzero(data <= x) / len(data)

H_x = lambda x: empirical_cdf(rainfall_data[:-1], x)


H_y = lambda y: empirical_cdf(rainfall_data[1:], y)
# Conditional CDFs for wet days (both consecutive days > 0)
wet_indices = (rainfall_data[:-1] > 0) & (rainfall_data[1:] > 0)
wet_x_data = rainfall_data[:-1][wet_indices]
wet_y_data = rainfall_data[1:][wet_indices]

# Estimate copula parameter using Spearman’s correlation for wet days


if len(wet_x_data) > 1:
rho, _ = spearmanr(wet_x_data, wet_y_data)
theta = 1 / (1 - rho) # Gumbel copula parameter
else:
theta = 1 # Default to independence if insufficient data

# ------------------------------
# 4. Gumbel Copula Functions
# ------------------------------

# Gumbel copula CDF


def gumbel_copula_cdf(u, v, theta):
if theta == 1:
return u * v # independent case
inner_term = ((-np.log(u))**theta + (-np.log(v))**theta)**(1/theta)
return np.exp(-inner_term)

# Partial derivative of Gumbel copula with respect to u


def gumbel_copula_partial_u(u, v, theta):
if theta == 1:
return v # independent case
inner_term = (-np.log(u))**theta + (-np.log(v))**theta
C_uv = gumbel_copula_cdf(u, v, theta)
return C_uv * ((-np.log(u))**(theta-1)) / (u * inner_term**(1 - 1/theta))

# Conditional CDF using Gumbel copula for a given x (if x > 0) and rainfall value y
def O_Y_given_X_x_and_X_positive(y, x):
u, v = H_x(x), H_y(y)
C_uv_partial = gumbel_copula_partial_u(u, v, theta)
h_x = np.count_nonzero(rainfall_data[:-1] == x) / len(rainfall_data[:-1]) if
len(rainfall_data[:-1]) > 0 else 0
f_y = np.count_nonzero(rainfall_data[1:] == y) / len(rainfall_data[1:]) if
len(rainfall_data[1:]) > 0 else 0
denom = P_10 * h_x + P_11 * f_y
return (P_10 * h_x + P_11 * f_y * C_uv_partial) / denom if denom > 0 else
H_y(y)

# Conditional CDF for X = 0 (when previous day is dry)


def O_Y_given_X_0(y):
denom = P_00 + P_01
return (P_00 + P_01 * H_y(y)) / denom if denom > 0 else H_y(y)

# ------------------------------
# 5. Generate Plots for Conditional CDF
# ------------------------------
y_values = np.linspace(0, max(rainfall_data), 100)
cdf_0 = np.array([O_Y_given_X_0(y) for y in y_values])
cdf_x_positive = np.array([O_Y_given_X_x_and_X_positive(y, 3) for y in y_values])

plt.figure(figsize=(10, 6))
plt.plot(y_values, cdf_0, label="O_Y_given_X=0", linestyle="--", linewidth=2)
plt.plot(y_values, cdf_x_positive, label="O_Y_given_X=x and X>0", linewidth=2)
plt.scatter(rainfall_data[1:], [O_Y_given_X_x_and_X_positive(y, 3) for y in
rainfall_data[1:]],
color='red', alpha=0.5, label="Observed Rainfall")
plt.xlabel('Rainfall (mm)')
plt.ylabel('Conditional CDF')
plt.legend()
plt.title('Conditional CDF of Y given X')
plt.grid()
# plt.show()

# ------------------------------
# 6. Simulate rainfall using the Markov Chain with Copula
# ------------------------------
simulated_rainfall = np.zeros(n, dtype=float)
simulated_rainfall[0] = rainfall_data[0] # start with the observed first day

# For wet days, sample intensities from the observed wet days
wet_intensities = rainfall_data[rainfall_data > 0]
if len(wet_intensities) == 0:
raise ValueError("No wet days found in observed data; cannot sample
intensities.")

# Simulate each day based on the previous day's state:


for i in range(1, n):
prev = simulated_rainfall[i-1]
r = np.random.rand() # uniform random number in [0,1)
if prev == 0:
# Previous day was dry: use transitions from a dry day.
if r < P_00:
simulated_rainfall[i] = 0
else:
simulated_rainfall[i] = np.random.choice(wet_intensities)
else:
# Previous day was wet: use transitions from a wet day.
if r < P_10:
simulated_rainfall[i] = 0
else:
simulated_rainfall[i] = np.random.choice(wet_intensities)

# Plot simulated vs observed rainfall


plt.figure(figsize=(10, 6))
plt.plot(rainfall_data, label="Observed Rainfall", marker="o", linestyle="-",
alpha=0.7)
plt.plot(simulated_rainfall, label="Simulated Rainfall", marker="x",
linestyle="--", alpha=0.7)
plt.xlabel("Time (days)")
plt.ylabel("Rainfall (mm)")
plt.title("Observed vs Simulated Rainfall")
plt.legend()
plt.grid(True)
# plt.show()

# ------------------------------
# 7. Calculate Performance Metrics
# ------------------------------
# For the performance metrics, we compare the simulated series with the
corresponding observed series.
# Note: simulated_rainfall has length n (which is len(rainfall_data)-1). We compare
it with the first n values.
observed = rainfall_data[:n]
simulated = simulated_rainfall

def nash_sutcliffe(observed, simulated):


return 1 - np.sum((observed - simulated)**2) / np.sum((observed -
np.mean(observed))**2)

def rmse(observed, simulated):


return np.sqrt(np.mean((observed - simulated)**2))

def pbias(observed, simulated):


return 100 * np.sum(simulated - observed) / np.sum(observed)

def kling_gupta_efficiency(observed, simulated):


r = np.corrcoef(observed, simulated)[0, 1]
alpha = np.std(simulated) / np.std(observed)
beta = np.mean(simulated) / np.mean(observed)
return 1 - np.sqrt((r - 1)**2 + (alpha - 1)**2 + (beta - 1)**2)

nse_val = nash_sutcliffe(observed, simulated)


rmse_val = rmse(observed, simulated)
pbias_val = pbias(observed, simulated)
r2_val = r2_score(observed, simulated)
kge_val = kling_gupta_efficiency(observed, simulated)

print("\nPerformance Metrics:")
print(f"Nash-Sutcliffe Efficiency (NSE): {nse_val:.3f}")
print(f"Root Mean Square Error (RMSE): {rmse_val:.3f}")
print(f"Percent Bias (PBIAS): {pbias_val:.3f}%")
print(f"R-squared (R²): {r2_val:.3f}")
print(f"Kling-Gupta Efficiency (KGE): {kge_val:.3f}")

n = len(simulated_rainfall) - 1 # number of transitions


dry_prev = simulated_rainfall[:-1] == 0
wet_prev = simulated_rainfall[:-1] > 0
dry_curr = simulated_rainfall[1:] == 0
wet_curr = simulated_rainfall[1:] > 0

P_00_sim = np.sum(dry_prev & dry_curr) / n


P_01_sim = np.sum(dry_prev & wet_curr) / n
P_10_sim = np.sum(wet_prev & dry_curr) / n
P_11_sim = np.sum(wet_prev & wet_curr) / n

print("\nTransition Probabilities for Simulation:")


print(f"P_00 (Dry-Dry): {P_00_sim:.3f}")
print(f"P_01 (Dry-Wet): {P_01_sim:.3f}")
print(f"P_10 (Wet-Dry): {P_10_sim:.3f}")
print(f"P_11 (Wet-Wet): {P_11_sim:.3f}")

plt.show()

You might also like