# Data Science mathematical foundations lab

Original synthetic numerical examples supporting articles NP-0281 through NP-0300: vector geometry, matrix shapes, PCA, gradients, probability, sampling limits, likelihood, regularization, bias/variance, entropy, redundancy, log transformations and numerical stability.

Run `python verify.py` in this directory. Initial execution environment: Python 3.12.0, NumPy 2.4.4 and scikit-learn 1.9.0. Inputs are included CSV files; no download, credentials or live model service is required.

## Reference examples

- Vectors A=(3,4), B=(6,8), C=(4,-3), Z=(0,0). A dot B=50, norms 5 and 10, cosine A/B=1 and A/C=0. Zero-vector cosine is explicitly rejected. Feature meaning and scaling remain a modelling choice; these are abstract signed features, not customer counts.
- Matrix X has shape (3,2), W shape (2,2); XW=[[2,5],[6,9],[10,13]]. Bias [1,-2] broadcasts across rows to [[3,3],[7,7],[11,11]]. WX is incompatible.
- PCA points (1,2),(2,1),(3,4),(4,3), centered at (2.5,2.5). Sample covariance [[5/3,1],[1,5/3]], eigenvalues 8/3 and 2/3, explained variance 80% and 20%. One-component reconstruction has total squared error 2. NumPy eigen analysis and scikit-learn's full-SVD PCA agree on reconstruction; eigenvector signs are not unique. PCA is centered but not automatically feature-standardized.
- No-intercept regression y=2x for x=1,2,3. MSE at theta=0 is 56/3; gradient is -56/3. Learning rate .05 converges toward theta=2, while .3 diverges in the demonstrated steps. Finite differences independently check the analytic gradient. This noiseless fixture does not demonstrate generalization.
- Surface f(x)=x1^2+3*x2 at (2,1): value7, gradient(4,3). Increasing x1 by .1 changes the value by .41, while the first-order approximation is .4. Local model sensitivity is not a causal effect.

`verification-results.json` records executed checks and runtime versions. Floating-point comparisons use tolerances where appropriate. The cosine helper scales before normalization to avoid overflow for large finite components; zero and nonfinite inputs have explicit failure behavior.

Primary references: [NumPy dot](https://numpy.org/doc/stable/reference/generated/numpy.dot.html), [NumPy matmul](https://numpy.org/doc/stable/reference/generated/numpy.matmul.html), [NumPy eigh](https://numpy.org/doc/stable/reference/generated/numpy.linalg.eigh.html), [scikit-learn PCA](https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html). All calculations and fixtures here are original teaching work, not copied provider examples.

## Probability extension

Run `python probability_core.py` for the separately recorded distribution/contingency/Bayes checks; SciPy 1.18.0 is used for the distribution functions. `probability-fixtures.json` contains all authored counts.

The ticket table has 18 urgent/resolved, 12 urgent/unresolved, 56 normal/resolved and 14 normal/unresolved records. P(resolved|urgent)=18/30=60%, while P(urgent|resolved)=18/74. These are different conditions, and the observed table does not factor as independent events.

The fictional record flagger has 100 erroneous records in 10,000, detects 90, and flags 495 of 9,900 valid records. Only 90/585=2/13 of flags are errors under this table, despite 90% sensitivity. Holding sensitivity and false-positive rate fixed while changing prevalence to 10% gives 2/3 by Bayes' formula; stability of those rates is an explicit hypothetical assumption.

Distribution examples contrast Binomial(10,.2) and Poisson(2) probabilities for exactly two outcomes, distinguish a normal density above one from an interval probability, and show an authored count vector with mean3 and descriptive ddof=0 variance19.2. Ten synthetic counts do not establish a definitive fitted distribution or formal overdispersion test.

## Sampling limits extension

Run `python sampling_limits.py` and `python render_sampling.py`. Independent Exponential(scale=2) samples have population mean2 and SD2. For n=1,5,30,100, 20,000 repetitions use documented integer seeds 20260929+n. The standardized mean is sqrt(n)*(mean-2)/2. The report records actual spread, skewness and quantiles rather than claiming that n=30 guarantees normality.

The separate 5,000-observation running path uses seed20260930 and ends at 2.0919085961. Its absolute error increases at 1,752 steps; the path is not monotone and does not reach the population mean exactly. A perfect-dependence counterexample repeats one draw within each hypothetical 100-observation sample, so its sample-mean SD remains about1.981 instead of shrinking to about.2. Theorems require their assumptions; finite simulations illustrate rather than prove them.

The CLT figure uses full simulation counts in histogram denominators and records the fraction outside the displayed range. The LLN figure labels its logarithmic observation-count axis. Primary context: [MIT 18.05 LLN/CLT reading](https://ocw.mit.edu/courses/18-05-introduction-to-probability-and-statistics-spring-2022/mit18_05_s22_class06-prep-b.pdf) and [NumPy Generator.exponential](https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.exponential.html). The simulations, seeds and figures are original.

## Inference and optimization extension

Run `python inference_core.py` for eleven checks recorded in `inference-verification.json`. A seven-head/ten-toss case distinguishes a specified sequence from a binomial count event: their probabilities at p=.7 are .0022235661 and .266827932, with ratio120. Analytical MLE .7 agrees with bounded numerical optimization; all-heads/all-tails boundaries and invalid empty samples are separate checks. Likelihood is not a posterior.

For no-intercept y=2x, x=1,2,3, ridge with SSE+14*theta^2 has theta1, residual14, penalty14 and objective28. Scikit-learn agrees. Changing SSE to MSE but leaving alpha14 gives theta.5, demonstrating loss-normalization dependence, not improved generalization. Parent class counts[6,4] split into[4,0] and[2,4] yield weighted information gain .419973094 bits. Invalid partitions are rejected. Softmax[1000,1001,1002] is [.0900305732,.2447284711,.6652409558]; logsumexp1002.4076059644. The transparent helper demonstrates ordinary finite ranges, not every extreme floating-point input; normalized outputs do not establish calibration.

## Model geometry and interpretation extension

Run `python model_geometry.py` for nine checks in `model-geometry-verification.json`.

- Bias/variance: seed20261002, 500 noisy response samples at25 fixed x locations, true sin(pi*x), normal noise SD.3, test grid101 locations. Polynomial degrees1/3/9 have empirical squared bias .206213/.005059/.000085 and variance .006812/.012664/.032496. Variance uses ddof0 for the exact finite-ensemble squared-error identity. Adding independent fresh outcome-noise variance .09 gives expected errors .303025/.107723/.122582; these are expectations over that noise, not an independently observed test-set score. Design is fixed; only training response noise varies.
- Scaling: A[1,1], B[2,1], C[1,3], distances1/2; multiplying the first feature by10 makes distances10/2 and reverses the nearest candidate. Cosine A/B changes .948683 to .998765 with feature-wise scaling, but stays unchanged under positive whole-vector scaling.
- Redundancy: x[1,2,3,4], z=2x; sample covariance[[5/3,10/3],[10/3,20/3]], rank1, eigenvalues0 and25/3, null direction[-2,1]. Unique predictions on the observed representation do not imply unique coefficients.
- Log transformation: log(Y)=log(100)+Normal(0,.6^2). Median100, mean119.721736; SciPy agrees. Seed20261003,200000 draws give mean119.483255 and median99.965010. Normal, constant-variance log residuals are explicit assumptions; this is not a universal retransformation correction.

Run all five verification entry points (`verify.py`, `probability_core.py`, `sampling_limits.py`, `inference_core.py`, `model_geometry.py`) to reproduce the separately recorded groups. Article block execution is additionally recorded by the programme checker. Passing calculations do not constitute instructor review or evidence of deployment performance.
