机器学习自学笔记(3)NumPy在机器学习中的应用详解

1. 特征标准化和归一化

1.1 基本概念

**特征标准化(Standardization)归一化(Normalization)**是机器学习预处理中的重要步骤,用于将不同量纲的特征转换到相同的尺度上。

1.2 标准化(Z-score标准化)

原理:将数据转换为均值为0,标准差为1的分布。

公式z = (x - μ) / σ

import numpy as np
import matplotlib.pyplot as plt

# 创建示例数据
np.random.seed(42)
data = np.random.normal(50, 15, 1000)  # 均值50,标准差15

# 标准化函数
def standardize(X):
    """
    标准化函数:将数据转换为均值0,标准差1
    """
    mean = np.mean(X, axis=0)
    std = np.std(X, axis=0)
    return (X - mean) / std, mean, std

# 应用标准化
standardized_data, mean, std = standardize(data)

print(f"原始数据 - 均值: {np.mean(data):.2f}, 标准差: {np.std(data):.2f}")
print(f"标准化后 - 均值: {np.mean(standardized_data):.2f}, 标准差: {np.std(standardized_data):.2f}")

1.3 归一化(Min-Max归一化)

原理:将数据缩放到[0,1]区间内。

公式x_norm = (x - min(x)) / (max(x) - min(x))

def normalize_minmax(X):
    """
    Min-Max归一化:将数据缩放到[0,1]区间
    """
    min_val = np.min(X, axis=0)
    max_val = np.max(X, axis=0)
    return (X - min_val) / (max_val - min_val), min_val, max_val

# 应用归一化
normalized_data, min_val, max_val = normalize_minmax(data)

print(f"归一化后 - 最小值: {np.min(normalized_data):.2f}, 最大值: {np.max(normalized_data):.2f}")

1.4 多维特征标准化

# 多维特征矩阵示例
X = np.array([[1, 2000, 3],
              [2, 3000, 4],
              [3, 4000, 5],
              [4, 5000, 6]])

# 按列标准化(每个特征独立标准化)
def standardize_features(X):
    """
    对多维特征矩阵进行标准化
    """
    means = np.mean(X, axis=0)
    stds = np.std(X, axis=0)
    return (X - means) / stds, means, stds

X_standardized, means, stds = standardize_features(X)

print("原始特征矩阵:")
print(X)
print("\n标准化后的特征矩阵:")
print(X_standardized)
print(f"\n各特征的均值: {means}")
print(f"各特征的标准差: {stds}")

1.5 应用场景

  • 梯度下降算法:避免某些特征主导优化过程
  • KNN算法:确保距离计算不被量纲影响
  • 神经网络:加速收敛,避免梯度爆炸/消失
  • SVM:提高分类效果

2. 损失函数计算

2.1 均方误差(MSE)

原理:衡量预测值与真实值之间的平均平方差。

公式MSE = (1/n) * Σ(y_true - y_pred)²

def mean_squared_error(y_true, y_pred):
    """
    计算均方误差
    """
    return np.mean((y_true - y_pred) ** 2)

# 示例
y_true = np.array([3, -0.5, 2, 7])
y_pred = np.array([2.5, 0.0, 2, 8])

mse = mean_squared_error(y_true, y_pred)
print(f"均方误差 (MSE): {mse:.4f}")

2.2 交叉熵损失(Cross-Entropy Loss)

原理:用于分类问题,衡量预测概率分布与真实标签的差距。

公式CE = -Σ(y_true * log(y_pred))

def cross_entropy_loss(y_true, y_pred):
    """
    计算交叉熵损失
    y_true: 真实标签(one-hot编码)
    y_pred: 预测概率
    """
    # 添加小值避免log(0)
    epsilon = 1e-15
    y_pred = np.clip(y_pred, epsilon, 1 - epsilon)
    return -np.mean(np.sum(y_true * np.log(y_pred), axis=1))

# 示例:3类分类问题
y_true = np.array([[1, 0, 0],  # 类别0
                   [0, 1, 0],  # 类别1
                   [0, 0, 1]])  # 类别2

y_pred = np.array([[0.9, 0.05, 0.05],
                   [0.1, 0.8, 0.1],
                   [0.2, 0.2, 0.6]])

ce_loss = cross_entropy_loss(y_true, y_pred)
print(f"交叉熵损失: {ce_loss:.4f}")

2.3 Huber损失

原理:结合了MSE和MAE的优点,对异常值更加鲁棒。

def huber_loss(y_true, y_pred, delta=1.0):
    """
    计算Huber损失
    delta: 阈值参数
    """
    error = y_true - y_pred
    is_small_error = np.abs(error) <= delta
    
    small_error_loss = 0.5 * error**2
    large_error_loss = delta * np.abs(error) - 0.5 * delta**2
    
    return np.mean(np.where(is_small_error, small_error_loss, large_error_loss))

# 示例
y_true = np.array([3, -0.5, 2, 7, 100])  # 包含异常值
y_pred = np.array([2.5, 0.0, 2, 8, 95])

huber = huber_loss(y_true, y_pred)
mse = mean_squared_error(y_true, y_pred)

print(f"Huber损失: {huber:.4f}")
print(f"MSE损失: {mse:.4f}")

3. 梯度计算

3.1 数值梯度

原理:使用有限差分法近似计算梯度。

公式∇f(x) ≈ (f(x + h) - f(x - h)) / (2h)

def numerical_gradient(f, x, h=1e-5):
    """
    计算函数f在点x处的数值梯度
    """
    grad = np.zeros_like(x)
    
    for i in range(len(x)):
        # 计算f(x + h)
        x_plus_h = x.copy()
        x_plus_h[i] += h
        
        # 计算f(x - h)
        x_minus_h = x.copy()
        x_minus_h[i] -= h
        
        # 计算梯度
        grad[i] = (f(x_plus_h) - f(x_minus_h)) / (2 * h)
    
    return grad

# 示例:计算二次函数的梯度
def quadratic_function(x):
    return x[0]**2 + 2*x[1]**2 + x[0]*x[1]

x = np.array([2.0, 3.0])
grad = numerical_gradient(quadratic_function, x)
print(f"在点{x}处的数值梯度: {grad}")

3.2 解析梯度 - 线性回归

原理:直接推导损失函数的梯度表达式。

def linear_regression_gradient(X, y, theta):
    """
    线性回归的梯度计算
    X: 特征矩阵 (m, n)
    y: 标签向量 (m,)
    theta: 参数向量 (n,)
    """
    m = X.shape[0]
    
    # 预测值
    y_pred = X.dot(theta)
    
    # 计算梯度
    gradient = (2 / m) * X.T.dot(y_pred - y)
    
    return gradient

# 示例数据
np.random.seed(42)
m, n = 100, 3
X = np.random.randn(m, n)
true_theta = np.array([1.5, -2.0, 0.5])
y = X.dot(true_theta) + 0.1 * np.random.randn(m)

# 初始参数
theta = np.random.randn(n)

# 计算梯度
grad = linear_regression_gradient(X, y, theta)
print(f"线性回归梯度: {grad}")

3.3 梯度下降实现

def gradient_descent(X, y, theta_init, learning_rate=0.01, max_iterations=1000):
    """
    梯度下降算法实现
    """
    theta = theta_init.copy()
    costs = []
    
    for i in range(max_iterations):
        # 计算预测值
        y_pred = X.dot(theta)
        
        # 计算损失
        cost = np.mean((y - y_pred) ** 2)
        costs.append(cost)
        
        # 计算梯度
        gradient = linear_regression_gradient(X, y, theta)
        
        # 更新参数
        theta -= learning_rate * gradient
        
        # 每100次迭代打印一次
        if i % 100 == 0:
            print(f"迭代 {i}: 损失 = {cost:.6f}")
    
    return theta, costs

# 运行梯度下降
theta_final, costs = gradient_descent(X, y, theta)

print(f"\n真实参数: {true_theta}")
print(f"学习参数: {theta_final}")
print(f"参数误差: {np.abs(true_theta - theta_final)}")

3.4 随机梯度下降(SGD)

def stochastic_gradient_descent(X, y, theta_init, learning_rate=0.01, max_iterations=1000):
    """
    随机梯度下降实现
    """
    theta = theta_init.copy()
    m = X.shape[0]
    costs = []
    
    for i in range(max_iterations):
        # 随机选择一个样本
        random_index = np.random.randint(0, m)
        xi = X[random_index:random_index+1]
        yi = y[random_index:random_index+1]
        
        # 计算梯度(单个样本)
        gradient = linear_regression_gradient(xi, yi, theta)
        
        # 更新参数
        theta -= learning_rate * gradient
        
        # 每100次迭代计算总损失
        if i % 100 == 0:
            y_pred = X.dot(theta)
            cost = np.mean((y - y_pred) ** 2)
            costs.append(cost)
            print(f"迭代 {i}: 损失 = {cost:.6f}")
    
    return theta, costs

# 运行SGD
theta_sgd, costs_sgd = stochastic_gradient_descent(X, y, np.random.randn(n))
print(f"\nSGD学习参数: {theta_sgd}")

4. 实际应用示例

4.1 完整的机器学习流程

def complete_ml_pipeline():
    """
    完整的机器学习流程示例
    """
    # 1. 生成数据
    np.random.seed(42)
    m, n = 1000, 5
    X_raw = np.random.randn(m, n) * [1, 10, 100, 1000, 0.1]  # 不同量纲
    true_theta = np.array([1, 2, -1, 0.5, 10])
    noise = 0.1 * np.random.randn(m)
    y = X_raw.dot(true_theta) + noise
    
    # 2. 特征标准化
    X_standardized, means, stds = standardize_features(X_raw)
    
    # 3. 添加偏置项
    X = np.column_stack([np.ones(m), X_standardized])
    theta_true_with_bias = np.concatenate([[0], true_theta])
    
    # 4. 应用梯度下降
    theta_init = np.random.randn(n + 1)
    theta_learned, costs = gradient_descent(X, y, theta_init, learning_rate=0.1, max_iterations=1000)
    
    # 5. 评估结果
    y_pred = X.dot(theta_learned)
    mse = mean_squared_error(y, y_pred)
    
    print("=== 完整机器学习流程结果 ===")
    print(f"最终MSE: {mse:.6f}")
    print(f"学习到的参数: {theta_learned}")
    
    return theta_learned, costs

# 运行完整流程
theta_result, cost_history = complete_ml_pipeline()

5. 总结

NumPy在机器学习中的核心作用包括:

  1. 数据预处理:标准化和归一化确保特征在相同尺度上
  2. 损失函数:提供高效的向量化计算
  3. 梯度计算:支持自动微分和数值微分
  4. 优化算法:实现各种梯度下降变体

这些基础操作构成了现代机器学习框架的核心,理解它们有助于深入掌握机器学习算法的本质。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值