Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Negative loss amounts in BootstrapODPSample #449

Open
cmds2k opened this issue Aug 3, 2023 · 2 comments
Open

[BUG] Negative loss amounts in BootstrapODPSample #449

cmds2k opened this issue Aug 3, 2023 · 2 comments
Assignees
Labels

Comments

@cmds2k
Copy link

cmds2k commented Aug 3, 2023

BootstrapODPSample creates samples with negative loss amounts. This leads to negative ldfs, cdfs and ultimates. There should be a way to keep samples with positive losses only.

@kennethshsu
Copy link
Collaborator

Hi @cmds2k, can you share some code examples?

@ntwong319
Copy link

ntwong319 commented Dec 21, 2023

Hi @kennethshsu I wanted to bring up this bug. I was running an ODP bootstrapping on our dataset and ran into the same issue OP posted about. Here are some snippets of my code:


samples_cdf = cl.Development(drop_high=True, drop_low=True,average='volume').fit(samples).cdf_

pipe = cl.Pipeline(
    [('dev', cl.Development(drop_high=True, drop_low=True,average='volume')),
     ('tail', cl.TailConstant(1.00)),
     ('model', cl.Chainladder())]).fit(samples)

resampled_ldf = pipe.named_steps.dev.ldf_

from scipy.stats.mstats import winsorize

fig, axes = plt.subplots(4, 4, figsize=(30, 12))
axes = axes.flatten()
#percentile_50_values = []

for x in range(16):
    # Apply winsorization to your data
    winsorized_data = winsorize(pd.Series(resampled_ldf.values[:, 0, 0, x]), limits=(0.01, 0.01))  # Adjust the limits as needed

    # Plot the histogram with winsorized data
    pd.Series(winsorized_data).plot(kind='hist', bins=100, ax=axes[x])
    axes[x].set_title(f'Age {(x+1)*3}-{(x+1)*3+3} LDF distribution using Bootstrap')
    axes[x].axvline(orig_dev.values[0, 0, 0, x], color="black", linestyle="dashed")

    # Calculate and display the 75th percentile
    percentile_75 = np.percentile(winsorized_data, 75)
    axes[x].text(0.6, 0.7, f"75th Percentile: {percentile_75:.3f}", transform=axes[x].transAxes)

    percentile_50 = np.percentile(winsorized_data, 50)
    axes[x].text(0.6, 0.8, f"50th Percentile: {percentile_50:.3f}", transform=axes[x].transAxes)

    # Display the original value
    axes[x].text(0.6, 0.9, f"Original LDF: {round(orig_dev.values[0, 0, 0, x], 4)}", transform=axes[x].transAxes)

    percentile_50 = np.percentile(winsorized_data, 50)
    

fig.suptitle("LDFs Using ODP Bootstrap")

# Add a common y-label for all subplots
fig.text(0.5, 0.04, 'Value', ha='center')
plt.subplots_adjust(wspace=0.3, hspace=0.3)

# Show the figure
plt.show()

And it generated this LDF distribution plot for the 24-27 factor.
Negative LDF

Additionally, I wanted to see what the minimum IBNR produced by this command was:

pipe.predict(net["REP_LALAE"]).ibnr_.min()

And the output was
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants