90-Minute Main Lesson: Loss → Regularization → Probability Decision
Objectives: Explain regression from its loss; compare Ridge and Lasso; map a linear score to probability; handle imbalance without leakage.
learning path:
prerequisite and regression 20 min → regularization 20 min → Sigmoid predict–reveal 15 min → Fuyao Glass main case 25 min → checks and synthesis 10 min.
SVM, multiclass methods, and SMOTE are extensions.
Answer first: If a residual grows from 2 to 4, by what factor does its squared-loss contribution grow?
Feedback: It grows from \(2^2=4\) to \(4^2=16\), a factor of four; MSE therefore emphasizes large residuals.
Welcome to Chapter 5: Linear Models
The intersection of machine learning and econometrics.
The art and science of finding linear relationships in data.
An indispensable foundation for building more complex models.
Goal 1: Build Powerful Predictive Capabilities
Linear models are the workhorses of economic forecasting.
Macroeconomics: Predicting GDP growth, inflation, and unemployment rates.
Financial Markets: Forecasting stock returns and asset price volatility.
Micro-level Behavior: Predicting consumer purchasing habits and corporate sales.
Mastering them means you possess the fundamental tools to quantitatively forecast the future.
Goal 2: Separate Predictive Association from Causal Effects
Linear regression first describes a conditional-mean association; it does not automatically answer ‘why’. Causal analysis must define the treatment, outcome, estimand, and a defensible identification design.
Identification checklist: establish timing and an assignment/exogeneity source; require consistency/SUTVA; measure treatment and key confounders; check overlap/positivity when relevant; choose in advance the estimand and specification.
Design before regression: tax, education, and pricing effects need a randomized or credible quasi-experimental design—not merely a broad ‘no omitted variables’ phrase.
Without identification: report a predictive association, not a policy or pricing effect.
This chapter trains prediction; its causal examples mark the boundary and do not turn an ordinary regression into an identified effect.
Goal 3: Establish the Foundation for Advanced Models
Nearly all modern, advanced machine learning models incorporate linear transformations at their core.
Neural Networks: Each neuron performs a weighted sum (a linear transformation) followed by a non-linear activation function.
Factor Models: In finance, asset returns are modeled as linear exposures to various risk factors.
Generalized Linear Models (GLMs): Extend the linear predictor to data with various distributions via a link function.
A solid understanding of linear models is the gateway to the broader world of machine learning.
This Chapter’s Learning Roadmap
We will follow a path from simple to complex to comprehensively master the ‘family’ of linear models.
Core Topic
Key Models
Core Problem Solved
Basic Linear Models
Linear Regression
Predicting continuous values (e.g., prices)
Logistic Regression
Predicting probabilities/binary classes
Regularization/Sparsity
Ridge & Lasso Regression
Preventing overfitting, feature selection
Maximum-Margin Idea
Support Vector Machine (SVM)
Finding the most robust decision boundary
Handling Complexity
Multiclass & Class Imbalance
Tackling more complex real-world tasks
The Core Idea: What is a Linear Model?
The central assumption of a linear model is that the target variable can be expressed as a weighted sum of the input features.
For a sample \(\mathbf{x} = (x_1, x_2, \ldots, x_d)\) with d features, the prediction function is:
Using vector notation, this can be written concisely as:
\[ \large{f(\mathbf{x}; \mathbf{w}, b) = \mathbf{w}^T\mathbf{x} + b} \]
\(\mathbf{w} = (w_1, \ldots, w_d)\): The weight vector, which determines the importance of each feature.
\(b\): The bias or intercept term, which acts as the model’s baseline.
Anatomy of a Linear Model
This diagram illustrates how a linear model combines input features to produce a single predictive value.
The Geometry: It Defines a Decision Hyperplane
The model’s equation, \(\mathbf{w}^T\mathbf{x} + b = 0\), geometrically defines a hyperplane.
In 2D space (d=2): This is a straight line (\(w_1x_1 + w_2x_2 + b = 0\)).
In 3D space (d=3): This is a flat plane (\(w_1x_1 + w_2x_2 + w_3x_3 + b = 0\)).
This hyperplane divides the feature space into two halves, forming the decision boundary for all linear classifiers.
Hyperplanes Take Different Forms in Different Dimensions
Example: A Linear Classifier in 2D Space
Suppose we predict if the economy is in an ‘expansion’ (blue circles) or ‘recession’ (red diamonds) based on two indicators: \(x_1\) (GDP growth) and \(x_2\) (inflation).
A linear classifier finds a line to separate these two classes.
The Weight Vector w Determines the Hyperplane’s Orientation
The weight vector \(\mathbf{w}\) is not just for weighting features; geometrically, it is always perpendicular to the decision hyperplane.
The direction of \(\mathbf{w}\) points in the direction of the fastest increase in the function \(f(\mathbf{x})\).
Orthogonality argument:
For two hyperplane points, \(\mathbf{w}^T(\mathbf{x}_A - \mathbf{x}_B) = 0\).
Therefore \(\mathbf{w}\) is orthogonal to every direction lying within the hyperplane.
In the previous slide, the vector \(\mathbf{w}\) (teal arrow) is perpendicular to the decision boundary (grey line).
From Geometry to Prediction: The Decision Rule
Once we have the hyperplane \(\mathbf{w}^T\mathbf{x} + b = 0\), classification is straightforward.
For a new data point \(\mathbf{x}\), we compute the value of \(f(\mathbf{x}) = \mathbf{w}^T\mathbf{x} + b\):
If \(f(\mathbf{x}) > 0\), the point lies on the side of the hyperplane pointed to by \(\mathbf{w}\). We predict it as the positive class (e.g., label +1).
If \(f(\mathbf{x}) < 0\), the point lies on the other side. We predict it as the negative class (e.g., label -1).
This decision function is often written as: \(\hat{y} = \text{sign}(\mathbf{w}^T\mathbf{x} + b)\).
Key Math: Distance from a Point to the Hyperplane
What is the distance from a sample point \(\mathbf{x}\) to the decision boundary \(\mathbf{w}^T\mathbf{x} + b = 0\)? This concept is crucial for Support Vector Machines (SVMs).
From analytic geometry, the distance \(r\) is given by:
Where \(\|\mathbf{w}\|\) is the L2 norm (Euclidean length) of the weight vector, \(\|\mathbf{w}\| = \sqrt{w_1^2 + w_2^2 + \ldots + w_d^2}\).
Within one fixed model, \(|f(\mathbf{x})|\) is proportional to geometric distance; across models, use \(|f(\mathbf{x})|/\|\mathbf{w}\|\). A geometric margin is not a calibrated class probability.
5.1 From Classification to Regression: Linear Regression
If our goal is not to predict a discrete class (like ‘Expansion/Recession’) but a continuous value (like house prices, stock prices), the linear model becomes Linear Regression.
We directly use the model’s output as the predicted value:
The objective now becomes: Find the best \(\mathbf{w}\) and \(b\) such that the predicted value \(\hat{y}\) is as close as possible to the true observed value \(y\).
Measuring ‘Closeness’: Mean Squared Error (MSE)
We use a Loss Function to quantify the ‘error’ of our predictions. For linear regression, the most common loss function is the Mean Squared Error (MSE).
For a dataset of \(N\) samples \(\{(\mathbf{x}_n, y_n)\}_{n=1}^N\), the MSE is defined as:
Shapes:\(\mathbf X\) is \(N\times(d+1)\) and \(\mathbf y\) is \(N\times1\).
Rank-safe computation:\(\mathbf w^*=\mathbf X^+\mathbf y\) is the minimum-norm solution; use QR/SVD or lstsq, not an explicit inverse.
The Normal Equation Has Pros and Cons
Pros
Convex Problem: Stable QR/SVD solvers directly recover a global least-squares solution.
No Hyperparameters: No learning rate to tune.
Cons
Computational Cost: Direct factorizations become expensive as feature count grows; large sparse problems often use iterative solvers.
Rank Deficiency: With multicollinearity or \(d>N\), coefficients may be non-unique, but QR/SVD/pseudoinverse still solves least squares; report rank and conditioning.
Solution 2: The Core Idea of Gradient Descent
When the number of features is large, we typically use an iterative method called Gradient Descent.
The Core Idea
Imagine a blindfolded person trying to walk to the bottom of a valley.
At each step, they feel for the steepest path downhill (the opposite direction of the gradient) and take a small step.
They repeat this until they reach the valley floor (the minimum of the loss function).
Gradient Descent: the Optimization Path
Randomly initialize \(\mathbf{w}\) and \(b\).
Compute the gradient of the loss function with respect to \(\mathbf{w}\) and \(b\).
Update the parameters in the opposite direction of the gradient: \(\mathbf{w} \leftarrow \mathbf{w} - \eta \nabla_{\mathbf{w}}J\); \(b \leftarrow b - \eta \nabla_{b}J\)
Repeat steps 2 and 3 until convergence. (\(\eta\) is the learning rate).
Problem: What if Features are Numerous or Correlated?
Standard linear regression (OLS) runs into trouble in certain situations:
Overfitting:
When the number of features \(d\) is close to or exceeds the number of samples \(N\), the model can become overly complex.
It may fit the training data perfectly but perform poorly on new data.
Multicollinearity:
Pattern: features are highly correlated, such as house area and number of rooms.
Consequence: weight estimates \(\mathbf{w}\) become unstable and unreliable.
A Visual Example of Overfitting
An overfit model learns the ‘noise’ in the training data, not just the underlying ‘signal’.
The Core Trade-off: Bias vs. Variance
Bias: The systematic difference between a model’s predictions and the true values. High bias means the model is too simple (underfitting).
Variance: The variability of a model’s predictions across different training sets. High variance means the model is too sensitive to the training data (overfitting).
Our goal is to find a model that achieves a good balance between bias and variance.
Bias–Variance Trade-off: Visual Summary
The Solution: Regularization Penalizes Complexity
The core idea of regularization is to penalize model complexity while minimizing training error.
We achieve this by adding a Penalty Term to the loss function, which is related to the magnitude of the weights \(\mathbf{w}\).
\(\lambda \ge 0\) is the regularization parameter, a hyperparameter we set. It controls the strength of the penalty.
\(\lambda = 0\): No penalty; this reverts to standard linear regression.
\(\lambda \to \infty\): The penalty is extreme, forcing all weights toward zero.
5.2 L2 Regularization: Ridge Regression
Ridge Regression uses the squared L2 norm of the weight vector, \(\|\mathbf{w}\|_2^2 = \sum_{j=1}^d w_j^2\), as its penalty term.
The objective function is:
\[ \large{J_{\text{Ridge}}(\mathbf{w}, b) = \text{MSE}(\mathbf{w},b) + \lambda \sum_{j=1}^d w_j^2} \]
Effect:
It causes shrinkage of the coefficients, pulling them towards zero but rarely making them exactly zero.
By penalizing large weights, it makes the model smoother and reduces variance.
It effectively handles multicollinearity, making the model more stable.
L1 Regularization: Lasso Regression
Lasso (Least Absolute Shrinkage and Selection Operator) Regression uses the L1 norm of the weight vector, \(\|\mathbf{w}\|_1 = \sum_{j=1}^d |w_j|\), as its penalty.
The objective function is:
\[ \large{J_{\text{Lasso}}(\mathbf{w}, b) = \text{MSE}(\mathbf{w},b) + \lambda \sum_{j=1}^d |w_j|} \]
Effect:
Lasso not only shrinks coefficients but can force the coefficients of some unimportant features to be exactly zero.
Therefore, Lasso performs automatic Feature Selection, producing a sparser, more interpretable model, which is highly valuable in economic analysis.
Figure 1: Geometric Interpretation of Lasso (left) vs. Ridge (right)
5.3 Logistic Regression
Let’s return to classification. What are the problems with using the raw output of a linear model, \(\mathbf{w}^T\mathbf{x}+b\), directly for classification?
Mismatched Output Range: The output is \((-\infty, +\infty)\), whereas the Sigmoid maps every finite input strictly into \((0, 1)\).
Sensitivity to Outliers: A single outlier far from the decision boundary can drastically shift the regression line, thereby altering the classification outcome.
Logistic regression solves these issues with a clever ‘squashing’ function.
The Sigmoid Function Maps Real Numbers to Probabilities
Logistic regression models the Bernoulli conditional mean as a Sigmoid (Logistic) transform of the linear score and estimates parameters by likelihood/cross-entropy.
\[ \large{\sigma(z) = \frac{1}{1 + e^{-z}}} \]
where \(z = \mathbf{w}^T\mathbf{x} + b\).
Code
import numpy as npimport matplotlib.pyplot as pltdef sigmoid(linear_predictor_values): # 定义当前教学案例所需的函数。# Returns the current function results for subsequent evaluation or display.return1/ (1+ np.exp(-linear_predictor_values)) # 返回当前步骤的计算结果供后续使用。linear_predictor_values = np.linspace(-8, 8, 200)probability_value = sigmoid(linear_predictor_values)plt.style.use('seaborn-v0_8-whitegrid') # 展示当前步骤的结果。plt.figure(figsize=(8, 3.2)) # 展示当前步骤的结果。plt.plot(linear_predictor_values, probability_value, color='crimson', linewidth=2.5) # 展示当前步骤的结果。plt.axhline(y=0.5, color='grey', linestyle='--'); plt.axvline(x=0, color='grey', linestyle='--') # 展示当前步骤的结果。plt.title('The Sigmoid Function', fontsize=50) # 放大图题以满足投影阅读距离。plt.xlabel('Linear score z', fontsize=50); plt.ylabel('Probability σ(z)', fontsize=50) # 放大坐标轴标题以满足投影阅读距离。plt.tick_params(axis='both', labelsize=50) # 放大刻度文字以满足投影阅读距离。plt.yticks([0, 0.5, 1.0]) # 展示当前步骤的结果。plt.show() # 展示当前步骤的结果。
Figure 2: The Sigmoid Function Curve
Sigmoid Properties
The output lies in \((0,1)\) and can therefore parameterize a Bernoulli probability; bounded output alone does not guarantee calibration, which must be checked on validation data.
When \(z=0\), \(\sigma(z)=0.5\); as \(z \to +\infty\), \(\sigma(z) \to 1\); as \(z \to -\infty\), \(\sigma(z) \to 0\).
Sigmoid Predict–Reveal: Probability and Sensitivity
Without a calculator, first rank the probabilities for \(z\in\{-2,0,2\}\); then decide where \(\sigma'(z)=\sigma(z)[1-\sigma(z)]\) is largest.
\(\sigma'(0)=0.25\), while \(\sigma'(\pm2)\approx0.105\).
The model is most sensitive to score changes near the boundary \(z=0\) and saturates toward both tails; for finite \(z\), the probability remains strictly inside \((0,1)\).
Probabilistic Interpretation of Logistic Regression
The logistic regression model assumes the probability of a sample belonging to the positive class (y=1) is:
A decision threshold of 0.5 is typically used: if \(P(y=1 | \mathbf{x}) > 0.5\) (which means \(\mathbf{w}^T\mathbf{x} + b > 0\)), we predict 1; otherwise, we predict 0.
The Loss Function for Logistic Regression is Cross-Entropy
Logistic regression isn’t optimized using Mean Squared Error. Instead, it uses an idea derived from Maximum Likelihood Estimation (MLE).
For the entire dataset, we want to maximize the joint probability of observing the given labels.
Taking the logarithm and negating it gives us the loss function to minimize, known as Log Loss or Binary Cross-Entropy:
where \(\hat{p}_n = \sigma(\mathbf{w}^T\mathbf{x}_n + b)\). This loss function is convex and can be efficiently solved using methods like gradient descent.
Intuition Behind the Cross-Entropy Loss
Main lesson: Skip SVM and Multiclass Methods
Main lesson: SVM and multiclass methods are Extension; continue from logistic loss directly to class imbalance.
5.4 Support Vector Machines (SVM)
Logistic regression finds a boundary that separates the data, but is it the best boundary?
As seen below, multiple lines can perfectly separate the two classes.
The core idea of SVM is: Don’t just separate the classes, separate them with the largest possible ‘margin’.
The most robust boundary is the one that is as far as possible from the nearest points of both classes.
Visual: Maximum Margin Selects a More Robust Boundary
Code
import numpy as npimport matplotlib.pyplot as pltfrom sklearn.datasets import make_blobsinput_feature_matrix, target_values = make_blobs(n_samples=40, centers=2, random_state=8, cluster_std=0.8)plt.style.use('seaborn-v0_8-whitegrid') # 展示当前步骤的结果。plt.figure(figsize=(8, 6)) # 展示当前步骤的结果。plt.scatter(input_feature_matrix[:, 0], input_feature_matrix[:, 1], c=target_values, s=50, cmap='winter', edgecolors='k') # 展示当前步骤的结果。x_fit = np.linspace(plt.xlim()[0], plt.xlim()[1], 100)plt.plot(x_fit, -1* x_fit +7, '-k', label='Boundary A (Optimal)') # 展示当前步骤的结果。plt.plot(x_fit, -0.6* x_fit +8.5, '--k', label='Boundary B (Too close to blue)') # 展示当前步骤的结果。plt.plot(x_fit, -1.5* x_fit +3.5, ':k', label='Boundary C (Too close to green)') # 展示当前步骤的结果。plt.title('SVM Motivation: The Optimal Boundary', fontsize=24) # 放大图题以满足投影阅读距离。plt.xlabel('Feature 1', fontsize=22); plt.ylabel('Feature 2', fontsize=22) # 放大坐标轴标题以满足投影阅读距离。plt.legend(fontsize=20) # 放大图例以满足投影阅读距离。plt.tick_params(axis='both', labelsize=20)plt.show() # 展示当前步骤的结果。
Figure 3: Which separating line is the best?
SVM Core Concepts: Margin and Support Vectors
Optional topic: Core proceeds from logistic loss to class imbalance, then the main case. Return to SVM and multiclass methods after Core.
Decision Boundary: The hyperplane \(\mathbf{w}^T\mathbf{x} + b = 0\).
Margin: The “empty” region between the decision boundary and the data points on either side. SVM aims to maximize the width of this region.
Support vectors:
in the linearly separable hard-margin case, they lie exactly on the margin boundaries.
In a soft-margin SVM, they have active/nonzero dual coefficients and may lie on the boundary, inside the margin, or violate it.
Moving a non-support point leaves the current solution unchanged only while that point remains inactive.
Mechanism Appendix: SVM Margin and Support Vectors
Figure 4: The margin and support vectors in an SVM
SVM Math (Linearly Separable Case)
To maximize the margin, we first define its width.
By scaling \(\mathbf{w}\) and \(b\), we can set the margin such that for any support vector \(\mathbf{x}_s\), we have \(|\mathbf{w}^T\mathbf{x}_s + b| = 1\).
The distance from a point to the hyperplane is \(\frac{|\mathbf{w}^T\mathbf{x} + b|}{\|\mathbf{w}\|}\).
So, the distance from a support vector to the hyperplane is \(1/\|\mathbf{w}\|\).
The total width of the margin is therefore \(2 / \|\mathbf{w}\|\).
Simultaneously, all points must be classified correctly, meaning for each sample \((\mathbf{x}_n, y_n)\) (where \(y_n \in \{-1, 1\}\)): \(y_n(\mathbf{w}^T\mathbf{x}_n + b) \ge 1\).
The SVM Optimization Problem (Hard Margin)
In summary, the optimization problem for a linearly separable (hard-margin) SVM is:
The Hyperparameter C Balances Margin Width and Errors
\(C\) is a crucial hyperparameter that controls the penalty for slack variables. Think of it as the inverse of the regularization parameter \(\lambda\).
Small \(C\): Low penalty for errors. The model prioritizes a wide margin, even if it means some points are inside the margin or misclassified. High tolerance, strong regularization, may underfit.
Large \(C\): High penalty for errors. The model tries very hard to classify every point correctly, which can lead to a narrow margin and overfitting to the training data. Low tolerance, weak regularization, may overfit.
SVM C: Visual Comparison of Margin and Errors
5.5 Multiclass Linear Models
We have focused on binary classification, but many real-world tasks involve multiple categories. For example:
Segmenting customers into ‘High-Value’, ‘Mid-Value’, and ‘Low-Value’.
Recognizing handwritten digits (0-9, a 10-class problem).
Predicting the state of the economy: ‘Recovery’, ‘Boom’, ‘Recession’, or ‘Depression’.
How can we extend binary classifiers to handle multiclass scenarios?
Strategy 1: One-vs-Rest (OvR)
This strategy involves training one binary classifier for each class, which is trained to distinguish that class from all other classes combined.
For K classes, you train K classifiers.
Prediction compares K decision scores. They are directly comparable only under a consistent training/scaling scheme or after calibration, and they are not automatically probability confidences.
One-vs-Rest: Three Binary Views
Strategy 2: One-vs-One (OvO)
This strategy involves training a binary classifier for every pair of classes.
For K classes, you train \(K(K-1)/2\) classifiers.
At prediction time, each pairwise classifier votes.
A unique plurality wins; ties use a predeclared deterministic rule (here, maximize the sum of signed pairwise confidences, then use a fixed class order if still tied).
Raw votes and uncalibrated margins are not multiclass probabilities.
OvR vs. OvO: A Comparison
Feature
One-vs-Rest (OvR)
One-vs-One (OvO)
# of Classifiers
K
K(K-1)/2
Training Data
Each classifier uses all data (can be imbalanced)
Each classifier uses only the participating pair; balance depends on their sample counts
Compute trade-off
Trains K classifiers on the full sample.
Trains K(K-1)/2 smaller two-class models; each fit is smaller, but total cost can be higher when K is large.
Commonly used with
Logistic Regression (default)
Support Vector Machines
Direct Extension: Softmax Regression
A more direct approach is Softmax Regression, which generalizes logistic regression to multiple classes.
For K classes, the model learns K weight vectors \(\{\mathbf{w}_1, \ldots, \mathbf{w}_K\}\).
For a sample \(\mathbf{x}\), we compute K scores: \(s_k(\mathbf{x}) = \mathbf{w}_k^T \mathbf{x} + b_k\).
The Softmax function then converts these scores into a probability distribution:
Measures how ‘correct’ the positive predictions are.
Recall (or Sensitivity): Of all samples that were actually positive, how many did the model successfully find?
\[ \large{\text{Recall} = \frac{TP}{TP + FN}} \]
Measures how ‘complete’ the positive predictions are.
In fraud detection, we care deeply about recall (we don’t want to miss any fraudulent transactions).
Solution 1: Data-Level Resampling
The most direct approach is to fix the imbalance at the data level. There are two main strategies:
Pros and Cons of Resampling Methods
Undersampling
Pro: Faster training time.
Con: May discard important information from the majority class.
Oversampling
Pro: No information loss.
Con: May lead to overfitting on the minority class.
Popular Algorithm: SMOTE (Synthetic Minority Over-sampling Technique).
Main lesson: SMOTE is Extension; continue from the resampling comparison to algorithm-level adjustment, then the main case.
SMOTE Creates Synthetic Minority Samples
SMOTE is one of the most effective oversampling techniques.
Core Idea
For each minority sample, find its k-nearest neighbors (which are also minority samples).
Then, randomly pick a point along the line segment connecting the sample to one of its neighbors and create a new, synthetic sample there.
This is like ‘interpolating’ within the minority class region, creating new data that is similar to the original data but not identical, which helps expand the decision region for the minority class.
How the SMOTE Algorithm Works
Solution 2: Algorithm-Level Adjustments
Besides modifying the data, we can also adjust the learning algorithm itself.
Adjusting Class Weights: We can assign a higher penalty for misclassifying minority class samples in the loss function.
For example, setting class_weight='balanced' in scikit-learn models.
This forces the model to pay more attention to correctly classifying the minority class during optimization.
Changing the Decision Threshold: Logistic regression uses a 0.5 probability threshold by default. For imbalanced problems, we can lower this threshold (e.g., to 0.3) to increase recall for the minority class.
Core Learning Review
Core (70 min): linear regression, regularization, logistic regression, and out-of-sample evaluation. Extension (20 min or after class): SVM, multiclass methods, and SMOTE.
Retrieve the opening objectives: derive a linear model from its loss, explain Ridge/Lasso constraints, distinguish scores from calibrated probabilities, and handle imbalance without leakage.
Retrieval prompt: If an error grows from 2 to 4, by what factor does its squared-loss contribution grow?
Answer: From \(2^2=4\) to \(4^2=16\), a factor of four; this is why MSE emphasizes large residuals.
Formative Check 1: Regularization
Which method more often produces exactly zero coefficients, Ridge or Lasso, and why?
Answer
Lasso. Corners of the L1 constraint often meet loss contours on coordinate axes; the smooth L2 ball usually shrinks continuously without exact zeros.
Task: use 2018–2024 close and volume to predict next-day return from one-to-five-day lagged returns and volume growth.
Split: chronological 80/20 train/test periods.
Nearby method source:Hoerl & Kennard (1970), ridge regression. First prepare the chronological boundary while keeping test labels held-out; then select regularization strength using training-period windows only.
Code
from pathlib import Path # Locate the downloaded data fileimport pandas as pd # Read local quotes into a tablefrom sklearn.pipeline import make_pipeline # Fit scaling and the model on the same training rowsfrom sklearn.preprocessing import StandardScaler # Unifying Lagging Feature Scalesfrom sklearn.linear_model import Ridge # Use L2 regularization to stabilize correlation characteristic coefficientsfrom sklearn.metrics import mean_squared_error # Evaluate Out-of-Sample Error of Continuous Forecast# Public download: https://assets.qiufei.site/data/stock/stock_price_pre_adjusted.h5# After downloading, change the next line to the file's actual location on your device.# Course-relative option: Path("data/stock/stock_price_pre_adjusted.h5")# Windows: Path(r"C:\qiufei\data\stock\stock_price_pre_adjusted.h5")# macOS: Path("/Users/your_name/data/stock/stock_price_pre_adjusted.h5")# Linux: Path("/home/your_name/data/stock/stock_price_pre_adjusted.h5")price_path = Path("/home/ubuntu/r2_data_mount/data/stock/stock_price_pre_adjusted.h5")price_rows = pd.read_hdf(price_path, key='data', where=['order_book_id=="600660.XSHG"', 'date>=Timestamp("2018-01-01")', 'date<=Timestamp("2024-12-31")'], columns=['close', 'volume']) # Only Load Target Companies, Periods, and Fieldsridge_frame = price_rows.reset_index().sort_values('date') # Build Forecast Order by Trading Dayridge_frame['return_t'] = ridge_frame['close'].pct_change() # Compute the baseline one-day returnfeature_names = [f'return_lag_{lag_day}'for lag_day inrange(1, 6)] # Pre-declare five historical benefit feature namesfor lag_day, feature_name inenumerate(feature_names, start=1): ridge_frame[feature_name] = ridge_frame['return_t'].shift(lag_day -1) # Write each available historical return to its lagged-feature columnridge_frame['volume_growth_t'] = ridge_frame['volume'].pct_change() # Adding the volume growth rate of the dayridge_frame['target_return_t1'] = ridge_frame['return_t'].shift(-1) # Define next-day return targetsridge_frame['target_date_t1'] = ridge_frame['date'].shift(-1) # Preserve the label-realization date for boundary purgingridge_frame = ridge_frame.replace([float('inf'), float('-inf')], pd.NA).dropna() # Remove non-finite observations created by transformations
Code
feature_names = feature_names + ['volume_growth_t'] # Add volume information to the model matrixsplit_row =int(len(ridge_frame) *0.8) # Fixed First Eighty Percent as Training Periodtest_start_date = ridge_frame.iloc[split_row]['date']train_rows = ridge_frame[(ridge_frame['date'] < test_start_date) & (ridge_frame['target_date_t1'] < test_start_date)] # Purge training labels realized in testtest_rows = ridge_frame[ridge_frame['date'] >= test_start_date]assert train_rows['target_date_t1'].max() < test_rows['date'].min() # Verify the label-realization boundarypd.Series({'train_end': train_rows['date'].max(), 'test_start': test_rows['date'].min()}) # Verify only the time boundary without reading test labels or candidate-model test errors
What probability does logistic regression assign when \(z=0\)? If false negatives become more costly, should the threshold generally rise or fall?
Answer
\(\sigma(0)=1/(1+e^0)=0.5\). It generally falls to gain positive-class recall; the threshold follows loss, not convention.
Step-by-Step Exercise: Choose \(\alpha\)
Task: Use expanding-window training validation to compare \(\alpha\in\{0.1,1,10,100\}\), choose selected_alpha, refit once, then evaluate once on the fixed test period beside the training-mean baseline.
Complete solution: Refit scaler + Ridge inside each window; minimize mean validation MSE, refit on all training data, then report Ridge and baseline test MSE. Never select \(\alpha\) from test results.
Code
from sklearn.model_selection import TimeSeriesSplit # Constructing an Extended Window Validated Only for the Futurealpha_rows = [] # Collect Validation MSE for Each Folded Regular Strengthfor fold_id, (fit_index, validation_index) inenumerate(TimeSeriesSplit(n_splits=5).split(train_rows), start=1): # Generate Five Time Windows fold_train = train_rows.iloc[fit_index] # Retrieve the historical training segment fold_validation = train_rows.iloc[validation_index] # Retrieve the subsequent validation segment fold_train = fold_train[fold_train['target_date_t1'] < fold_validation['date'].min()] # Purge labels realized in the validation foldassert fold_train['target_date_t1'].max() < fold_validation['date'].min() # Verify each fold's label boundaryfor alpha_value in [0.1, 1.0, 10.0, 100.0]: # Compare pre-stated candidate regular strength fold_model = make_pipeline(StandardScaler(), Ridge(alpha=alpha_value)).fit(fold_train[feature_names], fold_train['target_return_t1']) # Fit scaling and Ridge on the current training segment fold_prediction = fold_model.predict(fold_validation[feature_names]) # Generate Forecast for Subsequent Validation Periods alpha_rows.append({'fold': fold_id, 'alpha': alpha_value, 'validation_mse': mean_squared_error(fold_validation['target_return_t1'], fold_prediction)}) # save break errorsalpha_table = pd.DataFrame(alpha_rows) # Organize all validation resultsalpha_summary = alpha_table.groupby('alpha', as_index=False)['validation_mse'].mean().rename(columns={'validation_mse': 'mse'}).sort_values('mse') # Summarize validation-stage MSE under one explicit metric fieldalpha_summary.insert(0, 'stage', 'mean_time_validation') # Mark these rows as training-period time-validation evidenceselected_alpha =float(alpha_summary.iloc[0]['alpha'])final_ridge = make_pipeline(StandardScaler(), Ridge(alpha=selected_alpha)).fit(train_rows[feature_names], train_rows['target_return_t1']) # Re-fit the fixed model with a full training periodfinal_prediction = final_ridge.predict(test_rows[feature_names]) # Generate the Ridge return prediction for the fixed test period only oncefinal_baseline = [train_rows['target_return_t1'].mean()] *len(test_rows) # Establishing reviewable benchmarks with mean of training periodspd.concat([alpha_summary[['stage', 'alpha', 'mse']], pd.DataFrame([{'stage': 'test_model', 'alpha': selected_alpha, 'mse': mean_squared_error(test_rows['target_return_t1'], final_prediction)}, {'stage': 'test_baseline', 'alpha': pd.NA, 'mse': mean_squared_error(test_rows['target_return_t1'], final_baseline)}])], ignore_index=True) # Separate validation, test-period, and test-baseline evidence in a stage-explicit long table
Table 1
stage
alpha
mse
0
mean_time_validation
100.0
0.000508
1
mean_time_validation
10.0
0.000509
2
mean_time_validation
1.0
0.000509
3
mean_time_validation
0.1
0.000509
4
test_model
100.0
0.000252
5
test_baseline
<NA>
0.000249
Exercise Result: Ridge Does Not Beat the Baseline
fixed test: validation chose \(\alpha=100\). Ridge MSE \(0.0002521479>0.0002491785\) for the training-mean baseline, so this held-out check does not support practical use.
Apply It to a New Case
Change the task to Hengrui Pharmaceuticals 600276.XSHG next-day decline; compare logistic thresholds 0.5 and a 4:1 false-negative-cost threshold.
Submit AP (average precision), recall, precision, and confusion matrices.
The value \(0.2=1/(4+1)\) is Bayes-optimal only for calibrated probabilities, a 4:1 false-negative:false-positive cost ratio, and equal zero costs for correct decisions;
practical use still requires validation-period checking.
Metric convention: AP is computed with average_precision_score, which weights precision by recall increments; it is not the trapezoidal area under the empirical PR curve.
Complete-answer reminder:
Design: show the time split and fit preprocessing on training data.
Decisions: obtain probabilities with predict_proba and create both Boolean-threshold decisions.
Evidence: report all four metrics, the cost trade-off, and the non-causal limitation.
Complete Solution for the New Case: Hengrui Logistic Regression
Table 2
Code
from sklearn.linear_model import LogisticRegression # Estimating interpretable benchmarks for fall probabilitiesfrom sklearn.metrics import average_precision_score, confusion_matrix, precision_score, recall_score # Evaluation Unbalanced Classification and Cost Thresholds Calculated from Current Datafrom pathlib import Path # Locate the downloaded data file# Public download: https://assets.qiufei.site/data/stock/stock_price_pre_adjusted.h5# After downloading, change the next line to the file's actual location on your device.# Course-relative option: Path("data/stock/stock_price_pre_adjusted.h5")# Windows: Path(r"C:\qiufei\data\stock\stock_price_pre_adjusted.h5")# macOS: Path("/Users/your_name/data/stock/stock_price_pre_adjusted.h5")# Linux: Path("/home/your_name/data/stock/stock_price_pre_adjusted.h5")price_path = Path("/home/ubuntu/r2_data_mount/data/stock/stock_price_pre_adjusted.h5")transfer_rows = pd.read_hdf(price_path, key='data', where=['order_book_id=="600276.XSHG"', 'date>=Timestamp("2018-01-01")', 'date<=Timestamp("2024-12-31")'], columns=['close', 'volume']) # Select Hengrui Medicine, Period and Required Fieldstransfer_frame = transfer_rows.reset_index().sort_values('date') # Sort by trading days in order of forecast occurrencetransfer_frame['return_t'] = transfer_frame['close'].pct_change() # Compute one-day returnstransfer_frame['return_5d_t'] = transfer_frame['close'].pct_change(5) # Compute five-day returnstransfer_frame['volatility_5d_t'] = transfer_frame['return_t'].rolling(5).std() # Compute rolling five-day volatilitytransfer_frame['volume_growth_t'] = transfer_frame['volume'].pct_change() # Construct Volume Growthtransfer_frame['future_return_t1'] = transfer_frame['return_t'].shift(-1) # Retain continuous future returns before label constructiontransfer_frame['target_date_t1'] = transfer_frame['date'].shift(-1) # Preserve the label-realization datetransfer_frame = transfer_frame.replace([float('inf'), float('-inf')], pd.NA).dropna() # Delete unknown future and non-finite records before binary-label constructiontransfer_frame['down_t1'] = (transfer_frame['future_return_t1'] <0).astype(int) # Create classes only for observed future returnstransfer_train = transfer_frame[(transfer_frame['date'] <='2022-12-31') & (transfer_frame['target_date_t1'] <'2023-01-01')] # Purge training labels realized in testtransfer_test = transfer_frame[transfer_frame['date'] >='2023-01-01']assert transfer_train['target_date_t1'].max() < transfer_test['date'].min() # Verify the label-realization boundarytransfer_features = ['return_t', 'return_5d_t', 'volatility_5d_t', 'volume_growth_t'] # Fixed Four T-Points as Available Featuretransfer_logit = make_pipeline(StandardScaler(), LogisticRegression(max_iter=2000, random_state=42)).fit(transfer_train[transfer_features], transfer_train['down_t1']) # Use only the training period to fit scaling and Logittransfer_probability = transfer_logit.predict_proba(transfer_test[transfer_features])[:, 1] # Generate Probability for fixed Test Period
Code
threshold_output = [] # Collect Default Threshold and Cost Threshold Resultsfor probability_threshold in [0.5, 0.2]: # Compare 0.2 under calibrated probabilities, 4:1 error costs, and zero correct-decision costs transfer_prediction = transfer_probability >= probability_threshold # Convert Same Probability to Category Decision threshold_matrix = confusion_matrix(transfer_test['down_t1'], transfer_prediction, labels=[0, 1]) # Fixed Four-Lattice Matrix as Categorical Sequence threshold_output.append({'threshold': probability_threshold, 'average_precision': average_precision_score(transfer_test['down_t1'], transfer_probability), 'precision': precision_score(transfer_test['down_t1'], transfer_prediction, zero_division=0), 'recall': recall_score(transfer_test['down_t1'], transfer_prediction), 'tn': threshold_matrix[0, 0], 'fp': threshold_matrix[0, 1], 'fn': threshold_matrix[1, 0], 'tp': threshold_matrix[1, 1]}) # Save all requested metrics with the estimator named explicitlypd.DataFrame(threshold_output) # Show the true cost trade-off between the two thresholds
Table 3
threshold
average_precision
precision
recall
tn
fp
fn
tp
0
0.5
0.543929
0.532468
0.484252
121
108
131
123
1
0.2
0.543929
0.525880
1.000000
0
229
0
254
Hengrui Transfer Result: AP and Operating Points Answer Different Questions
Executed AP (average precision) is 0.543929; it is not the trapezoidal area under the empirical PR curve.
At 0.5, precision/recall are 0.532468/0.484252 and the matrix is \([[121,108],[131,123]]\).
At 0.2, precision/recall are 0.525880/1.000000 and the matrix is \([[0,229],[0,254]]\), so every observation is predicted as decline.
The test set has 483 observations; the last feature date is 2024-12-30, and unknown future labels are removed before integer conversion.
Threshold 0.2 depends on calibrated probabilities, 4:1 error costs, and zero correct-decision costs; choose it on validation data rather than treating it as universal or causal.
Formative Check 3: SMOTE Leakage
Is it valid to apply SMOTE to all data and split afterward?
Answer: No. Synthetic points would use future test neighbors. Apply SMOTE only inside each training fold; validation/test distributions remain untouched.
We’ve explored the entire ‘family’ of linear models, but they all share a unified underlying philosophy:
Core Engine: Every model starts with the linear function \(\mathbf{w}^T\mathbf{x} + b\).
Task Adaptation:
Regression: Use the linear output directly.
Classification: Map the output to probabilities using Sigmoid/Softmax.
SVM: Focus on the geometric margin around the output.
Optimization Goal: Learn the optimal weights \(\mathbf{w}\) by defining different loss functions and regularization terms.
Loss Functions: Mean Squared Error, Cross-Entropy, Hinge Loss (SVM).
Regularization: L1 and L2 norms.
The Linear Model Family at a Glance
This diagram summarizes the models we’ve discussed, showing how different combinations of loss functions and regularization penalties lead to different models.