Tutorials › CAS Exam 8 - Advanced Ratemaking › Version Control for Data, Code, and Models

CAS Exam 8 · Data and Model Governance · Tutorial 946 of 989

Version Control for Data, Code, and Models

Build a traceable ratemaking release by binding its data, code, configuration, and model output to explicit, preserved versions.

Intermediate 13 min read

What You'll Learn

  • Distinguish data snapshots, code versions, model artifacts, and release identifiers.
  • Construct a version manifest that links a ratemaking result to its exact inputs and implementation.
  • Trace a data correction or code change through to its effect on indicated rates.
  • Check release identity and arithmetic without mistaking a version label for proof of correctness.
  • Avoid common version-control errors such as mutable input files and unrecorded configuration changes.

Why Version Control Matters in Ratemaking

A ratemaking result is not fully traceable just because someone saved a spreadsheet or wrote down a model name. To reproduce the result, a reviewer needs to identify the exact data used, the code and configuration that processed it, and the model output that was approved for use. If any of those elements can change without a new identifier, a later user may unknowingly produce a different result while believing they have repeated the original analysis.

Version control provides a disciplined way to identify and preserve those elements. A data snapshot preserves a particular set of records. A code repository records changes to the implementation. A model identifier connects a specific model build and its settings to the result it produced. Together, these controls make it possible to determine what was run, reproduce it, and distinguish it from a later version. This is aligned with the CAS Exam 8 (Advanced Ratemaking) syllabus.

Definition: A traceable ratemaking release is a preserved result linked to uniquely identified versions of its input data, analysis code, configuration, and model artifact, along with the execution details needed to interpret the result. A version label is useful only if it points consistently to those preserved items.

The Components of a Traceable Release

A practical release record should distinguish components that are often incorrectly bundled under the word “model.” A model specification, the code that implements it, and the dataset on which it was run are different things and can change independently.

ComponentWhat it identifiesExample control
Data snapshotThe exact records and fields supplied to the analysisPreserved file or table export, unique snapshot ID, and content checksum
Code versionThe source code used to clean, transform, fit, or calculateRepository commit identifier and preserved repository history
ConfigurationSettings that affect execution, such as date ranges, selections, or factor choicesVersioned configuration file or recorded parameter values
Model artifactThe fitted model or other saved model object, if the workflow creates oneUnique artifact ID linked to its inputs and build
Release recordThe approved result and the identities of all components that produced itRelease ID and manifest

An immutable snapshot is preserved so its contents do not silently change after analysis. A common implementation is to save a read-only export and record a checksum: a value calculated from the file's contents that can be recalculated later to check whether those contents match. A checksum can reveal an accidental change, but it does not establish that the original data were accurate, complete, or appropriate. Data-quality review remains necessary.

A repository commit identifies a particular state of source code. A branch or tag name can be moved, so the commit identifier is more reliable evidence of the exact code than a label such as “current” or “final.” Dependencies and runtime settings may also affect results; where they matter, preserve their versions or a dependency lock file. Configuration values must be versioned or recorded as well: a fixed code commit does not fix a manually entered parameter.

A model ID should not be reused for a materially different build. It can identify the fitted artifact itself, while a separate release ID identifies the complete package of inputs, code, settings, and output. Whatever naming convention is used, it should unambiguously link the result to the exact components. Keep the preserved objects under appropriate access and retention controls; calling a file immutable does not remove the need to manage it securely.

Why the Link Must Be Complete

Let \(D\) denote the data snapshot, \(C\) the code version, \(K\) the configuration, and \(E\) the relevant execution environment. A ratemaking output can be represented as \(R=f(D,C,K,E)\). This notation does not assume that every workflow uses the same software or model. It expresses the basic dependency: the result is produced by applying a particular implementation and set of settings to particular data in a particular environment.

$$ R=f(D,C,K,E) $$

The traceability requirement follows directly. If the data change, then \(D\) is different; if the source code changes, then \(C\) is different; if a setting changes, then \(K\) is different. Unless it is established that a change cannot affect the output, the result cannot be assumed to be the same. Therefore, a release that records only the data filename or only the model name leaves an important part of the calculation unidentified.

A content checksum strengthens this link. Recalculating a checksum on a preserved file and comparing it with the recorded value tests whether the file contents are unchanged. Likewise, a repository commit identifies the source state to retrieve. Neither check proves that the selected source data, code, or assumptions are substantively correct. Version control answers “which one?”; review and validation address “is it fit for use?”

1
Freeze and identify inputs.
Preserve the analysis dataset as a snapshot, record its ID and checksum, and state the period and included records that the snapshot represents.
2
Identify implementation and settings.
Record the repository commit, relevant dependencies, configuration, and any other execution settings that could affect the result.
3
Save and link the output.
Assign the model artifact and release unique identifiers, and record the output's relationship to the exact inputs and implementation.
4
Verify before relying on a result.
Retrieve the identified components, compare checksums and version identifiers, and confirm that the recorded calculation agrees with the released output.

Worked Examples

Worked Example: Tracing a Corrected Data Snapshot

A hypothetical insurer calculates a portfolio pure premium as total losses divided by earned exposure. Its first release uses snapshot SNAP-31, containing $540,000 of losses and 900 earned exposure years. The code commit is c71a, and the configuration is CFG-4. A reviewed correction adds $18,000 of losses, producing snapshot SNAP-32. The code and configuration do not change. Identify the first result, the corrected result, and the versioning action required.

Method. Calculate each pure premium using the same stated formula, then identify which release components changed.

First release. Divide the original losses by the original exposure:

$$ \frac{\$540{,}000}{900\text{ earned exposure years}} =\$600\text{ per earned exposure year}. $$

Corrected snapshot. First calculate corrected losses: $540,000 + $18,000 = $558,000. Exposure remains 900 earned exposure years. The corrected pure premium is:

$$ \frac{\$558{,}000}{900\text{ earned exposure years}} =\$620\text{ per earned exposure year}. $$

The result increases by $620 - $600 = $20 per earned exposure year. The data snapshot changed from SNAP-31 to SNAP-32; the code commit c71a and configuration CFG-4 remained the same. The corrected result therefore needs a distinct release identity linked to SNAP-32, c71a, CFG-4, and its output. The old release should remain identifiable rather than being overwritten.

Check. $620 multiplied by 900 earned exposure years is $558,000, matching the corrected losses. The common mistake is to replace the old dataset in place while leaving the old release label unchanged. That makes the historical $600 result impossible to tie reliably to its original inputs.

Worked Example: Isolating a Code Change

A hypothetical rating analysis uses snapshot SNAP-52 with 42 claims and 700 earned exposure years. Average severity is $8,400. Code commit e210 calculates pure premium as claim frequency multiplied by average severity without a severity trend adjustment. A revised commit, e211, applies a versioned severity trend factor of 1.05. Calculate both results and state what must be recorded to distinguish them.

Method. Calculate frequency from claims divided by exposure, then multiply by average severity. For the revised calculation, apply the trend factor to severity before multiplying by frequency.

Frequency.

$$ \frac{42\text{ claims}}{700\text{ earned exposure years}} =0.06\text{ claims per earned exposure year}. $$

Result under e210. There is no trend adjustment, so adjusted severity is $8,400. Thus:

$$ 0.06\times \$8{,}400=\$504\text{ per earned exposure year}. $$

Result under e211. Adjusted severity is $8,400 × 1.05 = $8,820. Therefore:

$$ 0.06\times \$8{,}820=\$529.20\text{ per earned exposure year}. $$

The difference is $529.20 - $504 = $25.20 per earned exposure year. The snapshot is unchanged, but the code version and trend setting differ. The revised release must identify e211 and the factor 1.05, as well as SNAP-52 and the output. If the factor is in a separate configuration file, that file's version or the exact recorded value must be linked too.

Check. Under e211, $529.20 equals the original $504 multiplied by 1.05. The common mistake is to report a new result under the old model or release identity because the dataset did not change. A code or setting change can change the result even when the input data are identical.

Worked Example: Checking a Complete Release Record

A hypothetical release uses 36 claims, 600 earned exposure years, and an average severity of $7,500. Its versioned configuration applies a severity trend factor of 1.04 and an expense loading factor of 1.10. The release manifest identifies snapshot SNAP-88, commit f430, configuration CFG-12, model artifact MOD-207, and release REL-207. Calculate the indicated amount per earned exposure year and assess a proposed output of $514.80.

Method. Calculate claim frequency, trend-adjusted severity, pure premium, and then apply the stated expense loading factor. The factor 1.10 multiplies the pure premium; it is not a 10% addition followed by a second multiplication.

Frequency.

$$ \frac{36}{600}=0.06\text{ claims per earned exposure year}. $$

Trend-adjusted severity. $7,500 × 1.04 = $7,800. The pure premium is $0.06 × $7,800 = $468 per earned exposure year. Applying the expense loading gives:

$$ \$468\times 1.10=\$514.80\text{ per earned exposure year}. $$

The proposed output of $514.80 agrees with the calculation. The manifest identifies each component needed to locate the release inputs and implementation: SNAP-88, f430, CFG-12, and MOD-207, all linked by REL-207. To check the data file itself, retrieve SNAP-88 and compare its checksum with the checksum preserved in the manifest. A matching checksum supports the conclusion that the retrieved file is unchanged; it does not by itself validate the claims or the factor choices.

Check. The arithmetic reproduces $514.80, and the manifest provides a complete set of identifiers for this example. The common mistake is to see a correct calculation and assume it is traceable. Correct arithmetic is not enough if the data, code, or settings that produced it cannot be identified.

Common Version-Control Traps

  • Overwriting a file while keeping its name. A filename such as “latest_data.csv” does not establish which contents were used. Preserve a distinct snapshot and record its identity.
  • Relying on a branch or informal label. “Approved,” “production,” or “final” may not uniquely identify source code over time. Record the repository commit and maintain the referenced source.
  • Versioning code but not settings. A fixed commit can produce different outputs when a date range, factor, or selection parameter changes. Record those settings as versioned inputs.
  • Reusing a model or release ID. If a new dataset or implementation produces a new result, it must be possible to distinguish that result from the prior one.
  • Treating a checksum as quality assurance. A checksum can detect a changed file; it cannot establish that the file is complete, correctly prepared, or suitable for ratemaking.

These controls are valuable when a result must be reproduced, compared with a later indication, or explained to a reviewer. Version control makes the chain of evidence specific: not merely “the model was run,” but which preserved data and implementation produced which result. It also supports a clean comparison when only one component changes, such as SNAP-31 to SNAP-32 in the first example or e210 to e211 in the second.

Key takeaway: Give each material data snapshot, code state, configuration, model artifact, and release a stable identity. Preserve the referenced components and link them in one record so a result can be traced to its exact inputs and implementation.

Check Your Understanding

For each problem, identify the relevant version-control issue as well as the requested calculation.

  1. A hypothetical book has $312,000 of losses and 520 earned exposure years in snapshot S-6. A corrected snapshot adds $10,400 of losses, with exposure unchanged. Calculate both pure premiums and identify what must change in the release record. (Answer: S-6 is $600 per earned exposure year; the corrected result is $620 per earned exposure year, and the new snapshot and release must be identified.)
  2. A hypothetical analysis has 24 claims over 400 earned exposure years and average severity of $6,000. A code change multiplies severity by 1.10. Calculate the unadjusted and adjusted pure premiums. (Answer: Frequency is 0.06; unadjusted pure premium is $360 and adjusted pure premium is $396 per earned exposure year.)
  3. A result record identifies a dataset filename, “approved” code branch, and output, but no snapshot ID, commit, or configuration. Name three missing identifiers or controls needed to make the result more traceable. (Answer: A preserved and identified data snapshot with checksum, a specific code commit, and a recorded or versioned configuration.)
  4. A hypothetical release has 30 claims, 500 earned exposure years, average severity of $8,000, trend factor 1.05, and expense loading factor 1.08. Calculate the loaded amount per earned exposure year. (Answer: Frequency is 0.06; adjusted severity is $8,400; pure premium is $504; loaded amount is $544.32 per earned exposure year.)
  5. A reviewer retrieves a dataset and its checksum matches the checksum in the release manifest. What does this support, and what does it not establish? (Answer: It supports that the retrieved contents match the recorded snapshot; it does not establish that the data are accurate, complete, or appropriate.)
Clinical Biostats