σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyRoadmapsSkills
Ctrl K
AO
+1.2k Learners
LoginJoin ↗
RoadmapsSkills
AO
+1.2k Learners
Login
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyRoadmapsSkills
Ctrl K
AO
+1.2k Learners
LoginJoin ↗
RoadmapsSkills
AO
+1.2k Learners
Login
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
SciPy skill›Module 1 · Fitting and finding›Topic 1.6·~50 minIntermediate

Least squares and curve fitting

Skill positionModule 1 of 3 · Topic 6 of 6
1.6 Least squares and curve fitting
—Lab score— / 100Total XP—Streak—

Fitting a curve by shrinking the errors

Many models are curves with a few parameters, and fitting means choosing the parameters that make the curve sit close to the data. scipy.optimize.least_squares(fun, x0) does this. You write fun(p), which returns the vector of residuals, one for each data point, where a residual is the model value minus the data value. The function then minimises the cost 12∑ri2\tfrac12\sum r_i^221​∑ri2​. It starts at your guess x0 and takes steps using the Jacobian JJJ, the table of how each residual changes when each parameter changes. A Gauss–Newton step solves J⊤J δ=−J⊤rJ^{\top}J\,\delta=-J^{\top}rJ⊤Jδ=−J⊤r, and then moves the parameters by δ\deltaδ. For a model that is linear in its parameters one such step lands on the answer. bounds=(low, high) keeps parameters in a sensible range. curve_fit is a friendlier wrapper that takes the model f(x,params)f(x,\text{params})f(x,params) directly.

Squared errors let one wild point dominate: a residual of 101010 counts 100100100. A robust loss grows more slowly for large residuals. With loss='soft_l1' and f_scale=1 the penalty is ρ(z)=2(1+z−1)\rho(z)=2(\sqrt{1+z}-1)ρ(z)=2(1+z​−1), where zzz is the squared residual. Fitting yield curves is the classic use. The Nelson–Siegel curve is y(τ)=β0+β11−e−τ/λτ/λ+β2(1−e−τ/λτ/λ−e−τ/λ)y(\tau)=\beta_0+\beta_1\frac{1-e^{-\tau/\lambda}}{\tau/\lambda}+\beta_2\Big(\frac{1-e^{-\tau/\lambda}}{\tau/\lambda}-e^{-\tau/\lambda}\Big)y(τ)=β0​+β1​τ/λ1−e−τ/λ​+β2​(τ/λ1−e−τ/λ​−e−τ/λ). It has a long-run level β0\beta_0β0​, a slope β1\beta_1β1​, a hump β2\beta_2β2​ and a decay length λ\lambdaλ in years, and four numbers describe the whole curve. After a fit, the noise level is estimated by s=SSE/(n−p)s=\sqrt{\mathrm{SSE}/(n-p)}s=SSE/(n−p)​, with nnn points and ppp parameters.

δ=−(J⊤J)−1J⊤r,cost=12∑ri2,ρ(z)=2(1+z−1),s=SSEn−p\delta=-(J^{\top}J)^{-1}J^{\top}r,\qquad \text{cost}=\tfrac12\sum r_i^{2},\qquad \rho(z)=2(\sqrt{1+z}-1),\qquad s=\sqrt{\frac{\mathrm{SSE}}{n-p}}δ=−(J⊤J)−1J⊤r,cost=21​∑ri2​,ρ(z)=2(1+z​−1),s=n−pSSE​​(1)
A line through the originFit y=a xy=a\,xy=ax to the points (1,2.1)(1,2.1)(1,2.1), (2,3.9)(2,3.9)(2,3.9) and (3,6.2)(3,6.2)(3,6.2). Start at a=1a=1a=1. The residuals are r=ax−y=(−1.1,−1.9,−3.2)r=ax-y=(-1.1,-1.9,-3.2)r=ax−y=(−1.1,−1.9,−3.2) and the Jacobian is J=x=(1,2,3)J=x=(1,2,3)J=x=(1,2,3). Then J⊤r=−14.5J^{\top}r=-14.5J⊤r=−14.5 and J⊤J=14J^{\top}J=14J⊤J=14, so δ=14.5/14=1.036\delta=14.5/14=1.036δ=14.5/14=1.036 and the new value is a=2.036a=2.036a=2.036. This is already the answer, because the model is linear in aaa. The residuals at the answer are 0.0640.0640.064, −0.171-0.171−0.171 and 0.0930.0930.093, so the cost is 0.02110.02110.0211. A residual of 101010 costs 100100100 with squares but only ρ=18.10\rho=18.10ρ=18.10 with soft_l1. On real data, a Nelson–Siegel curve fitted by least_squares to the ten Treasury yields of 9 October 2026 (3 months to 30 years) has a level of 5.75%5.75\%5.75%, a slope of −1.52-1.52−1.52 (the curve rises with maturity) and λ=2.7\lambda=2.7λ=2.7 years, and misses the quoted yields by only 7.37.37.3 basis points on average, and by 131313 at worst. Fitting 444 parameters to 101010 points with SSE=0.54\mathrm{SSE}=0.54SSE=0.54 leaves n−p=6n-p=6n−p=6 degrees of freedom and s=0.54/6=0.30s=\sqrt{0.54/6}=0.30s=0.54/6​=0.30.
  • Residuals in, parameters out: fun(p) returns model minus data, and least_squares shrinks the sum of squares.
  • Robust loss for outliers: soft_l1 stops one wild point from dragging the whole curve.
  • Four numbers for a curve: Nelson–Siegel summarises a yield curve with a level, a slope, a hump and a decay length.

Lab · what's graded

  • A slope through the origin10 pts
  • A Gauss–Newton step15 pts
  • A robust penalty15 pts
  • The noise level after a fit10 pts
  • The arguments of least_squares10 pts
  • A curve-fitting workflow10 pts
  • Why a robust loss30 pts
0/ 7 answered
Tasks
1Numeric answer10 ptsNot answered

For y=a xy=a\,xy=ax the best aaa is ∑xiyi/∑xi2\sum x_iy_i/\sum x_i^{2}∑xi​yi​/∑xi2​. With x=(1,2,3)x=(1,2,3)x=(1,2,3) and y=(2.1,3.9,6.2)y=(2.1,3.9,6.2)y=(2.1,3.9,6.2), what is aaa? Give three decimals.

a=a =a=accepted: ± 0.003
2Numeric answer15 ptsNot answered

Start at a=1a=1a=1. The residuals are r=(−1.1,−1.9,−3.2)r=(-1.1,-1.9,-3.2)r=(−1.1,−1.9,−3.2) and J=(1,2,3)J=(1,2,3)J=(1,2,3), with J⊤r=−14.5J^{\top}r=-14.5J⊤r=−14.5 and J⊤J=14J^{\top}J=14J⊤J=14. What is the step δ=−J⊤r/J⊤J\delta=-J^{\top}r/J^{\top}Jδ=−J⊤r/J⊤J? Give three decimals.

d=d =d=accepted: ± 0.003
3Numeric answer15 ptsNot answered

A residual of 101010 has squared value z=100z=100z=100. With soft_l1 and f_scale=1 the penalty is ρ(z)=2(1+z−1)\rho(z)=2(\sqrt{1+z}-1)ρ(z)=2(1+z​−1). What is ρ\rhoρ? Give two decimals.

rho=rho =rho=accepted: ± 0.05
4Numeric answer10 ptsNot answered

A curve with p=4p=4p=4 parameters is fitted to n=10n=10n=10 points and the sum of squared residuals is SSE=0.54\mathrm{SSE}=0.54SSE=0.54. What is s=SSE/(n−p)s=\sqrt{\mathrm{SSE}/(n-p)}s=SSE/(n−p)​? Give two decimals.

s=s =s=accepted: ± 0.005
5Match10 ptsNot answered

Match each argument with what it does.

Pick the partner of each item on the left.

fun
x0
bounds
loss
6Order the steps10 ptsNot answered

Put the steps of fitting a yield curve in order.

Drag to reorder, or focus an item, press Space to lift it, the arrow keys to move it and Space to drop it.

  1. 1Look at the residuals and success flag
  2. 2Call least_squares with a start and bounds
  3. 3Choose the model, here Nelson–Siegel
  4. 4Write a function returning model minus data
7Explain in words30 ptsNot answered

One bad quote sits far from the other nine yields. In one or two sentences, explain why a plain least-squares fit is pulled toward it and why soft_l1 helps.

Math modeKeyboard or LaTeX inputTask 1 of 7 · Ctrl ⏎ to check

Log in to run your code.

Every lecture is free to read. Create an account or log in to run code, run tests and submit this lab.

  • In-browser IDE with a bash terminal — nothing to install
  • Instant grading, XP and your place on the skill
Create an accountLog in
OR
Continue with GitHub