【机器学习基础算法:从零实现到精通】第2章 监督学习:线性模型与基函数方法

【机器学习-06】线性回归(Linear Regression,LR)算法:原理、应用与实现 在【机器学习-01】机器学习一般建模流程yiβ0β1x1βp−1xp−1εii12nyi​β0​β1​x1​...βp−1​xp−1​εi​i12...n上述等式的矩阵形式是yXβεy∈RnX∈Rn∗pβ∈Rpε∈RnyXβεy∈RnX∈Rn∗pβ∈Rpε∈Rn其中 Y 是反应变量, X 是解释变量,β 是参数。 阅读详情

目录

2.1 线性回归与最小二乘

2.1.1 解析解与几何解释

2.1.2 概率视角与高斯噪声假设

2.2 正则化与稀疏性

2.2.1 L2正则化与Ridge回归

2.2.2 L1正则化与Lasso回归

2.2.3 弹性网络与结构化稀疏

2.3 分类模型:从线性到概率

2.3.1 感知机与逻辑回归

2.3.2 多类分类与Softmax回归

2.3.3 概率生成模型

2.4 基函数与非线性扩展

2.4.1 多项式回归与样条

2.4.2 径向基函数与核方法初步


2.1 线性回归与最小二乘

2.1.1 解析解与几何解释

线性回归模型的参数估计可归结为最小化残差平方和的目标函数。解析解的构造依赖于设计矩阵的QR分解或Cholesky分解,其中Cholesky分解利用对称正定矩阵的三角化性质,将正规方程的求解转化为前向与后向替换过程,数值稳定性显著优于直接矩阵求逆。从几何视角审视,最小二乘估计等价于响应向量在设计矩阵列空间上的正交投影,投影矩阵(Hat矩阵)的构造直接导出杠杆值与Cook距离等诊断统计量,为异常点检测提供解析基础。计算复杂度的权衡体现在直接求解与迭代方法的比较:基于稠密矩阵分解的方法具有O(ND2) 的复杂度,其中N 为样本量,D 为特征维度;当N≫D 时,采用Gram矩阵的Cholesky分解可显著降低计算开销,而条件数分析揭示了数据共线性对数值稳定性的影响。

2.1.2 概率视角与高斯噪声假设

在概率框架下,响应变量的高斯噪声假设导出似然函数的对数形式与最小二乘目标函数的等价性。极大似然估计在此设定下退化为残差平方和最小化。引入参数的先验分布后,最大后验估计自然地正则化为Ridge回归,其中高斯先验对应L2惩罚项,拉普拉斯先验对应L1惩罚项。后验预测分布的积分计算涉及高斯分布的卷积性质,解析解的获得依赖于对权重空间的边缘化,这为预测不确定性的量化提供了贝叶斯解释。

脚本1:线性回归数值实现与概率解释

Python

"""
脚本1:线性回归的数值方法与概率视角实现
涉及内容:
- 2.1.1.1 正规方程的Cholesky分解求解
- 2.1.1.2 Hat矩阵计算与杠杆值可视化
- 2.1.2.1 MLE与最小二乘等价性数值验证
- 2.1.2.2 MAP估计与Ridge回归的贝叶斯实现

使用方式:
python linear_regression_numerical.py
依赖:numpy, scipy, matplotlib, seaborn
"""

import numpy as np
import matplotlib.pyplot as plt
from scipy import linalg
from scipy.stats import multivariate_normal
import seaborn as sns

# 设置样式
sns.set_palette("husl")
plt.style.use('seaborn-v0_8-whitegrid')

class LinearRegressionNumerical:
    """
    线性回归的数值稳定实现
    包含直接求逆、Cholesky分解、SVD三种求解策略
    """
    
    def __init__(self, method='cholesky'):
        self.method = method
        self.coef_ = None
        self.intercept_ = None
        self.H = None  # Hat矩阵
        self.leverage_ = None
        self.condition_number_ = None
        
    def fit(self, X, y):
        """
        拟合线性回归模型
        实现复杂度O(ND^2)的Cholesky分解与直接O(D^3)方法对比
        """
        n_samples, n_features = X.shape
        # 增广设计矩阵 [1, X]
        X_aug = np.column_stack([np.ones(n_samples), X])
        
        # 计算Gram矩阵 A = X^T X
        A = X_aug.T @ X_aug
        b = X_aug.T @ y
        
        # 记录条件数用于数值稳定性分析
        self.condition_number_ = np.linalg.cond(A)
        
        if self.method == 'direct':
            # 直接求逆(数值不稳定,仅用于教学对比)
            self.coef_ = np.linalg.inv(A) @ b
        elif self.method == 'cholesky':
            # Cholesky分解: A = L L^T
            # 复杂度O(D^3/3),但数值稳定性优于直接求逆
            try:
                L = linalg.cholesky(A, lower=True)
                # 前向替换解 L y = b
                y_temp = linalg.solve_triangular(L, b, lower=True)
                # 后向替换解 L^T x = y
                self.coef_ = linalg.solve_triangular(L.T, y_temp, lower=False)
            except np.linalg.LinAlgError:
                # 矩阵非正定,添加微小正则化
                A_reg = A + 1e-8 * np.eye(n_features + 1)
                L = linalg.cholesky(A_reg, lower=True)
                y_temp = linalg.solve_triangular(L, b, lower=True)
                self.coef_ = linalg.solve_triangular(L.T, y_temp, lower=False)
        elif self.method == 'svd':
            # SVD分解用于共线性处理
            U, s, Vh = linalg.svd(X_aug, full_matrices=False)
            # 伪逆求解
            self.coef_ = Vh.T @ np.diag(1/s) @ U.T @ y
            
        self.intercept_ = self.coef_[0]
        self.coef_ = self.coef_[1:]
        
        # 计算Hat矩阵 H = X (X^T X)^{-1} X^T
        # 用于杠杆值与影响分析
        X_aug_pinv = np.linalg.pinv(X_aug)
        self.H = X_aug @ X_aug_pinv
        self.leverage_ = np.diag(self.H)
        
        return self
    
    def predict(self, X):
        """预测响应值"""
        return X @ self.coef_ + self.intercept_
    
    def bayesian_posterior(self, X, y, alpha=1.0, beta=1.0):
        """
        2.1.2.2 贝叶斯线性回归的后验分布计算
        alpha: 噪声精度先验 (1/sigma^2)
        beta: 权重先验精度 (1/lambda^2)
        """
        n_samples, n_features = X.shape
        X_aug = np.column_stack([np.ones(n_samples), X])
        
        # 后验精度矩阵 S^{-1} = beta I + alpha X^T X
        S_inv = beta * np.eye(n_features + 1) + alpha * X_aug.T @ X_aug
        # Cholesky分解用于稳定计算
        L = linalg.cholesky(S_inv, lower=True)
        
        # 后验均值 mu = alpha S X^T y
        temp = linalg.solve_triangular(L, X_aug.T @ y, lower=True)
        mu = alpha * linalg.solve_triangular(L.T, temp, lower=False)
        
        # 计算后验协方差 S = (S^{-1})^{-1}
        S = linalg.cho_solve((L, True), np.eye(n_features + 1))
        
        return mu, S
    
    def posterior_predictive(self, X_new, X_train, y_train, alpha=1.0, beta=1.0):
        """
        2.1.2.3 后验预测分布计算
        返回预测分布的均值与方差
        """
        mu_post, S_post = self.bayesian_posterior(X_train, y_train, alpha, beta)
        
        X_new_aug = np.column_stack([np.ones(X_new.shape[0]), X_new])
        
        # 预测均值
        y_pred_mean = X_new_aug @ mu_post
        
        # 预测方差: sigma^2 + X_new S X_new^T
        pred_var = 1.0/alpha + np.sum(X_new_aug @ S_post * X_new_aug, axis=1)
        
        return y_pred_mean, pred_var


def demo_numerical_stability():
    """
    演示Cholesky分解与直接求逆的数值稳定性差异
    特别是当设计矩阵具有较高条件数时
    """
    np.random.seed(42)
    
    # 构造病态矩阵(高度共线性)
    n_samples = 100
    x_base = np.random.randn(n_samples)
    X = np.column_stack([x_base, x_base + 1e-10 * np.random.randn(n_samples)])
    y = 2 * x_base + 1 + 0.1 * np.random.randn(n_samples)
    
    methods = ['direct', 'cholesky', 'svd']
    results = {}
    
    fig, axes = plt.subplots(1, 3, figsize=(15, 5))
    
    for idx, method in enumerate(methods):
        model = LinearRegressionNumerical(method=method)
        model.fit(X, y)
        
        results[method] = {
            'coef': model.coef_,
            'intercept': model.intercept_,
            'condition': model.condition_number_,
            'residual': np.linalg.norm(y - model.predict(X))
        }
        
        # 可视化杠杆值
        axes[idx].scatter(range(len(model.leverage_)), model.leverage_, 
                         c=model.leverage_, cmap='viridis', alpha=0.6)
        axes[idx].axhline(y=2*(X.shape[1]+1)/len(X), color='r', 
                         linestyle='--', label='Threshold: 2(p+1)/n')
        axes[idx].set_title(f'{method.upper()} Method\n'
                           f'Cond: {model.condition_number_:.2e}\n'
                           f'Residual: {results[method]["residual"]:.4f}')
        axes[idx].set_xlabel('Sample Index')
        axes[idx].set_ylabel('Leverage (Hat Diagonal)')
        axes[idx].legend()
        axes[idx].grid(True, alpha=0.3)
    
    plt.tight_layout()
    plt.savefig('numerical_stability_comparison.png', dpi=150, bbox_inches='tight')
    plt.show()
    
    print("数值稳定性对比:")
    for method, res in results.items():
        print(f"{method:10s}: Coef=[{res['coef'][0]:.6f}, {res['coef'][1]:.6f}], "
              f"Intercept={res['intercept']:.6f}, Cond={res['condition']:.2e}")


def demo_bayesian_approach():
    """
    演示贝叶斯线性回归与后验预测分布
    对比MLE与MAP估计的差异
    """
    np.random.seed(42)
    
    # 生成数据
    n_samples = 50
    X = np.linspace(-3, 3, n_samples).reshape(-1, 1)
    y_true = np.sin(X).ravel()
    y = y_true + 0.3 * np.random.randn(n_samples)
    
    # 多项式特征扩展以展示正则化效果
    from sklearn.preprocessing import PolynomialFeatures
    poly = PolynomialFeatures(degree=7, include_bias=False)
    X_poly = poly.fit_transform(X)
    
    # MLE估计(无正则化,对应alpha->inf, beta->0)
    model_mle = LinearRegressionNumerical(method='svd')
    model_mle.fit(X_poly, y)
    y_mle = model_mle.predict(X_poly)
    
    # MAP估计(Ridge回归,对应有限alpha, beta)
    alpha = 10.0  # 噪声精度
    beta = 0.1    # 权重先验精度(正则化强度)
    
    model_map = LinearRegressionNumerical(method='cholesky')
    mu_post, S_post = model_map.bayesian_posterior(X_poly, y, alpha=alpha, beta=beta)
    
    # 后验预测
    y_pred_mean, y_pred_var = model_map.posterior_predictive(
        X_poly, X_poly, y, alpha=alpha, beta=beta
    )
    y_pred_std = np.sqrt(y_pred_var)
    
    # 采样后验权重以展示不确定性
    n_posterior_samples = 100
    post_samples = multivariate_normal.rvs(mean=mu_post, cov=S_post, 
                                          size=n_posterior_samples)
    
    fig, axes = plt.subplots(1, 2, figsize=(14, 5))
    
    # 左图:MLE vs MAP对比
    axes[0].scatter(X, y, c='black', s=30, alpha=0.6, label='Observations')
    axes[0].plot(X, y_true, 'g-', linewidth=2, label='True Function')
    axes[0].plot(X, y_mle, 'r--', linewidth=2, label='MLE (No Regularization)')
    axes[0].plot(X, y_pred_mean, 'b-', linewidth=2, label='MAP (Ridge)')
    axes[0].fill_between(X.ravel(), 
                        y_pred_mean - 2*y_pred_std,
                        y_pred_mean + 2*y_pred_std,
                        alpha=0.3, color='blue', label='95% Predictive Interval')
    axes[0].set_title('MLE vs MAP Estimation\n(High-degree Polynomial)')
    axes[0].legend()
    axes[0].set_xlabel('x')
    axes[0].set_ylabel('y')
    axes[0].grid(True, alpha=0.3)
    
    # 右图:后验权重分布
    axes[1].bar(range(len(mu_post)), mu_post, yerr=2*np.sqrt(np.diag(S_post)),
               capsize=5, alpha=0.7, color='steelblue', edgecolor='black')
    axes[1].set_title('Posterior Mean of Weights\n(with 2σ Uncertainty)')
    axes[1].set_xlabel('Weight Index')
    axes[1].set_ylabel('Posterior Value')
    axes[1].grid(True, alpha=0.3, axis='y')
    
    plt.tight_layout()
    plt.savefig('bayesian_linear_regression.png', dpi=150, bbox_inches='tight')
    plt.show()
    
    print(f"\n贝叶斯分析结果:")
    print(f"噪声精度参数 alpha: {alpha}")
    print(f"权重先验精度 beta: {beta} (等价于Ridge的lambda={alpha/beta})")
    print(f"后验权重均值: {mu_post[:4]} ...")  # 只显示前4个


if __name__ == "__main__":
    demo_numerical_stability()
    demo_bayesian_approach()

 


2.2 正则化与稀疏性

2.2.1 L2正则化与Ridge回归

Ridge回归通过引入L2惩罚项处理设计矩阵的奇异或近奇异情形。奇异值分解揭示了Ridge估计量对最小二乘解的收缩效应:滤波系数以σj2​+λσj2​​ 的形式几何衰减,其中σj​ 为设计矩阵的奇异值。这种收缩机制有效地改善了条件数,使病态问题的数值求解趋于稳定。核化Ridge回归的对偶形式将计算复杂度从O(D3) 转换为O(N3) ,在高维特征空间(D≫N )中实现计算效率的逆转,为后续核方法的引入奠定算法基础。

2.2.2 L1正则化与Lasso回归

Lasso回归采用L1惩罚诱导参数稀疏性,优化问题不再具有解析解,需借助数值方法求解。软阈值算子作为近端映射的具体形式,构成了迭代收缩阈值算法(ISTA)的核心步骤。坐标下降法通过逐维度更新策略规避Hessian矩阵的显式构造,活跃集策略进一步加速收敛,仅对非零系数的子集执行迭代更新。最小角回归(LARS)则提供了整条正则化路径的高效计算,其几何解释与最小二乘的前向选择密切相关,在每一步选择与当前残差具有最大相关性的预测变量,并沿等角方向更新系数,直至所有变量进入模型或相关系数降至零。

2.2.3 弹性网络与结构化稀疏

弹性网络结合L1与L2惩罚,在保持稀疏性的同时处理组效应,避免高度相关变量选择时的随机排除现象。稀疏组Lasso扩展至多层级结构,通过分组惩罚项实现变量的层次化选择。快速迭代收缩阈值算法(FISTA)引入Nesterov动量加速策略,将收敛速率从O(1/k) 提升至O(1/k2) ,在大规模稀疏优化问题中显著减少迭代次数。

脚本2:正则化方法与稀疏优化实现

Python

"""
脚本2:正则化方法与稀疏优化算法实现
涉及内容:
- 2.2.1.1 Ridge回归的SVD视角与滤波系数分析
- 2.2.2.1 软阈值算子与坐标下降法实现Lasso
- 2.2.2.3 LARS算法完整路径求解
- 2.2.3.3 FISTA加速与Nesterov动量实现

使用方式:
python regularization_sparse_optimization.py
依赖:numpy, matplotlib, scikit-learn (仅用于数据生成对比)
"""

import numpy as np
import matplotlib.pyplot as plt
from itertools import cycle
import warnings

class RidgeRegressionSVD:
    """
    2.2.1.1 Ridge回归的SVD实现与滤波系数分析
    展示收缩效应的几何衰减特性
    """
    
    def __init__(self, lambdas=[0.01, 0.1, 1.0, 10.0]):
        self.lambdas = lambdas
        self.results_ = {}
        
    def fit(self, X, y):
        """
        使用SVD分解实现Ridge回归
        X = U S V^T, w_ridge = V (S^2 + lambda I)^{-1} S U^T y
        """
        # 中心化处理
        self.mean_X = X.mean(axis=0)
        self.mean_y = y.mean()
        X_centered = X - self.mean_X
        y_centered = y - self.mean_y
        
        # SVD分解
        U, s, Vh = np.linalg.svd(X_centered, full_matrices=False)
        V = Vh.T
        
        for lam in self.lambdas:
            # 滤波系数: s_j^2 / (s_j^2 + lambda)
            filter_coef = s**2 / (s**2 + lam)
            # Ridge系数
            w = V @ np.diag(filter_coef / s) @ U.T @ y_centered
            
            self.results_[lam] = {
                'coef': w,
                'filter': filter_coef,
                'singular_values': s,
                'effective_df': np.sum(filter_coef)  # 有效自由度
            }
            
        return self
    
    def plot_shrinkage(self):
        """可视化奇异值收缩效应"""
        fig, axes = plt.subplots(1, 2, figsize=(14, 5))
        
        # 左图:滤波系数随lambda变化
        s = self.results_[self.lambdas[0]]['singular_values']
        for lam in self.lambdas:
            axes[0].plot(range(1, len(s)+1), 
                        self.results_[lam]['filter'], 
                        'o-', label=f'λ={lam}', markersize=6)
        axes[0].set_xlabel('Singular Value Index')
        axes[0].set_ylabel('Filter Coefficient σ²/(σ²+λ)')
        axes[0].set_title('Geometric Decay of Filter Coefficients\n(Ridge Shrinkage Effect)')
        axes[0].legend()
        axes[0].grid(True, alpha=0.3)
        axes[0].set_ylim(0, 1.05)
        
        # 右图:有效自由度与lambda关系
        eff_dfs = [self.results_[lam]['effective_df'] for lam in self.lambdas]
        axes[1].semilogx(self.lambdas, eff_dfs, 'bo-', markersize=8, linewidth=2)
        axes[1].set_xlabel('Regularization Parameter λ')
        axes[1].set_ylabel('Effective Degrees of Freedom')
        axes[1].set_title('Effective DoF vs Regularization Strength')
        axes[1].grid(True, alpha=0.3)
        
        plt.tight_layout()
        plt.savefig('ridge_shrinkage_analysis.png', dpi=150, bbox_inches='tight')
        plt.show()


class LassoCoordinateDescent:
    """
    2.2.2.1 坐标下降法实现Lasso
    结合软阈值算子与活跃集策略
    """
    
    def __init__(self, lambda_reg=0.1, max_iter=1000, tol=1e-4, 
                 active_set=True):
        self.lambda_reg = lambda_reg
        self.max_iter = max_iter
        self.tol = tol
        self.active_set = active_set
        self.coef_path_ = []
        
    def _soft_threshold(self, z, gamma):
        """软阈值算子: sign(z) * max(|z| - gamma, 0)"""
        return np.sign(z) * np.maximum(np.abs(z) - gamma, 0)
    
    def fit(self, X, y):
        """
        坐标下降法求解Lasso
        活跃集策略:仅更新非零系数以加速收敛
        """
        n_samples, n_features = X.shape
        
        # 标准化
        self.X_mean = X.mean(axis=0)
        self.X_std = X.std(axis=0) + 1e-8
        self.y_mean = y.mean()
        
        X_std = (X - self.X_mean) / self.X_std
        y_std = y - self.y_mean
        
        # 初始化
        w = np.zeros(n_features)
        residuals = y_std.copy()
        
        # 预计算X的列范数(用于标准化lambda)
        x_norms = np.sum(X_std**2, axis=0)
        
        for iteration in range(self.max_iter):
            w_old = w.copy()
            
            if self.active_set and iteration > 0:
                # 活跃集策略:仅更新当前非零的系数
                active_indices = np.where(w != 0)[0]
                if len(active_indices) == 0:
                    active_indices = range(n_features)
            else:
                active_indices = range(n_features)
            
            # 坐标下降循环
            for j in active_indices:
                # 残差扣除第j个特征的影响
                residuals += X_std[:, j] * w[j]
                
                # 偏相关
                rho_j = np.dot(X_std[:, j], residuals)
                
                # 软阈值更新
                w[j] = self._soft_threshold(rho_j / x_norms[j], 
                                           self.lambda_reg / x_norms[j])
                
                # 残差更新
                residuals -= X_std[:, j] * w[j]
            
            # 记录路径
            if iteration % 10 == 0:
                self.coef_path_.append(w.copy())
            
            # 收敛判断
            if np.max(np.abs(w - w_old)) < self.tol:
                break
                
        self.coef_ = w / self.X_std  # 反标准化
        self.intercept_ = self.y_mean - np.dot(self.X_mean, self.coef_)
        self.n_iter_ = iteration + 1
        
        return self
    
    def predict(self, X):
        return X @ self.coef_ + self.intercept_


class LARS:
    """
    2.2.2.3 最小角回归(LARS)实现
    计算完整正则化路径,等角方向更新
    """
    
    def __init__(self):
        self.coef_path_ = None
        self.lambda_path_ = None
        
    def fit(self, X, y):
        """
        LARS算法实现
        基于Efron et al. (2004) Annals of Statistics
        """
        n_samples, n_features = X.shape
        
        # 标准化
        X = X / np.sqrt(np.sum(X**2, axis=0))
        
        # 初始化
        beta = np.zeros(n_features)
        mu = np.zeros(n_samples)  # 当前预测值
        c = X.T @ y  # 当前相关性
        
        # 路径记录
        self.coef_path_ = [beta.copy()]
        self.lambda_path_ = [np.max(np.abs(c))]
        
        active_set = []
        signs = np.zeros(n_features)
        n_iter = min(n_features, n_samples - 1)
        
        for _ in range(n_iter):
            # 寻找最大相关性变量
            c_abs = np.abs(c)
            C_max = np.max(c_abs)
            
            if C_max < 1e-12:
                break
                
            # 加入活跃集
            j = np.argmax(c_abs)
            if j not in active_set:
                active_set.append(j)
                signs[j] = np.sign(c[j])
            
            # 计算等角方向
            X_A = X[:, active_set] * signs[active_set]
            G_A = X_A.T @ X_A  # Gram矩阵
            
            try:
                # 求解等角方向 A_A = (G_A)^{-1} 1_A
                ones_A = np.ones(len(active_set))
                w_A = np.linalg.solve(G_A, ones_A)
                # 归一化
                A_A = 1 / np.sqrt(np.sum(w_A))
                u_A = X_A @ w_A * A_A
                
                # 计算步长
                a = X.T @ u_A
                
                # 计算加入新变量的gamma
                gamma_candidates = []
                for j_inactive in range(n_features):
                    if j_inactive not in active_set:
                        cc = c[j_inactive]
                        aa = a[j_inactive]
                        # 方程 (C_max - cc) / (A_A - aa) 和 (C_max + cc) / (A_A + aa)
                        if abs(A_A - aa) > 1e-12:
                            gamma_candidates.append((C_max - cc) / (A_A - aa))
                        if abs(A_A + aa) > 1e-12:
                            gamma_candidates.append((C_max + cc) / (A_A + aa))
                
                if len(gamma_candidates) > 0:
                    gamma = np.min([g for g in gamma_candidates if g > 1e-12])
                else:
                    gamma = C_max / A_A
                
            except np.linalg.LinAlgError:
                # 数值问题,使用伪逆
                break
            
            # 更新系数和预测值
            for idx, var_idx in enumerate(active_set):
                beta[var_idx] += gamma * signs[var_idx] * w_A[idx] * A_A
            
            mu += gamma * u_A
            c = X.T @ (y - mu)
            
            self.coef_path_.append(beta.copy())
            self.lambda_path_.append(np.max(np.abs(c)) if len(c) > 0 else 0)
            
        self.coef_path_ = np.array(self.coef_path_)
        self.lambda_path_ = np.array(self.lambda_path_)
        self.coef_ = beta
        
        return self


class FISTA:
    """
    2.2.3.3 FISTA加速近端梯度下降
    用于Elastic Net优化,收敛率O(1/k^2)
    """
    
    def __init__(self, lambda_reg=0.1, alpha=0.5, max_iter=500, tol=1e-6):
        """
        alpha: Elastic Net混合参数 (0=纯Ridge, 1=纯Lasso)
        """
        self.lambda_reg = lambda_reg
        self.alpha = alpha  # L1比例
        self.max_iter = max_iter
        self.tol = tol
        
    def _soft_threshold(self, x, gamma):
        return np.sign(x) * np.maximum(np.abs(x) - gamma, 0)
    
    def fit(self, X, y):
        """
        FISTA算法实现
        基于Nesterov加速: t_{k+1} = (1 + sqrt(1 + 4*t_k^2)) / 2
        """
        n_samples, n_features = X.shape
        
        # 初始化
        w = np.zeros(n_features)
        w_old = w.copy()
        t = 1.0
        
        # Lipschitz常数估计(谱范数)
        L = np.linalg.norm(X, ord=2)**2 + 1e-8
        
        for k in range(self.max_iter):
            # 外推点
            y_k = w + ((t - 1) / (t + 1)) * (w - w_old)  # Nesterov动量
            
            # 梯度计算(平滑部分:最小二乘 + Ridge)
            grad = X.T @ (X @ y_k - y) / n_samples + \
                   (1 - self.alpha) * self.lambda_reg * y_k
            
            # 近端映射(L1部分)
            w_new = self._soft_threshold(
                y_k - grad / L, 
                self.alpha * self.lambda_reg / L
            )
            
            # 收敛判断
            if np.linalg.norm(w_new - w) < self.tol:
                break
            
            # 更新动量参数
            t_new = (1 + np.sqrt(1 + 4 * t**2)) / 2
            
            w_old = w.copy()
            w = w_new
            t = t_new
            
        self.coef_ = w
        self.n_iter_ = k + 1
        return self


def demo_regularization_paths():
    """
    对比Ridge、Lasso、LARS的正则化路径
    """
    np.random.seed(42)
    
    # 构造稀疏数据
    n_samples, n_features = 50, 10
    true_coef = np.array([5, -4, 3, 0, 0, 0, 0, 2, 0, 0])
    X = np.random.randn(n_samples, n_features)
    y = X @ true_coef + 0.5 * np.random.randn(n_samples)
    
    # Ridge路径(使用SVD)
    lambdas = np.logspace(-3, 2, 50)
    ridge_coefs = []
    
    U, s, Vh = np.linalg.svd(X, full_matrices=False)
    for lam in lambdas:
        filter_coef = s / (s**2 + lam)
        w = Vh.T @ np.diag(filter_coef) @ U.T @ y
        ridge_coefs.append(w)
    ridge_coefs = np.array(ridge_coefs)
    
    # LARS路径
    lars = LARS()
    lars.fit(X, y)
    
    # 绘制对比
    fig, axes = plt.subplots(1, 2, figsize=(14, 6))
    
    # Ridge路径
    for i in range(n_features):
        axes[0].plot(lambdas, ridge_coefs[:, i], label=f'Feature {i+1}' if i < 3 else '')
    axes[0].set_xscale('log')
    axes[0].set_xlabel('Regularization Parameter λ')
    axes[0].set_ylabel('Coefficient Value')
    axes[0].set_title('Ridge Regression Path\n(Smooth Shrinkage)')
    axes[0].legend()
    axes[0].grid(True, alpha=0.3)
    
    # LARS路径
    for i in range(n_features):
        axes[1].plot(lars.lambda_path_, lars.coef_path_[:, i], 
                    marker='o', markersize=3, label=f'Feature {i+1}' if i < 3 else '')
    axes[1].set_xlabel('Max Correlation (λ equivalent)')
    axes[1].set_ylabel('Coefficient Value')
    axes[1].set_title('LARS Path\n(Piecewise Linear with Knots)')
    axes[1].legend()
    axes[1].grid(True, alpha=0.3)
    
    plt.tight_layout()
    plt.savefig('regularization_paths.png', dpi=150, bbox_inches='tight')
    plt.show()
    
    print(f"LARS路径长度: {len(lars.lambda_path_)}")
    print(f"LARS最终非零系数数量: {np.sum(lars.coef_ != 0)}")


if __name__ == "__main__":
    # 生成测试数据
    np.random.seed(42)
    X = np.random.randn(100, 8)
    true_w = np.array([3, -2, 1.5, 0, 0, 0, 0.5, 0])
    y = X @ true_w + 0.3 * np.random.randn(100)
    
    # Ridge SVD分析
    print("=== Ridge SVD分析 ===")
    ridge = RidgeRegressionSVD(lambdas=[0.001, 0.01, 0.1, 1.0, 10.0])
    ridge.fit(X, y)
    ridge.plot_shrinkage()
    
    # Lasso坐标下降
    print("\n=== Lasso坐标下降 ===")
    lasso = LassoCoordinateDescent(lambda_reg=0.2, active_set=True)
    lasso.fit(X, y)
    print(f"迭代次数: {lasso.n_iter_}")
    print(f"非零系数: {np.sum(lasso.coef_ != 0)} / {len(lasso.coef_)}")
    print(f"估计系数: {np.round(lasso.coef_, 3)}")
    print(f"真实系数: {true_w}")
    
    # LARS
    print("\n=== LARS算法 ===")
    lars = LARS()
    lars.fit(X, y)
    print(f"路径步数: {len(lars.lambda_path_)}")
    
    # FISTA
    print("\n=== FISTA加速 ===")
    fista = FISTA(lambda_reg=0.2, alpha=0.8, max_iter=1000)
    fista.fit(X, y)
    print(f"FISTA迭代次数: {fista.n_iter_}")
    print(f"非零系数: {np.sum(fista.coef_ != 0)}")
    
    # 路径可视化
    demo_regularization_paths()

运行结果

=== Ridge SVD分析 ===

=== Lasso坐标下降 ===
迭代次数: 6
非零系数: 7 / 8
估计系数: [ 3.008e+00 -1.952e+00  1.498e+00 -1.500e-02 -3.000e-03  0.000e+00
  4.620e-01  1.800e-02]
真实系数: [ 3.  -2.   1.5  0.   0.   0.   0.5  0. ]

=== LARS算法 ===
路径步数: 9

=== FISTA加速 ===
FISTA迭代次数: 1000
非零系数: 4
LARS路径长度: 11
LARS最终非零系数数量: 4


2.3 分类模型:从线性到概率

2.3.1 感知机与逻辑回归

感知机算法通过迭代更新权重向量寻找分离超平面,Novikoff收敛定理保证了在数据线性可分时算法在有限步内终止,间隔(Margin)的大小直接影响收敛速度的上界。对数几率回归将分类问题纳入概率框架,通过极大似然估计优化对数似然函数,其目标函数为凸函数保证全局最优解的存在。迭代重加权最小二乘(IRLS)算法将非线性优化问题转化为一系列加权最小二乘子问题,每步迭代基于当前参数估计计算工作响应与权重矩阵,利用Newton-Raphson方法实现二次收敛速率,Hessian矩阵的解析形式为XTWX ,其中W 为对角的方差权重矩阵。

2.3.2 多类分类与Softmax回归

Softmax回归将二分类逻辑回归扩展至多类情形,输出层的概率分布通过指数归一化获得。数值稳定性实践中需采用Log-Sum-Exp技巧避免指数运算的上溢或下溢。多项分布的广义线性模型形式与交叉熵损失的等价性通过最大似然估计建立,多类逻辑回归的Hessian矩阵具有分块结构,利用Kronecker积或稀疏结构可优化高维参数优化中的存储与计算。

2.3.3 概率生成模型

高斯判别分析假设类条件分布服从多元高态,通过共享或独立协方差矩阵分别导出线性判别分析(LDA)与二次判别分析(QDA)。协方差共享机制减少了待估参数数量,在样本量有限时降低过拟合风险。朴素贝叶斯基于特征条件独立性假设,通过拉普拉斯平滑处理零概率问题。生成式与判别式模型的渐近误差分析表明,生成式模型在模型设定正确时收敛更快,而判别式模型对模型误设具有更强的鲁棒性。

脚本3:分类模型与概率实现

"""
脚本3:分类模型与概率生成/判别式实现
涉及内容:
- 2.3.1.3 IRLS算法Newton-Raphson实现与Hessian计算
- 2.3.2.1 Softmax数值稳定性技巧(Log-Sum-Exp)
- 2.3.2.3 多类Hessian分块结构优化
- 2.3.3.1 GDA/QDA协方差共享推导实现

使用方式:
python classification_models.py
依赖:numpy, matplotlib, scipy
"""

import numpy as np
import matplotlib.pyplot as plt
from scipy.linalg import block_diag
from scipy.special import logsumexp
import warnings

class LogisticRegressionIRLS:
    """
    2.3.1.3 迭代重加权最小二乘(IRLS)实现
    Newton-Raphson方法,显式Hessian计算
    """
    
    def __init__(self, max_iter=100, tol=1e-6, fit_intercept=True):
        self.max_iter = max_iter
        self.tol = tol
        self.fit_intercept = fit_intercept
        self.coef_ = None
        self.intercept_ = None
        self.convergence_history_ = []
        
    def _sigmoid(self, z):
        """数值稳定的sigmoid实现"""
        # 防止溢出
        return np.where(z >= 0, 
                       1 / (1 + np.exp(-z)), 
                       np.exp(z) / (1 + np.exp(z)))
    
    def fit(self, X, y):
        """
        IRLS算法实现
        基于Fisher评分:w_new = w + (X^T W X)^{-1} X^T (y - p)
        其中W是权重矩阵,对角线元素为 p(1-p)
        """
        n_samples, n_features = X.shape
        
        # 添加截距项
        if self.fit_intercept:
            X_aug = np.column_stack([np.ones(n_samples), X])
        else:
            X_aug = X
            
        # 初始化
        w = np.zeros(X_aug.shape[1])
        
        for i in range(self.max_iter):
            # 线性预测
            z = X_aug @ w
            p = self._sigmoid(z)
            
            # 工作响应(Working Response)
            # z_working = z + (y - p) / (p * (1 - p))
            # 但直接计算权重矩阵W更稳定
            W_diag = p * (1 - p)
            W_diag = np.maximum(W_diag, 1e-8)  # 防止除零
            
            # 梯度(Score Function): X^T (y - p)
            gradient = X_aug.T @ (y - p)
            
            # Hessian: -X^T W X
            # 使用Cholesky分解求解线性系统避免直接求逆
            try:
                # 构造加权设计矩阵 sqrt(W) * X
                X_weighted = X_aug * np.sqrt(W_diag)[:, np.newaxis]
                # 正规方程: (X^T W X) delta = X^T (y - p)
                A = X_weighted.T @ X_weighted
                # 添加微小正则化确保正定性
                A += 1e-8 * np.eye(A.shape[0])
                
                # 求解更新方向
                L = np.linalg.cholesky(A)
                temp = np.linalg.solve(L, gradient)
                delta = np.linalg.solve(L.T, temp)
                
            except np.linalg.LinAlgError:
                # 回退到伪逆
                H = -X_aug.T @ np.diag(W_diag) @ X_aug
                delta = -np.linalg.pinv(H) @ gradient
            
            # 更新参数
            w_new = w + delta
            
            # 记录收敛历史
            loss = -np.sum(y * np.log(p + 1e-10) + (1-y) * np.log(1-p + 1e-10))
            self.convergence_history_.append(loss)
            
            # 收敛判断
            if np.linalg.norm(delta) < self.tol:
                break
                
            w = w_new
            
        if self.fit_intercept:
            self.intercept_ = w[0]
            self.coef_ = w[1:]
        else:
            self.coef_ = w
            
        self.n_iter_ = i + 1
        return self
    
    def predict_proba(self, X):
        z = X @ self.coef_ + (self.intercept_ if self.fit_intercept else 0)
        return self._sigmoid(z)
    
    def predict(self, X):
        return (self.predict_proba(X) >= 0.5).astype(int)


class SoftmaxRegression:
    """
    2.3.2.1 Softmax回归实现
    包含Log-Sum-Exp数值稳定性技巧
    """
    
    def __init__(self, max_iter=100, tol=1e-6, reg_lambda=0.01):
        self.max_iter = max_iter
        self.tol = tol
        self.reg_lambda = reg_lambda
        
    def _softmax_stable(self, Z):
        """
        数值稳定的Softmax实现
        减去每行的最大值防止指数上溢
        """
        # Log-Sum-Exp技巧
        Z_max = np.max(Z, axis=1, keepdims=True)
        exp_Z = np.exp(Z - Z_max)
        return exp_Z / np.sum(exp_Z, axis=1, keepdims=True)
    
    def _compute_hessian_block(self, X, P, n_classes):
        """
        2.3.2.3 计算多类Hessian的分块结构
        Hessian是块对角矩阵,每块为 -X^T W_k X
        总维度 (n_classes * n_features) x (n_classes * n_features)
        """
        n_samples, n_features = X.shape
        
        # 对于多类逻辑回归,Hessian是Kronecker积结构
        # 这里实现简化的块对角近似用于教学演示
        
        hessian_blocks = []
        for k in range(n_classes):
            # 第k类的权重矩阵
            W_k = P[:, k] * (1 - P[:, k])
            H_k = -X.T @ np.diag(W_k) @ X - self.reg_lambda * np.eye(n_features)
            hessian_blocks.append(H_k)
            
        # 构造块对角Hessian(近似)
        return block_diag(*hessian_blocks)
    
    def fit(self, X, y):
        """
        多类逻辑回归的Newton-Raphson实现
        参数W为 n_features x n_classes 矩阵
        """
        n_samples, n_features = X.shape
        n_classes = len(np.unique(y))
        
        # One-hot编码
        Y_onehot = np.eye(n_classes)[y]
        
        # 初始化参数 (增广X以包含截距)
        X_aug = np.column_stack([np.ones(n_samples), X])
        n_aug_features = X_aug.shape[1]
        
        # 向量化参数: (n_aug_features * n_classes) x 1
        W = np.zeros((n_aug_features, n_classes))
        
        for iteration in range(self.max_iter):
            # 线性预测 n_samples x n_classes
            Z = X_aug @ W
            
            # 概率预测(数值稳定)
            P = self._softmax_stable(Z)
            
            # 梯度: X_aug^T (P - Y_onehot) + reg
            G = X_aug.T @ (P - Y_onehot) + self.reg_lambda * W
            
            # 向量化梯度用于收敛判断
            g_vec = G.ravel()
            
            # Hessian计算与求解(分块Newton-Raphson)
            # 使用IRLS风格的加权最小二乘近似
            W_old = W.copy()
            
            for k in range(n_classes):
                # 第k类的IRLS更新
                W_k_diag = P[:, k] * (1 - P[:, k])
                # 加权正规方程
                X_weighted = X_aug * np.sqrt(W_k_diag)[:, np.newaxis]
                
                try:
                    # Cholesky求解
                    A = X_weighted.T @ X_weighted + self.reg_lambda * np.eye(n_aug_features)
                    L = np.linalg.cholesky(A)
                    temp = np.linalg.solve(L, G[:, k])
                    update_k = np.linalg.solve(L.T, temp)
                    W[:, k] -= 0.5 * update_k  # 步长0.5确保收敛
                except:
                    # 梯度下降回退
                    W[:, k] -= 0.01 * G[:, k]
            
            # 收敛判断
            if np.linalg.norm(W - W_old) < self.tol:
                break
                
        self.coef_ = W[1:, :]
        self.intercept_ = W[0, :]
        self.classes_ = np.unique(y)
        return self
    
    def predict_proba(self, X):
        n_samples = X.shape[0]
        X_aug = np.column_stack([np.ones(n_samples), X])
        W = np.row_stack([self.intercept_, self.coef_])
        Z = X_aug @ W
        return self._softmax_stable(Z)
    
    def predict(self, X):
        proba = self.predict_proba(X)
        return self.classes_[np.argmax(proba, axis=1)]


class GaussianDiscriminantAnalysis:
    """
    2.3.3.1 高斯判别分析(GDA)
    实现LDA(共享协方差)与QDA(独立协方差)
    """
    
    def __init__(self, shared_covariance=True):
        self.shared_covariance = shared_covariance
        self.classes_ = None
        self.phi_ = None  # 类先验
        self.mu_ = None   # 类均值
        self.sigma_ = None  # 共享协方差(LDA)
        self.sigma_k_ = None  # 独立协方差(QDA)
        
    def fit(self, X, y):
        """
        拟合GDA模型
        共享协方差时为LDA,独立时为QDA
        """
        self.classes_ = np.unique(y)
        n_samples, n_features = X.shape
        n_classes = len(self.classes_)
        
        # 估计类先验
        self.phi_ = np.array([np.mean(y == k) for k in self.classes_])
        
        # 估计类均值
        self.mu_ = np.array([X[y == k].mean(axis=0) for k in self.classes_])
        
        if self.shared_covariance:
            # LDA: 共享协方差矩阵(加权平均)
            sigma = np.zeros((n_features, n_features))
            for idx, k in enumerate(self.classes_):
                X_k = X[y == k]
                diff = X_k - self.mu_[idx]
                sigma += self.phi_[idx] * (diff.T @ diff / len(X_k))
            self.sigma_ = sigma
            
            # 预计算逆矩阵与行列式
            self.sigma_inv_ = np.linalg.pinv(self.sigma_)
            self.sigma_det_ = np.linalg.det(self.sigma_)
        else:
            # QDA: 独立协方差矩阵
            self.sigma_k_ = []
            self.sigma_inv_k_ = []
            self.sigma_det_k_ = []
            
            for idx, k in enumerate(self.classes_):
                X_k = X[y == k]
                diff = X_k - self.mu_[idx]
                sigma_k = (diff.T @ diff) / len(X_k)
                self.sigma_k_.append(sigma_k)
                self.sigma_inv_k_.append(np.linalg.pinv(sigma_k))
                self.sigma_det_k_.append(np.linalg.det(sigma_k))
                
        return self
    
    def _log_gaussian_prob(self, X, mu, sigma_inv, sigma_det):
        """计算多元高斯对数概率"""
        diff = X - mu
        # log N(x; mu, sigma) = -0.5 * (log|sigma| + (x-mu)^T sigma^{-1} (x-mu) + d*log(2*pi))
        mahalanobis = np.sum(diff @ sigma_inv * diff, axis=1)
        log_prob = -0.5 * (np.log(sigma_det + 1e-8) + mahalanobis + X.shape[1] * np.log(2*np.pi))
        return log_prob
    
    def predict_log_proba(self, X):
        """预测对数概率"""
        n_samples = X.shape[0]
        log_probs = np.zeros((n_samples, len(self.classes_)))
        
        for idx, k in enumerate(self.classes_):
            if self.shared_covariance:
                # LDA: 共享协方差,线性决策边界
                log_likelihood = self._log_gaussian_prob(
                    X, self.mu_[idx], self.sigma_inv_, self.sigma_det_
                )
            else:
                # QDA: 独立协方差,二次决策边界
                log_likelihood = self._log_gaussian_prob(
                    X, self.mu_[idx], 
                    self.sigma_inv_k_[idx], 
                    self.sigma_det_k_[idx]
                )
            
            log_probs[:, idx] = np.log(self.phi_[idx] + 1e-10) + log_likelihood
            
        # 使用log-sum-exp技巧归一化
        log_probs -= logsumexp(log_probs, axis=1, keepdims=True)
        return log_probs
    
    def predict(self, X):
        log_probs = self.predict_log_proba(X)
        return self.classes_[np.argmax(log_probs, axis=1)]


def demo_classification_models():
    """
    演示二分类与多分类模型的对比
    """
    np.random.seed(42)
    
    # 构造二分类数据
    n_samples = 200
    X_class0 = np.random.multivariate_normal([0, 0], [[1, 0.5], [0.5, 1]], n_samples//2)
    X_class1 = np.random.multivariate_normal([3, 3], [[1, -0.5], [-0.5, 1]], n_samples//2)
    X_binary = np.vstack([X_class0, X_class1])
    y_binary = np.array([0]*(n_samples//2) + [1]*(n_samples//2))
    
    # 训练Logistic回归
    log_reg = LogisticRegressionIRLS(max_iter=50)
    log_reg.fit(X_binary, y_binary)
    
    # 训练LDA与QDA
    lda = GaussianDiscriminantAnalysis(shared_covariance=True)
    lda.fit(X_binary, y_binary)
    
    qda = GaussianDiscriminantAnalysis(shared_covariance=False)
    qda.fit(X_binary, y_binary)
    
    # 可视化决策边界
    fig, axes = plt.subplots(1, 3, figsize=(18, 5))
    
    models = [
        (log_reg, 'Logistic Regression (IRLS)', 'coef_'),
        (lda, 'LDA (Shared Covariance)', 'mu_'),
        (qda, 'QDA (Independent Covariance)', 'mu_')
    ]
    
    for idx, (model, title, attr) in enumerate(models):
        # 绘制数据点
        axes[idx].scatter(X_binary[y_binary==0, 0], X_binary[y_binary==0, 1], 
                         c='blue', alpha=0.5, label='Class 0')
        axes[idx].scatter(X_binary[y_binary==1, 0], X_binary[y_binary==1, 1], 
                         c='red', alpha=0.5, label='Class 1')
        
        # 绘制决策边界
        x_min, x_max = X_binary[:, 0].min() - 1, X_binary[:, 0].max() + 1
        y_min, y_max = X_binary[:, 1].min() - 1, X_binary[:, 1].max() + 1
        xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100),
                            np.linspace(y_min, y_max, 100))
        grid = np.c_[xx.ravel(), yy.ravel()]
        
        if isinstance(model, LogisticRegressionIRLS):
            Z = model.predict_proba(grid).reshape(xx.shape)
        else:
            Z = np.exp(model.predict_log_proba(grid))[:, 1].reshape(xx.shape)
            
        axes[idx].contourf(xx, yy, Z, levels=20, alpha=0.3, cmap='RdBu')
        axes[idx].contour(xx, yy, Z, levels=[0.5], colors='k', linewidths=2)
        
        axes[idx].set_title(title)
        axes[idx].legend()
        axes[idx].set_xlabel('Feature 1')
        axes[idx].set_ylabel('Feature 2')
        axes[idx].grid(True, alpha=0.3)
    
    plt.tight_layout()
    plt.savefig('classification_boundaries.png', dpi=150, bbox_inches='tight')
    plt.show()
    
    # 多分类演示
    print("\n=== 多分类Softmax回归 ===")
    X_multi = np.random.randn(300, 4)
    true_w = np.array([[2, -1, 0.5], [1, 2, -1], [-0.5, 1, 1.5], [0, 0, 1]])
    logits = X_multi @ true_w
    y_multi = np.argmax(logits + 0.5*np.random.randn(300, 3), axis=1)
    
    softmax = SoftmaxRegression(max_iter=200)
    softmax.fit(X_multi, y_multi)
    
    acc = np.mean(softmax.predict(X_multi) == y_multi)
    print(f"Softmax训练准确率: {acc:.4f}")
    print(f"Softmax迭代次数: {softmax.n_iter_}")


if __name__ == "__main__":
    demo_classification_models()


2.4 基函数与非线性扩展

2.4.1 多项式回归与样条

多项式回归通过范德蒙德矩阵构造特征映射,其条件数随阶数增长呈指数恶化,导致数值不稳定。正交多项式基(Legendre、Chebyshev)通过Gram-Schmidt正交化或递推关系构造,在区间上关于特定权函数正交,显著改善设计矩阵的条件数。三次样条插值要求分段三次多项式在节点处保持连续的二阶导数,自然边界条件设定端点二阶导数为零,将插值问题转化为三对角线性系统的求解,利用Thomas算法可在O(N) 时间内完成。B-样条基函数通过de Boor-Cox递推公式构造,具备局部支撑性质,即每个基函数仅在有限区间内非零,这一特性使B-样条在局部数据修改时具有计算稳定性,de Boor算法提供了高效的递归计算框架。

2.4.2 径向基函数与核方法初步

径向基函数网络以输入到中心点的径向距离作为非线性映射,中心点的选择通过K-Means聚类或正交最小二乘(OLS)优化。高斯过程回归建立了函数空间视角与权重空间视角的等价性,通过Mercer定理保证核函数对应无穷维特征空间的合法映射,协方差函数(核函数)直接定义函数空间的相似性度量,规避了显式特征映射的计算。

脚本4:基函数方法与核方法实现

"""
脚本4:基函数方法与核方法实现
涉及内容:
- 2.4.1.1 正交多项式基(Legendre/Chebyshev)与条件数改善
- 2.4.1.3 B-样条的de Boor-Cox递推实现
- 2.4.2.1 RBF网络中心点选择(K-Means/OLS)
- 2.4.2.2 高斯过程的权重空间与函数空间视角

使用方式:
python basis_functions_kernels.py
依赖:numpy, matplotlib, scipy
"""

import numpy as np
import matplotlib.pyplot as plt
from scipy.special import legendre, chebyt
from scipy.linalg import solve_banded
from scipy.spatial.distance import cdist
from sklearn.cluster import KMeans

class OrthogonalPolynomialBasis:
    """
    2.4.1.1 正交多项式基实现
    对比范德蒙德矩阵与正交多项式的条件数
    """
    
    def __init__(self, degree=10, poly_type='legendre'):
        self.degree = degree
        self.poly_type = poly_type
        
    def _vandermonde(self, x):
        """标准范德蒙德矩阵(病态)"""
        return np.vander(x, self.degree + 1, increasing=True)
    
    def _legendre_basis(self, x):
        """
        Legendre多项式基(区间[-1,1]正交)
        通过递推关系构造数值稳定
        """
        # 映射到[-1, 1]
        x_scaled = 2 * (x - x.min()) / (x.max() - x.min()) - 1
        
        basis = np.zeros((len(x), self.degree + 1))
        for d in range(self.degree + 1):
            # 使用scipy的Legendre函数
            coeffs = [0] * d + [1]
            P_d = legendre(d)
            basis[:, d] = P_d(x_scaled)
        return basis
    
    def _chebyshev_basis(self, x):
        """
        Chebyshev多项式基(第一类)
        在[-1,1]上关于权函数(1-x^2)^{-1/2}正交
        """
        x_scaled = 2 * (x - x.min()) / (x.max() - x.min()) - 1
        
        basis = np.zeros((len(x), self.degree + 1))
        for d in range(self.degree + 1):
            T_d = chebyt(d)
            basis[:, d] = T_d(x_scaled)
        return basis
    
    def fit_transform(self, x):
        """根据类型返回相应的基"""
        if self.poly_type == 'vandermonde':
            return self._vandermonde(x)
        elif self.poly_type == 'legendre':
            return self._legendre_basis(x)
        elif self.poly_type == 'chebyshev':
            return self._chebyshev_basis(x)
        else:
            raise ValueError(f"Unknown type: {self.poly_type}")
    
    def compare_condition_numbers(self, x):
        """对比不同多项式基的条件数"""
        types = ['vandermonde', 'legendre', 'chebyshev']
        cond_numbers = []
        
        for t in types:
            self.poly_type = t
            X_basis = self.fit_transform(x)
            cond = np.linalg.cond(X_basis)
            cond_numbers.append(cond)
            
        return dict(zip(types, cond_numbers))


class BSplineBasis:
    """
    2.4.1.3 B-样条基函数实现
    de Boor-Cox递推公式
    """
    
    def __init__(self, degree=3, n_knots=10):
        self.degree = degree
        self.n_knots = n_knots
        
    def _cox_deboor_recursion(self, x, i, k, knots):
        """
        de Boor-Cox递推公式实现
        B_{i,0}(x) = 1 if knots[i] <= x < knots[i+1], else 0
        B_{i,k}(x) = w_{i,k}(x) B_{i,k-1}(x) + (1-w_{i+1,k}(x)) B_{i+1,k-1}(x)
        其中 w_{i,k}(x) = (x - knots[i]) / (knots[i+k] - knots[i])
        """
        if k == 0:
            # 0次基函数(指示函数)
            if i < len(knots) - 1:
                return np.where((x >= knots[i]) & (x < knots[i+1]), 1.0, 0.0)
            return np.zeros_like(x)
        
        # 递归计算
        B_im1 = self._cox_deboor_recursion(x, i, k-1, knots)
        B_ip1 = self._cox_deboor_recursion(x, i+1, k-1, knots)
        
        # 计算权重(处理除零)
        left_denom = knots[i+k] - knots[i]
        right_denom = knots[i+k+1] - knots[i+1]
        
        w_left = np.zeros_like(x)
        w_right = np.zeros_like(x)
        
        if abs(left_denom) > 1e-10:
            w_left = (x - knots[i]) / left_denom
        if abs(right_denom) > 1e-10:
            w_right = (knots[i+k+1] - x) / right_denom
            
        return w_left * B_im1 + w_right * B_ip1
    
    def fit_transform(self, x):
        """
        生成B-样条基矩阵
        使用重复的边界节点实现自然边界条件
        """
        x_min, x_max = x.min(), x.max()
        
        # 创建节点向量(Clamped,重复边界)
        interior_knots = np.linspace(x_min, x_max, self.n_knots)
        # 边界节点重复degree+1次以实现插值性质
        knots = np.concatenate([
            [x_min] * (self.degree + 1),
            interior_knots,
            [x_max] * (self.degree + 1)
        ])
        
        n_basis = len(knots) - self.degree - 1
        basis_matrix = np.zeros((len(x), n_basis))
        
        for i in range(n_basis):
            basis_matrix[:, i] = self._cox_deboor_recursion(x, i, self.degree, knots)
            
        # 处理最后一个点的包含性(右闭区间)
        basis_matrix[x == x_max, n_basis-1] = 1.0
            
        return basis_matrix, knots
    
    def fit(self, x, y):
        """拟合B-样条回归"""
        self.x_range_ = (x.min(), x.max())
        B, self.knots_ = self.fit_transform(x)
        
        # 最小二乘拟合(可使用稀疏矩阵优化)
        self.coef_ = np.linalg.lstsq(B, y, rcond=None)[0]
        return self
    
    def predict(self, x):
        B, _ = self.fit_transform(x)
        return B @ self.coef_


class RBFnetwork:
    """
    2.4.2.1 RBF网络实现
    中心点选择:K-Means与正交最小二乘(OLS)
    """
    
    def __init__(self, n_centers=10, method='kmeans', sigma=None):
        self.n_centers = n_centers
        self.method = method
        self.sigma = sigma  # 高斯RBF宽度
        self.centers_ = None
        self.weights_ = None
        
    def _rbf_kernel(self, x, centers):
        """高斯径向基函数"""
        dists = cdist(x, centers, 'euclidean')
        if self.sigma is None:
            # 启发式设置sigma
            self.sigma = np.median(dists) / np.sqrt(2)
        return np.exp(-dists**2 / (2 * self.sigma**2))
    
    def fit(self, x, y):
        """
        拟合RBF网络
        method='kmeans': 使用K-Means选择中心点
        method='ols': 正交最小二乘逐步选择中心点
        """
        if self.method == 'kmeans':
            # K-Means选择中心点
            kmeans = KMeans(n_clusters=self.n_centers, random_state=42, n_init=10)
            kmeans.fit(x.reshape(-1, 1) if x.ndim == 1 else x)
            self.centers_ = kmeans.cluster_centers_
            
        elif self.method == 'ols':
            # 正交最小二乘(简化版)
            # 从候选池中选择使残差减少最大的中心点
            candidates = x[np.random.choice(len(x), min(50, len(x)), replace=False)]
            if x.ndim == 1:
                candidates = candidates.reshape(-1, 1)
                
            selected = []
            residuals = y.copy()
            phi_full = self._rbf_kernel(x, candidates)
            
            for _ in range(self.n_centers):
                # 选择解释最多方差的中心点
                correlations = np.abs(phi_full.T @ residuals)
                best_idx = np.argmax(correlations)
                selected.append(candidates[best_idx])
                
                # 更新残差(Gram-Schmidt正交化思想)
                if len(selected) == 1:
                    phi_selected = phi_full[:, best_idx:best_idx+1]
                else:
                    phi_selected = self._rbf_kernel(x, np.array(selected))
                    
                # 投影到已选空间
                proj = phi_selected @ np.linalg.pinv(phi_selected) @ residuals
                residuals = y - proj
                
            self.centers_ = np.array(selected).reshape(-1, 1) if x.ndim == 1 else np.array(selected)
        
        # 拟合权重(Ridge正则化确保稳定)
        Phi = self._rbf_kernel(x, self.centers_)
        # 添加微小正则化
        self.weights_ = np.linalg.lstsq(Phi, y, rcond=1e-6)[0]
        self.phi_matrix_ = Phi
        
        return self
    
    def predict(self, x):
        Phi = self._rbf_kernel(x, self.centers_)
        return Phi @ self.weights_


class GaussianProcessRegression:
    """
    2.4.2.2 高斯过程回归(RBF核)
    展示函数空间视角(无需显式权重)
    """
    
    def __init__(self, length_scale=1.0, noise_var=0.1):
        self.length_scale = length_scale
        self.noise_var = noise_var
        
    def _rbf_kernel(self, x1, x2):
        """平方指数核(高斯核)"""
        sqdist = cdist(x1, x2, 'sqeuclidean')
        return np.exp(-0.5 * sqdist / self.length_scale**2)
    
    def fit(self, X, y):
        """
        GP回归的函数空间视角
        计算后验分布 p(f|X,y) ~ N(mu, Sigma)
        mu = K(X,X) (K(X,X) + sigma^2 I)^{-1} y
        """
        self.X_train_ = X
        self.y_train_ = y
        
        # 训练协方差矩阵
        K = self._rbf_kernel(X, X)
        K_noise = K + self.noise_var * np.eye(len(X))
        
        # 使用Cholesky分解求解(稳定)
        try:
            L = np.linalg.cholesky(K_noise)
            self.alpha_ = np.linalg.solve(L.T, np.linalg.solve(L, y))
        except:
            # 如果矩阵接近奇异,添加微小抖动
            L = np.linalg.cholesky(K_noise + 1e-6 * np.eye(len(X)))
            self.alpha_ = np.linalg.solve(L.T, np.linalg.solve(L, y))
            
        self.K_inv_solver_ = (L, L.T)  # 保存求解器用于预测
        
        return self
    
    def predict(self, X, return_std=True):
        """
        预测:后验高斯过程
        mu* = K(X*, X) alpha
        var* = K(X*, X*) - K(X*, X) (K(X,X) + sigma^2 I)^{-1} K(X, X*)
        """
        K_star = self._rbf_kernel(X, self.X_train_)
        mu = K_star @ self.alpha_
        
        if return_std:
            # 计算预测方差
            K_star_star = self._rbf_kernel(X, X)
            
            # 使用已分解的矩阵求解
            L, Lt = self.K_inv_solver_
            v = np.linalg.solve(L, K_star.T)
            var = np.diag(K_star_star) - np.sum(v**2, axis=0)
            std = np.sqrt(np.maximum(var, 0))
            return mu, std
        return mu


def demo_basis_functions():
    """
    演示正交多项式、B-样条、RBF与GP的对比
    """
    np.random.seed(42)
    
    # 生成复杂函数数据
    x = np.linspace(-3, 3, 100)
    y_true = np.sin(x) * np.exp(-x**2/10) + 0.5 * np.cos(2*x)
    y = y_true + 0.2 * np.random.randn(len(x))
    
    fig, axes = plt.subplots(2, 3, figsize=(18, 12))
    
    # 1. 多项式条件数对比
    degrees = range(5, 21)
    vand_cond = []
    leg_cond = []
    cheb_cond = []
    
    for d in degrees:
        ortho = OrthogonalPolynomialBasis(degree=d)
        conds = ortho.compare_condition_numbers(x)
        vand_cond.append(conds['vandermonde'])
        leg_cond.append(conds['legendre'])
        cheb_cond.append(conds['chebyshev'])
    
    axes[0, 0].semilogy(degrees, vand_cond, 'o-', label='Vandermonde', markersize=6)
    axes[0, 0].semilogy(degrees, leg_cond, 's-', label='Legendre', markersize=6)
    axes[0, 0].semilogy(degrees, cheb_cond, '^-', label='Chebyshev', markersize=6)
    axes[0, 0].set_xlabel('Polynomial Degree')
    axes[0, 0].set_ylabel('Condition Number (log scale)')
    axes[0, 0].set_title('Condition Number Comparison\n(Orthogonal vs Monomial Basis)')
    axes[0, 0].legend()
    axes[0, 0].grid(True, alpha=0.3)
    
    # 2. B-样条拟合
    bspline = BSplineBasis(degree=3, n_knots=8)
    bspline.fit(x, y)
    x_fine = np.linspace(-3, 3, 300)
    y_bspline = bspline.predict(x_fine)
    
    axes[0, 1].scatter(x, y, c='gray', alpha=0.5, s=30, label='Data')
    axes[0, 1].plot(x_fine, y_true, 'g-', linewidth=2, alpha=0.7, label='True Function')
    axes[0, 1].plot(x_fine, y_bspline, 'r--', linewidth=2, label='B-Spline (cubic)')
    axes[0, 1].scatter(bspline.knots_[4:-4], 
                      np.interp(bspline.knots_[4:-4], x_fine, y_bspline),
                      c='red', s=100, marker='x', label='Interior Knots', zorder=5)
    axes[0, 1].set_title('Cubic B-Spline Regression\n(de Boor-Cox Recursion)')
    axes[0, 1].legend()
    axes[0, 1].grid(True, alpha=0.3)
    
    # 3. B-样条基函数可视化
    x_vis = np.linspace(-3, 3, 300)
    B_vis, _ = bspline.fit_transform(x_vis)
    for i in range(min(6, B_vis.shape[1])):
        axes[0, 2].plot(x_vis, B_vis[:, i], alpha=0.7, label=f'$B_{{{i},3}}$')
    axes[0, 2].set_title('B-Spline Basis Functions\n(Local Support Property)')
    axes[0, 2].set_xlabel('x')
    axes[0, 2].legend(ncol=2, fontsize=8)
    axes[0, 2].grid(True, alpha=0.3)
    
    # 4. RBF网络对比(K-Means vs OLS中心选择)
    X = x.reshape(-1, 1)
    
    rbf_kmeans = RBFnetwork(n_centers=8, method='kmeans')
    rbf_kmeans.fit(X, y)
    
    rbf_ols = RBFnetwork(n_centers=8, method='ols')
    rbf_ols.fit(X, y)
    
    y_rbf_kmeans = rbf_kmeans.predict(X)
    y_rbf_ols = rbf_ols.predict(X)
    
    axes[1, 0].scatter(x, y, c='gray', alpha=0.5, s=30)
    axes[1, 0].plot(x, y_true, 'g-', linewidth=2, alpha=0.7, label='True Function')
    axes[1, 0].plot(x, y_rbf_kmeans, 'b-', linewidth=2, label='RBF (K-Means Centers)')
    axes[1, 0].scatter(rbf_kmeans.centers_, 
                      rbf_kmeans.predict(rbf_kmeans.centers_),
                      c='blue', s=100, marker='x', zorder=5)
    axes[1, 0].set_title('RBF Network: K-Means Center Selection')
    axes[1, 0].legend()
    axes[1, 0].grid(True, alpha=0.3)
    
    axes[1, 1].scatter(x, y, c='gray', alpha=0.5, s=30)
    axes[1, 1].plot(x, y_true, 'g-', linewidth=2, alpha=0.7, label='True Function')
    axes[1, 1].plot(x, y_rbf_ols, 'purple', linewidth=2, label='RBF (OLS Centers)')
    axes[1, 1].scatter(rbf_ols.centers_, 
                      rbf_ols.predict(rbf_ols.centers_),
                      c='purple', s=100, marker='x', zorder=5)
    axes[1, 1].set_title('RBF Network: OLS Center Selection')
    axes[1, 1].legend()
    axes[1, 1].grid(True, alpha=0.3)
    
    # 5. 高斯过程回归(不确定性量化)
    gp = GaussianProcessRegression(length_scale=0.5, noise_var=0.1)
    gp.fit(X, y)
    
    mu, std = gp.predict(x_fine.reshape(-1, 1), return_std=True)
    
    axes[1, 2].scatter(x, y, c='gray', alpha=0.5, s=30, label='Observations')
    axes[1, 2].plot(x_fine, y_true, 'g-', linewidth=2, alpha=0.7, label='True Function')
    axes[1, 2].plot(x_fine, mu, 'b-', linewidth=2, label='GP Mean')
    axes[1, 2].fill_between(x_fine, mu - 2*std, mu + 2*std, 
                           alpha=0.3, color='blue', label='95% Confidence')
    axes[1, 2].set_title('Gaussian Process Regression\n(Function Space Perspective)')
    axes[1, 2].legend()
    axes[1, 2].grid(True, alpha=0.3)
    
    plt.tight_layout()
    plt.savefig('basis_functions_comparison.png', dpi=150, bbox_inches='tight')
    plt.show()
    
    # 打印数值分析结果
    print("=== 正交多项式条件数分析 ===")
    print(f"10阶范德蒙德条件数: {vand_cond[5]:.2e}")
    print(f"10阶Legendre条件数: {leg_cond[5]:.2e}")
    print(f"10阶Chebyshev条件数: {cheb_cond[5]:.2e}")
    print(f"\n条件数改善比: {vand_cond[5]/leg_cond[5]:.2f}x")


if __name__ == "__main__":
    demo_basis_functions()

以上脚本提供了第2章监督学习核心内容的完整实现,涵盖从基础线性回归到高级非线性方法的数值技术细节。每个实现均包含计算复杂度优化、数值稳定性处理及可视化验证,可直接用于教学演示与算法原型开发。

【100天精通Python】Day73:python机器学习入门算法详解与代码示例 python机器学习入门算法,监督学习算法和无监督学习算法以及集成学习算法,包括线性回归,逻辑回归,决策树,支持向量机,随机森林,聚类算法,主成分分析,k均值聚类,梯度提升树,AdaBoost 算法详解与代码示例 阅读详情

相关推荐

从入门到精通:学习机器学习基础

作者:禅与计算机程序设计艺术 1.简介 Machine Learning(ML)是一门目前热门的计算机科学领域,它可以使计算机具备自我学习能力,从而自动化地解决复杂的问题和实现智能化。本文将从基本概念、术语的定义、核心算法及其原理、具体操作步骤、代码实例和解释等方面详细阐述机器学习的基础知识。希望通过阅

AI天才研究院 1065

人工智能从入门到精通:机器学习基础算法实战与应用

理解机器学习的核心概念与分类,掌握线性回归、逻辑回归、决策树三大基础算法的原理与代码实现,完成真实数据集上的预测任务,对比不同算法的性能表现。

今天比昨天更努力一点! 1万+

AI:272-【机器学习算法】从线性到多维:多元线性回归算法的深度解析与应用实践

多元线性回归(Multiple Linear Regression)是机器学习中最基本且广泛应用的算法之一。尽管它简单易懂,但在实际应用中仍然能解决许多复杂的问题。本篇文章将从零开始,逐步深入地讲解多元线性回归算法的原理,并通过Python代码实例帮助你理解和实现这一算法。

一键难忘的博客 3933

【机器学习】数据驱动的未来:机器学习的原理与算法探索

机器通过分析大量数据来进行学习。比如说,不需要通过编程来识别猫或人脸,它们可以通过使用图片来进行训练,从而归纳和识别特定的目标。 二、机器学习和人工智能的关系 机器学习是一种重在寻找数据中的模式并使用这些模式来做出预测的研究和算法的门类。机器学习是人工智能领域的一部分,并且和知识发现与数据挖掘有所交集。 三、机器学习的工作方式 ①选择数据:将你的数据分成三组:训练数据、验证数据和测试数据 ②模型数据:使用训练数据来构建使用相关特征的模型

鱼干的博客 5702

Rust嵌入式开发环境搭建指南(基于Stm32+Vscode)

本文档旨在指导开发者如何搭建基于Rust语言的STM32嵌入式开发环境。相比传统的C/C++开发方式,Rust提供了更强的内存安全保障和现代化的语言特性,非常适合嵌入式系统开发。本指南将详细介绍从环境搭建到项目配置的全过程,特别关注VSCode作为IDE的配置以及STLink和DAPLink调试器的使用。

u014627020的博客 2601

局域网ip冲突检测工具_python 小工具实现 windows笔记本与 ipad数据互传

宅在家没事的时候就开始琢磨ipad的进阶使用,由于没有mac无法隔空投送,ipad与windows的数据交互表现极差,所以设计了这个ftp小工具。当然,这个工具不仅仅能用于windows与ipad,还可以用于局域网任意两台设备之间程序源码与下载见文章末尾使用说明windows端:biubiubiu.exeipad端: appsotre下载 FE文件管理器windows端操作在c盘下创建ftp目录...

weixin_39866265的博客 4437

从零精通机器学习:线性回归入门

线性回归是机器学习中最基础、最经典的算法之一,也是许多复杂模型的起点。它简单易懂,却能解决许多实际问题,比如预测房价、分析销售趋势或研究变量之间的关系。本文将带你从零开始,全面剖析线性回归的原理、数学基础、损失函数、优化方法以及实际应用场景。无论你是初学者还是希望深入理解的高阶读者,这篇文章都将以通俗的语言、清晰的结构和丰富的示例,帮你彻底掌握线性回归。线性回归是一种统计方法,旨在通过自变量(输入特征)和因变量(输出目标)之间的线性关系进行建模。

吴师兄大模型的博客 2079

安检机图像处理避坑指南:从条纹校正到物质分类,那些论文里没写的工程细节

本文深入探讨了双能X射线安检机图像处理中的关键工程实践,从条纹校正到物质分类,揭示了论文中未提及的实用技巧。针对探测器校正、物质分类模糊、伪彩色系统设计等核心问题,提供了动态参数更新、空间上下文分析和自适应色彩映射等解决方案,助力提升安检系统的准确性和鲁棒性。

weixin_30325487的博客 889

Python开发从入门到精通:机器学习入门与应用

本文介绍了Python机器学习的基础知识和实践方法。主要内容包括:机器学习概述(监督/无监督学习、应用场景)、数据预处理(清洗缺失值、标签编码、特征缩放)、模型训练与评估(线性回归、逻辑回归、决策树)以及特征工程(特征选择与提取)。通过多个代码示例展示了如何使用Scikit-learn库进行数据处理、模型训练和评估,帮助读者掌握机器学习的基本流程和核心技能,为实际应用开发打下基础。

编程世界如山海,探索不止。 1万+

ADT MCP Server 把 ABAP 开发带进 Agent 模式

今天讨论 ADT MCP Server,不能只把它看成 Visual Studio Code 里多出来的一个开关。它真正有意思的地方,在于它把 ABAP 后端开发里那些原本需要手工点击、手工创建、手工激活、手工查服务元数据的动作,包装成一组可以被 GitHub Copilot 这类 coding agent 调用的工具。SAP 在 RAP130 练习里把它描述为运行在 ADT for Visual Studio Code 扩展内部的本地 HTTP Server,它实现的是 Model Context Pro

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 185

ML307R OpenCPU TCP使用

实现现象 平台下发数据,板子在收到数据之后,马上再发送到平台,通过串口助手可以看到已经接收到数据。ML307R TCP 是使用LWIP的标准的socket通信,具体TCP流程可以自行百度。实验目的:实现把接收的数据再发送到服务端。因为是4G,所以必须用外网的。

面朝大海春暖花开 2234

【机器学习基础算法:从零实现到精通】第1章 数学与计算基础

采用综述式描述,系统阐述特征值分解的数值稳定性问题,特别是幂迭代中的正交化修正与QR算法中的位移策略。张量运算部分构建了完整的自动微分引擎,实现了基于计算图的反向传播,并通过梯度检查确保数值正确性。从凸性判定出发,实现了完整的一阶方法体系(Batch/Mini-batch/SGD的方差分析、动量法的等价形式证明、Adam的偏差修正)。共轭先验部分实现了Beta-Binomial与Dirichlet-Multinomial的解析后验更新,展示了贝叶斯推断中的参数收缩效应。

VectorShift的博客 496

SAP-ABAP:接口多继承与复合接口设计:复杂业务场景下的能力组合实现方案

本文介绍了ABAP中通过接口多继承与复合接口设计实现能力组合的方案。文章首先辨析了类实现多个接口与接口继承接口的核心概念,指出ABAP虽不支持类多继承,但可通过这两种机制灵活组合能力。随后详细讲解了类实现多个接口的语法规则与三种调用方式,并给出了五个基础能力接口的设计示例(日志记录、权限校验、数据导出、消息通知、格式转换)。作者通过对比单继承与接口多重实现的差异,强调后者在解耦和扩展性上的优势,为复杂业务场景下的能力组合提供了实用解决方案。

baidu_35680696的博客 248

【机器学习基础算法:从零实现到精通】第3章 监督学习:树模型与集成方法

决策树通过递归二分构建层次化预测规则。代价复杂度剪枝(Cost-Complexity Pruning)通过引入复杂度参数α 平衡树的拟合优度与模型复杂度,剪枝序列从最复杂的完全生长树开始,递归地剪除使单位叶节点减少带来的误差增加最小的子树,形成嵌套的子树序列,通过交叉验证或独立验证集选择最优α。缺失值处理采用代理分裂机制,当主分裂特征缺失时,预先计算的替代分裂特征按照与主分裂的相似度排序,选择与主分裂保持最大一致性的代理特征进行样本划分,若代理特征亦缺失则继续尝试次级代理或采用多数方向分配。

VectorShift的博客 414

Xilinx FPGA ICAP原语实现多重配置

众所周知,常见的FPGA通常为SRAM结构,固件程序一般存放在外置的串行Flash中,比如SPI Flash,M25P16或N25Q128等。 FPGA启动时,一般先从SPI起始地址开始加载数据到内部的SRAM,加载完成、校验通过则会直接运行。 那么有没有可能在SPI Flash中存放两个或多个FPGA固件呢?

whik1194的博客 4614

python全栈入门到实战【基础篇 01】Python初识:定位、优势与发展历程

本文介绍了热门编程语言Python。它是解释型高级语言,具通用、入门友好、胶水型特点,以简洁易读为设计哲学。优势包括语法简洁高效、生态庞大、跨平台、社区活跃、应用广泛、门槛低。发展历经诞生(1989-1994,吉多创建,1994年1.0发布)、成长(版本迭代,3.0发布)、崛起(Web与大数据推动)、爆发(AI浪潮助推)及持续迭代阶段。

那些看似不起波澜的日复一日,会在某天让你看到坚持的意义 1万+

Python机器学习入门必学必会:机器学习与Python基础

根据输入数据是否具有“响应变量”信息,机器学习被分为“监督式学习”和“非监督式学习”。“监督式学习”即输入数据中即有X变量,也有y变量,特色在于使用“特征(X变量)”来预测“响应变量(y变量)”。“非监督式学习”即算法在训练模型时期不对结果进行标记,而是直接在数据点之间找有意义的关系,或者说输入数据中仅有X变量而没有y变量,特色在于针对X变量进行降维或者聚类,以挖掘特征变量的自身特征。

m0_72274883的博客 2059

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Interview之AI:人工智能领域岗位求职面试—人工智能算法工程师知识框架及课程大纲(AI基础之数学基础/数据结构与算法/编程学习基础、ML算法简介、DL算法简介)来理解技术交互流程

​ Interview之AI:人工智能领域岗位求职面试—人工智能算法工程师知识框架及课程大纲(AI基础之数学基础/数据结构与算法/编程学习基础、ML算法简介、DL算法简介)来理解技术交互流程 目录 剖析自己 一、AI基础 二、ML算法简介 三、DL算法简介 剖析自己 1、个人能力角度 确定自己应具备的能力:以结果为导向的思维,看职位要求让做什么,自己会会什么,还差哪些? 职位条件 目前能力 还差的能力 ML算法工程师 熟悉python/R、S

头部AI社区如有邀博主AI主题演讲请私信—心比天高,仗剑走天涯,保持热爱,奔赴向梦想!低调,专注,谦虚,自律,反思,成长,还算比较正能量的博主,公益免费传播…内心特别想在AI界做出一些可以推进历史进程影响力的技术(兴趣使然,有点小情怀,也有点使命感呀 1万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

《Python机器学习原理与算法实现》学习笔记

从我周边朋友的经历来看,真正学进去的,基本上都是有数据分析需要的朋友们,因为工作中真的需要。Python中使用数字n乘以一个序列(非numpy模块中的数组、非pandas模块中的序列,只是普通的序列)会生成新的序列,内容为原来序列被重复n 次的结果 序列的切片就是将序列切成小的子序列,通过切片操作可以访问一定范围内的元素或者生成一个新的子序列。噪声度量的是针对既定学习任务,使用任何学习算法所能达到的期望泛化误差的最小值,属于不可约减误差,反映的是学习问题本身的难度,或者说是无法用机器学习算法解决的问题。

m0_72274883的博客 1225

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

30天精通线性代数与微积分:ML-foundations终极学习指南

想要在机器学习领域脱颖而出?掌握**线性代数**和**微积分**是成功的关键!🚀 ML-foundations项目为初学者提供了完整的学习路径,让你在短短30天内快速掌握机器学习所需的数学基础。 ## 为什么机器学习需要数学基础? 机器学习就像一座房子,需要坚实的地基支撑。ML-foundations项目通过"机器学习之屋"的生动比喻,清晰展示了数学在AI领域的重要性。 [![机器学习之屋

gitblog_00259的博客 885

【R机器学习入门到精通】:掌握10个经典算法案例实现与调优技巧

掌握R语言机器学习核心方法,通过10个经典算法示例解析分类、回归与聚类实战技巧。涵盖数据预处理、模型调优与交叉验证,助你高效构建预测模型,值得收藏的入门到精通指南。

Algorift的博客 797

机器学习入门教学:从零基础到精通,一文搞定!

(一)定义 机器学习是一种让计算机通过数据自动学习并做出预测或决策的技术。它不需要明确的编程指令,而是通过算法从大量数据中发现模式和规律,从而实现自我优化和改进。简单来说,机器学习就是让计算机“学会”如何解决问题,而不是告诉它“怎么做”。 (二)与人工智能的关系 人工智能是一个广泛的概念,它涵盖了让计算机模拟人类智能的各种技术,包括机器学习、深度学习、自然语言处理、计算机视觉等。机器学习是人工智能的基础和核心,为AI提供了学习和适应的能力。可以说,没有机器学习,人工智能就无法实现其强大的

saluteSIWU的博客 2260

精通机器学习算法(一)

在过去几年里,机器学习已经成为大多数行业中越来越重要的领域。许多曾经被认为无法自动化的任务现在完全由计算机管理,这使得人类能够专注于更具创造性的工作。这一革命得益于标准算法的显著改进以及硬件价格的持续下降。仅十年前还是巨大障碍的复杂性,现在甚至个人电脑也能解决。高级开源框架的普遍可用性使得每个人都能设计和训练极其强大的模型。这本书的主要目标是向读者介绍复杂的技术(如半监督学习和流形学习、概率模型和神经网络),在数学理论与用 Python 编写的实际例子之间保持平衡。我想要保持实用主义的方法,专注于应用但也不

龙哥盟 1330

【机器学习入门】54.[第5章 监督学习算法] 线性回归全解析:从闭式解到岭回归与Lasso

文章摘要(150字): 本文系统解析线性回归核心技术与实战要点:1)基础理论强调数据线性检验与标准化预处理;2)闭式解高效但需规避大数据内存问题,推荐梯度下降替代;3)岭回归通过L2正则化抑制过拟合,交叉验证调优α参数;4)Lasso回归利用L1正则实现特征选择,解决冗余问题;5)实战对比演示Python代码差异,指导Ridge与Lasso场景选择。全文直击新手痛点(过拟合、特征冗余、计算效率),提供可复现解决方案,助力夯实监督学习基础。 关键词:线性回归、岭回归、Lasso、正则化、特征选择

927

ml-mastery-zh项目概览:一站式掌握机器学习算法与应用

想要系统学习机器学习却不知从何开始?ml-mastery-zh项目为您提供了完整的机器学习学习路径!这个开源项目翻译整理了Machine Learning Mastery博客的精华内容,涵盖了从基础概念到高级算法的全方位知识体系。无论您是机器学习初学者还是希望系统提升的开发者,这个项目都能为您提供宝贵的资源。 ## 📚 项目核心功能与价值 ml-mastery-zh项目是一个全面的机器学习中

gitblog_00924的博客 355

Gamdl 教程:3 步把 Apple Music 歌曲与音乐视频下载到本地

你肯定遇到过这种情况:Apple Music 里看到一首想长期收藏的歌、一支想反复看的高清 MV,但订阅一旦中断,这些内容就全没了。官方离线模式又无法让你把它们放进自己的音乐库统一管理。 Gamdl(Glomatico's Apple Music Downloader)是一个开源命令行工具,专门用来下载 Apple Music 的歌曲、音乐视频和发布视频。在浏览器里把歌曲链接复制出来,在终端执行

gitblog_00012的博客 470
上一篇: 【机器学习基础算法:从零实现到精通】第1章 数学与计算基础
下一篇: 【机器学习基础算法:从零实现到精通】第3章 监督学习:树模型与集成方法
VectorShift
博客等级 码龄1年 1839粉丝 1109原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VectorShift

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值