1 课程概述

1.1 课程定位

01.基础地位
    a.AI学习的第一步
        本课程是进入人工智能领域的必修基础课,为后续所有课程提供数学和编程支撑。
    b.三大支柱
        a.数学基础
            线性代数、微积分、概率论构成AI算法的理论基础。
        b.编程能力
            Python及科学计算库是实现算法的工具基础。
        c.思维方式
            培养用数学语言描述问题、用代码实现算法的工程思维。

02.与后续课程的关系
    a.机器学习课程
        线性代数用于理解模型参数,微积分用于优化算法,概率论用于评估模型。
    b.深度学习课程
        矩阵运算是神经网络的计算核心,梯度下降是训练算法的基础。
    c.NLP与大模型课程
        向量表示是词嵌入的基础,张量运算是Transformer的计算基础。

1.2 学习目标

01.数学能力目标
    a.线性代数
        a.理解向量和矩阵的几何意义
            掌握向量空间、线性变换等核心概念,能用几何直觉理解算法。
        b.熟练矩阵运算
            掌握矩阵乘法、转置、求逆等运算,能手算简单矩阵运算。
        c.应用到神经网络
            理解神经网络中的权重矩阵、前向传播的矩阵运算本质。
    b.微积分
        a.掌握导数与梯度
            理解导数的几何意义,能计算多元函数的梯度。
        b.理解优化算法
            掌握梯度下降算法的数学原理,理解学习率的作用。
        c.应用到模型训练
            理解反向传播算法的数学基础,能推导简单网络的梯度。
    c.概率论
        a.掌握概率基础
            理解条件概率、贝叶斯定理、常见概率分布。
        b.理解统计推断
            掌握期望、方差、协方差等统计量的计算和意义。
        c.应用到模型评估
            理解损失函数、交叉熵等概念的概率论基础。

02.编程能力目标
    a.Python基础
        a.核心语法
            掌握数据类型、控制流、函数、类等Python核心语法。
        b.代码规范
            遵循PEP8规范,编写可读性强的代码。
    b.科学计算库
        a.NumPy
            熟练使用数组操作、矩阵运算、广播机制等核心功能。
        b.Pandas
            掌握数据读取、清洗、转换、分析等数据处理流程。
        c.Matplotlib
            能绘制折线图、散点图、热力图等常见可视化图表。
    c.实践能力
        a.实现基础算法
            能用NumPy实现线性回归、梯度下降等基础算法。
        b.数据处理
            能处理CSV、JSON等格式数据,完成数据清洗和特征工程。

03.岗位技能对应
    a.必备技能
        所有AI相关岗位的基础要求,面试必考内容。
    b.加分项
        能用数学语言解释算法原理,展现扎实的理论功底。

1.3 前置要求

01.数学基础
    a.高中数学水平
        a.代数基础
            掌握方程求解、函数概念、指数对数运算。
        b.几何基础
            理解坐标系、向量的基本概念。
        c.无需高等数学
            本课程会从零开始讲解微积分和线性代数,无需大学数学基础。
    b.学习态度
        愿意投入时间理解抽象概念,不畏惧数学公式。

02.编程基础
    a.零基础可学
        本课程包含Python从零开始的教学内容。
    b.有基础更好
        如果有任何编程语言基础,学习会更轻松。
    c.实践为主
        重点是能用代码实现算法,不要求深入的计算机科学知识。

03.学习环境
    a.硬件要求
        a.个人电脑
            Windows、Mac、Linux均可,无需GPU。
        b.内存建议
            8GB以上内存,用于运行Jupyter Notebook和数据处理。
    b.软件环境
        a.Python环境
            推荐安装Anaconda,包含Python和常用科学计算库。
        b.开发工具
            推荐使用Jupyter Notebook或VS Code进行学习和实践。

1.4 学习时长

01.总体时长规划
    a.全日制学习
        a.学习时长
            每天6-8小时,持续4-6周完成。
        b.适用人群
            全职学习者、应届毕业生、转行人员。
    b.业余学习
        a.学习时长
            每天2-3小时,持续3-4个月完成。
        b.适用人群
            在职学习者、利用业余时间提升技能。

02.各模块时长分配
    a.线性代数
        a.学习时长
            2-3周,每天2-3小时。
        b.重点内容
            矩阵运算、特征值分解、在神经网络中的应用。
    b.微积分
        a.学习时长
            2-3周,每天2-3小时。
        b.重点内容
            导数、梯度、梯度下降算法、反向传播。
    c.概率论
        a.学习时长
            1-2周,每天2-3小时。
        b.重点内容
            概率分布、贝叶斯定理、在损失函数中的应用。
    d.Python编程
        a.学习时长
            2-3周,每天2-3小时。
        b.重点内容
            NumPy、Pandas、实现基础算法。

03.学习节奏建议
    a.循序渐进
        先学数学理论,再学编程实现,理论与实践结合。
    b.及时复习
        每周复习前一周内容,巩固记忆。
    c.动手实践
        每学完一个知识点,立即用代码实现,加深理解。

1.5 岗位关联

01.岗位必备技能
    a.算法工程师
        a.数学要求
            必须掌握线性代数、微积分、概率论,能推导算法原理。
        b.编程要求
            熟练使用NumPy实现算法,能优化计算性能。
        c.面试重点
            手推梯度下降、反向传播,解释损失函数的数学原理。
    b.NLP工程师
        a.数学要求
            理解向量空间、矩阵运算,用于词嵌入和Transformer。
        b.编程要求
            熟练使用NumPy处理文本向量,能实现简单的词向量算法。
        c.面试重点
            解释词向量的数学原理,Attention机制的矩阵运算。
    c.机器学习工程师
        a.数学要求
            掌握概率论用于模型评估,微积分用于优化算法。
        b.编程要求
            熟练使用Pandas处理数据,NumPy实现特征工程。
        c.面试重点
            解释正则化的数学原理,交叉验证的统计学基础。

02.技能优先级
    a.P0级别
        a.NumPy基础
            数组操作、矩阵运算、广播机制,所有岗位必考。
        b.梯度下降
            理解原理、能手推公式、能用代码实现。
        c.矩阵运算
            理解神经网络中的权重矩阵、前向传播的计算过程。
    b.P1级别
        a.概率论基础
            理解损失函数、交叉熵的概率论基础。
        b.Pandas数据处理
            数据清洗、特征工程的基本操作。
    c.P2级别
        a.高级数学
            特征值分解、奇异值分解等高级线性代数知识。
        b.统计推断
            假设检验、置信区间等统计学知识。

03.薪资影响
    a.基础扎实
        数学和编程基础扎实,起薪可提升20-30%。
    b.面试加分
        能用数学语言解释算法,展现理论功底,面试通过率提升50%。
    c.职业发展
        基础扎实的工程师更容易晋升到算法专家、技术Leader。

2 线性代数

2.1 核心概念

01.标量、向量、矩阵、张量
    a.标量
        a.定义
            单个数值,如温度、年龄、价格等。
        b.在AI中的应用
            学习率、损失值、权重衰减系数等超参数。
        c.代码示例
            ---
            import numpy as np

            # 标量示例
            learning_rate = 0.01  # 学习率
            loss = 0.5  # 损失值
            temperature = 25.5  # 温度

            # 标量运算
            new_lr = learning_rate * 0.9  # 学习率衰减
            print(f"新学习率: {new_lr}")
            ---
    b.向量
        a.定义
            一维数组,表示方向和大小,如位置、速度、特征向量。
        b.几何意义
            空间中的一个点或一个方向,可以用箭头表示。
        c.在AI中的应用
            词向量、特征向量、梯度向量。
        d.代码示例
            ---
            # 向量示例
            word_vector = np.array([0.2, 0.5, -0.3, 0.8])  # 词向量
            feature_vector = np.array([1.5, 2.3, 0.8])  # 特征向量

            # 向量运算
            vector_norm = np.linalg.norm(word_vector)  # 向量的模
            print(f"向量的模: {vector_norm:.4f}")

            # 向量加法
            v1 = np.array([1, 2, 3])
            v2 = np.array([4, 5, 6])
            v_sum = v1 + v2
            print(f"向量和: {v_sum}")
            ---
    c.矩阵
        a.定义
            二维数组,表示线性变换,如旋转、缩放、投影。
        b.几何意义
            将一个向量空间映射到另一个向量空间的线性变换。
        c.在AI中的应用
            神经网络的权重矩阵、图像数据、注意力矩阵。
        d.代码示例
            ---
            # 矩阵示例
            weight_matrix = np.array([
                [0.1, 0.2, 0.3],
                [0.4, 0.5, 0.6],
                [0.7, 0.8, 0.9]
            ])  # 神经网络权重矩阵

            # 图像矩阵(灰度图)
            image = np.random.randint(0, 256, (28, 28))  # 28x28像素
            print(f"图像形状: {image.shape}")

            # 矩阵转置
            weight_T = weight_matrix.T
            print(f"转置矩阵:\n{weight_T}")
            ---
    d.张量
        a.定义
            多维数组,是标量、向量、矩阵的推广。
        b.维度说明
            0维张量是标量,1维张量是向量,2维张量是矩阵,3维及以上是高维张量。
        c.在AI中的应用
            彩色图像(高×宽×通道)、视频数据(时间×高×宽×通道)、批量数据(批次×特征)。
        d.代码示例
            ---
            # 张量示例
            # 3维张量:彩色图像(高×宽×RGB通道)
            color_image = np.random.randint(0, 256, (224, 224, 3))
            print(f"彩色图像形状: {color_image.shape}")

            # 4维张量:批量图像(批次×高×宽×通道)
            batch_images = np.random.rand(32, 224, 224, 3)
            print(f"批量图像形状: {batch_images.shape}")

            # 张量操作
            mean_value = batch_images.mean()
            print(f"张量均值: {mean_value:.4f}")
            ---

02.向量空间
    a.定义
        满足加法和数乘封闭性的集合,如所有二维向量构成的平面。
    b.基与维度
        a.基向量
            向量空间中的一组线性无关向量,可以表示空间中的任意向量。
        b.维度
            基向量的个数,如三维空间的维度是3。
    c.在AI中的应用
        词向量空间、特征空间、隐藏层表示空间。
    d.代码示例
        ---
        # 向量空间示例
        # 二维空间的基向量
        basis_1 = np.array([1, 0])
        basis_2 = np.array([0, 1])

        # 用基向量表示任意向量
        v = np.array([3, 4])
        # v = 3 * basis_1 + 4 * basis_2
        v_reconstructed = 3 * basis_1 + 4 * basis_2
        print(f"原向量: {v}")
        print(f"重构向量: {v_reconstructed}")

        # 检查线性无关性
        matrix = np.column_stack([basis_1, basis_2])
        rank = np.linalg.matrix_rank(matrix)
        print(f"矩阵秩: {rank}(等于2说明线性无关)")
        ---

2.2 向量与矩阵

01.向量运算
    a.向量加法与数乘
        a.几何意义
            向量加法是平行四边形法则,数乘是向量的伸缩。
        b.代数运算
            对应分量相加或相乘。
        c.代码示例
            ---
            # 向量加法
            v1 = np.array([1, 2, 3])
            v2 = np.array([4, 5, 6])
            v_add = v1 + v2
            print(f"向量加法: {v_add}")

            # 向量数乘
            scalar = 2.5
            v_scaled = scalar * v1
            print(f"向量数乘: {v_scaled}")

            # 向量减法
            v_sub = v1 - v2
            print(f"向量减法: {v_sub}")
            ---
    b.点积
        a.定义
            两个向量对应分量乘积的和,结果是标量。
        b.几何意义
            衡量两个向量的相似度,点积越大越相似。
        c.在AI中的应用
            计算余弦相似度、神经网络的加权求和。
        d.代码示例
            ---
            # 点积计算
            v1 = np.array([1, 2, 3])
            v2 = np.array([4, 5, 6])
            dot_product = np.dot(v1, v2)
            print(f"点积: {dot_product}")

            # 余弦相似度
            cos_sim = dot_product / (np.linalg.norm(v1) * np.linalg.norm(v2))
            print(f"余弦相似度: {cos_sim:.4f}")

            # 神经网络加权求和
            weights = np.array([0.5, 0.3, 0.2])
            inputs = np.array([1.0, 2.0, 3.0])
            weighted_sum = np.dot(weights, inputs)
            print(f"加权求和: {weighted_sum:.4f}")
            ---
    c.叉积
        a.定义
            三维向量的叉积,结果是垂直于两个向量的新向量。
        b.几何意义
            叉积的模等于两个向量构成的平行四边形面积。
        c.在AI中的应用
            计算机图形学、3D视觉中的法向量计算。
        d.代码示例
            ---
            # 叉积计算
            v1 = np.array([1, 0, 0])
            v2 = np.array([0, 1, 0])
            cross_product = np.cross(v1, v2)
            print(f"叉积: {cross_product}")

            # 验证垂直性
            dot_v1 = np.dot(cross_product, v1)
            dot_v2 = np.dot(cross_product, v2)
            print(f"与v1点积: {dot_v1}(应为0)")
            print(f"与v2点积: {dot_v2}(应为0)")
            ---

02.矩阵基本概念
    a.矩阵的形状
        a.行数与列数
            m×n矩阵有m行n列,如3×2矩阵有3行2列。
        b.方阵
            行数等于列数的矩阵,如3×3矩阵。
        c.代码示例
            ---
            # 创建不同形状的矩阵
            matrix_3x2 = np.array([
                [1, 2],
                [3, 4],
                [5, 6]
            ])
            print(f"3×2矩阵:\n{matrix_3x2}")
            print(f"形状: {matrix_3x2.shape}")

            # 方阵
            square_matrix = np.array([
                [1, 2, 3],
                [4, 5, 6],
                [7, 8, 9]
            ])
            print(f"方阵:\n{square_matrix}")
            ---
    b.特殊矩阵
        a.单位矩阵
            对角线为1,其余为0的方阵,记作I。
        b.零矩阵
            所有元素都是0的矩阵。
        c.对角矩阵
            只有对角线有非零元素的矩阵。
        d.代码示例
            ---
            # 单位矩阵
            identity = np.eye(3)
            print(f"单位矩阵:\n{identity}")

            # 零矩阵
            zeros = np.zeros((3, 3))
            print(f"零矩阵:\n{zeros}")

            # 对角矩阵
            diagonal = np.diag([1, 2, 3])
            print(f"对角矩阵:\n{diagonal}")

            # 验证单位矩阵性质:A * I = A
            A = np.array([[1, 2], [3, 4]])
            I = np.eye(2)
            result = np.dot(A, I)
            print(f"A * I =\n{result}")
            ---
    c.矩阵转置
        a.定义
            将矩阵的行列互换,记作A^T。
        b.性质
            (A^T)^T = A,(A + B)^T = A^T + B^T。
        c.在AI中的应用
            计算协方差矩阵、注意力机制中的转置操作。
        d.代码示例
            ---
            # 矩阵转置
            A = np.array([
                [1, 2, 3],
                [4, 5, 6]
            ])
            A_T = A.T
            print(f"原矩阵:\n{A}")
            print(f"转置矩阵:\n{A_T}")

            # 验证转置性质
            B = np.array([[7, 8, 9], [10, 11, 12]])
            sum_T = (A + B).T
            T_sum = A.T + B.T
            print(f"(A+B)^T =\n{sum_T}")
            print(f"A^T + B^T =\n{T_sum}")
            print(f"相等: {np.allclose(sum_T, T_sum)}")
            ---

2.3 矩阵运算

01.矩阵乘法
    a.定义与规则
        a.计算规则
            C[i,j] = Σ A[i,k] * B[k,j],要求A的列数等于B的行数。
        b.几何意义
            矩阵乘法表示线性变换的复合。
        c.代码示例
            ---
            # 矩阵乘法
            A = np.array([[1, 2], [3, 4]])
            B = np.array([[5, 6], [7, 8]])
            C = np.dot(A, B)
            print(f"A =\n{A}")
            print(f"B =\n{B}")
            print(f"A * B =\n{C}")

            # 验证形状规则
            A_3x2 = np.random.rand(3, 2)
            B_2x4 = np.random.rand(2, 4)
            C_3x4 = np.dot(A_3x2, B_2x4)
            print(f"(3×2) * (2×4) = {C_3x4.shape}")
            ---
    b.在神经网络中的应用
        a.前向传播
            输出 = 输入 × 权重矩阵 + 偏置。
        b.代码示例
            ---
            # 神经网络前向传播
            # 输入层:3个特征
            X = np.array([[1.0, 2.0, 3.0]])  # 1个样本

            # 权重矩阵:3×4(输入3维,输出4维)
            W = np.array([
                [0.1, 0.2, 0.3, 0.4],
                [0.5, 0.6, 0.7, 0.8],
                [0.9, 1.0, 1.1, 1.2]
            ])

            # 偏置向量
            b = np.array([0.1, 0.2, 0.3, 0.4])

            # 前向传播
            Z = np.dot(X, W) + b
            print(f"输入形状: {X.shape}")
            print(f"权重形状: {W.shape}")
            print(f"输出: {Z}")
            print(f"输出形状: {Z.shape}")
            ---
    c.批量计算
        a.批量矩阵乘法
            处理多个样本时,使用批量矩阵乘法提高效率。
        b.代码示例
            ---
            # 批量前向传播
            # 32个样本,每个3个特征
            X_batch = np.random.rand(32, 3)
            W = np.random.rand(3, 4)
            b = np.random.rand(4)

            # 批量计算
            Z_batch = np.dot(X_batch, W) + b
            print(f"批量输入形状: {X_batch.shape}")
            print(f"批量输出形状: {Z_batch.shape}")

            # 性能对比
            import time
            start = time.time()
            for i in range(1000):
                Z = np.dot(X_batch, W) + b
            batch_time = time.time() - start
            print(f"批量计算耗时: {batch_time:.4f}秒")
            ---

02.矩阵求逆
    a.定义
        方阵A的逆矩阵A^(-1)满足:A * A^(-1) = I。
    b.存在条件
        只有满秩方阵才有逆矩阵。
    c.在AI中的应用
        最小二乘法、协方差矩阵求逆。
    d.代码示例
        ---
        # 矩阵求逆
        A = np.array([[1, 2], [3, 4]])
        A_inv = np.linalg.inv(A)
        print(f"A =\n{A}")
        print(f"A^(-1) =\n{A_inv}")

        # 验证:A * A^(-1) = I
        I = np.dot(A, A_inv)
        print(f"A * A^(-1) =\n{I}")

        # 奇异矩阵(不可逆)
        singular = np.array([[1, 2], [2, 4]])
        try:
            singular_inv = np.linalg.inv(singular)
        except np.linalg.LinAlgError:
            print("奇异矩阵不可逆")
        ---

03.矩阵的秩
    a.定义
        矩阵的秩是其线性无关的行(或列)的最大数目。
    b.满秩矩阵
        秩等于行数和列数的较小值。
    c.在AI中的应用
        判断特征是否线性相关、降维算法。
    d.代码示例
        ---
        # 计算矩阵的秩
        A = np.array([
            [1, 2, 3],
            [4, 5, 6],
            [7, 8, 9]
        ])
        rank_A = np.linalg.matrix_rank(A)
        print(f"矩阵A:\n{A}")
        print(f"秩: {rank_A}(小于3,说明行向量线性相关)")

        # 满秩矩阵
        B = np.array([
            [1, 0, 0],
            [0, 1, 0],
            [0, 0, 1]
        ])
        rank_B = np.linalg.matrix_rank(B)
        print(f"单位矩阵的秩: {rank_B}(满秩)")

        # 特征相关性检测
        features = np.array([
            [1, 2, 3],
            [2, 4, 6],  # 第二行是第一行的2倍
            [3, 6, 9]   # 第三行是第一行的3倍
        ])
        rank_features = np.linalg.matrix_rank(features)
        print(f"特征矩阵的秩: {rank_features}(只有1,说明特征高度相关)")
        ---

2.4 特征值与特征向量

01.定义与计算
    a.特征值与特征向量
        a.定义
            对于方阵A,如果存在非零向量v和标量λ,使得Av = λv,则λ是特征值,v是特征向量。
        b.几何意义
            特征向量是矩阵变换后方向不变的向量,特征值是伸缩比例。
        c.代码示例
            ---
            # 计算特征值和特征向量
            A = np.array([
                [4, 2],
                [1, 3]
            ])

            # 使用NumPy计算
            eigenvalues, eigenvectors = np.linalg.eig(A)
            print(f"矩阵A:\n{A}")
            print(f"特征值: {eigenvalues}")
            print(f"特征向量:\n{eigenvectors}")

            # 验证:Av = λv
            v1 = eigenvectors[:, 0]
            lambda1 = eigenvalues[0]
            Av1 = np.dot(A, v1)
            lambda_v1 = lambda1 * v1
            print(f"\nAv1 = {Av1}")
            print(f"λ1*v1 = {lambda_v1}")
            print(f"相等: {np.allclose(Av1, lambda_v1)}")
            ---

02.特征分解
    a.定义
        将矩阵分解为A = QΛQ^(-1),其中Q是特征向量矩阵,Λ是特征值对角矩阵。
    b.应用条件
        只有可对角化的方阵才能进行特征分解。
    c.代码示例
        ---
        # 特征分解
        A = np.array([
            [4, 2],
            [1, 3]
        ])

        eigenvalues, eigenvectors = np.linalg.eig(A)

        # 构造Λ和Q
        Lambda = np.diag(eigenvalues)
        Q = eigenvectors

        # 重构矩阵:A = Q * Λ * Q^(-1)
        Q_inv = np.linalg.inv(Q)
        A_reconstructed = Q @ Lambda @ Q_inv

        print(f"原矩阵A:\n{A}")
        print(f"重构矩阵:\n{A_reconstructed}")
        print(f"重构成功: {np.allclose(A, A_reconstructed)}")
        ---

03.在AI中的应用
    a.主成分分析
        a.PCA原理
            通过特征分解找到数据的主要方向,实现降维。
        b.代码示例
            ---
            # PCA降维示例
            from sklearn.decomposition import PCA

            # 生成高维数据
            np.random.seed(42)
            X = np.random.rand(100, 10)  # 100个样本,10个特征

            # 计算协方差矩阵
            X_centered = X - X.mean(axis=0)
            cov_matrix = np.cov(X_centered.T)

            # 特征分解
            eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)

            # 按特征值排序
            idx = eigenvalues.argsort()[::-1]
            eigenvalues = eigenvalues[idx]
            eigenvectors = eigenvectors[:, idx]

            # 选择前3个主成分
            k = 3
            principal_components = eigenvectors[:, :k]

            # 降维
            X_reduced = X_centered @ principal_components

            print(f"原始数据形状: {X.shape}")
            print(f"降维后形状: {X_reduced.shape}")
            print(f"前3个特征值: {eigenvalues[:3]}")
            print(f"方差解释比例: {eigenvalues[:3].sum() / eigenvalues.sum():.2%}")
            ---
    b.谱聚类
        通过图的拉普拉斯矩阵的特征分解进行聚类。
    c.推荐系统
        矩阵分解用于协同过滤算法。

2.5 在AI中的应用

01.神经网络中的矩阵运算
    a.前向传播
        a.计算过程
            每一层的输出是输入与权重矩阵相乘再加偏置。
        b.代码示例
            ---
            # 多层神经网络前向传播
            def relu(x):
                return np.maximum(0, x)

            # 输入数据:32个样本,每个784维(28×28图像展平)
            X = np.random.rand(32, 784)

            # 第一层:784 -> 128
            W1 = np.random.randn(784, 128) * 0.01
            b1 = np.zeros(128)
            Z1 = np.dot(X, W1) + b1
            A1 = relu(Z1)

            # 第二层:128 -> 64
            W2 = np.random.randn(128, 64) * 0.01
            b2 = np.zeros(64)
            Z2 = np.dot(A1, W2) + b2
            A2 = relu(Z2)

            # 输出层:64 -> 10
            W3 = np.random.randn(64, 10) * 0.01
            b3 = np.zeros(10)
            Z3 = np.dot(A2, W3) + b3

            print(f"输入形状: {X.shape}")
            print(f"第一层输出: {A1.shape}")
            print(f"第二层输出: {A2.shape}")
            print(f"最终输出: {Z3.shape}")
            ---
    b.反向传播
        a.梯度计算
            使用链式法则和矩阵转置计算梯度。
        b.代码示例
            ---
            # 简化的反向传播示例
            # 假设已有前向传播的结果
            X = np.random.rand(32, 10)
            W = np.random.rand(10, 5)
            b = np.zeros(5)
            Z = np.dot(X, W) + b
            A = relu(Z)

            # 假设的损失梯度
            dL_dA = np.random.rand(32, 5)

            # 反向传播计算梯度
            dL_dZ = dL_dA * (Z > 0)  # ReLU的梯度
            dL_dW = np.dot(X.T, dL_dZ) / 32  # 权重梯度
            dL_db = np.sum(dL_dZ, axis=0) / 32  # 偏置梯度
            dL_dX = np.dot(dL_dZ, W.T)  # 输入梯度

            print(f"权重梯度形状: {dL_dW.shape}")
            print(f"偏置梯度形状: {dL_db.shape}")
            print(f"输入梯度形状: {dL_dX.shape}")
            ---

02.词向量与矩阵
    a.词嵌入矩阵
        a.定义
            将词汇表中的每个词映射到一个向量,所有词向量组成嵌入矩阵。
        b.代码示例
            ---
            # 词嵌入矩阵
            vocab_size = 10000  # 词汇表大小
            embedding_dim = 300  # 词向量维度

            # 初始化嵌入矩阵
            embedding_matrix = np.random.randn(vocab_size, embedding_dim) * 0.01

            # 查询单词的向量
            word_id = 42
            word_vector = embedding_matrix[word_id]
            print(f"词向量形状: {word_vector.shape}")

            # 批量查询
            word_ids = np.array([1, 5, 10, 20])
            word_vectors = embedding_matrix[word_ids]
            print(f"批量词向量形状: {word_vectors.shape}")

            # 计算词语相似度
            word1_id = 10
            word2_id = 20
            v1 = embedding_matrix[word1_id]
            v2 = embedding_matrix[word2_id]
            similarity = np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))
            print(f"余弦相似度: {similarity:.4f}")
            ---
    b.注意力机制中的矩阵
        a.Query、Key、Value矩阵
            Transformer中的核心矩阵运算。
        b.代码示例
            ---
            # 简化的注意力机制
            seq_len = 10  # 序列长度
            d_model = 64  # 模型维度

            # 输入序列
            X = np.random.rand(seq_len, d_model)

            # Q、K、V权重矩阵
            W_q = np.random.randn(d_model, d_model) * 0.01
            W_k = np.random.randn(d_model, d_model) * 0.01
            W_v = np.random.randn(d_model, d_model) * 0.01

            # 计算Q、K、V
            Q = np.dot(X, W_q)
            K = np.dot(X, W_k)
            V = np.dot(X, W_v)

            # 计算注意力分数
            scores = np.dot(Q, K.T) / np.sqrt(d_model)
            attention_weights = np.exp(scores) / np.exp(scores).sum(axis=1, keepdims=True)

            # 加权求和
            output = np.dot(attention_weights, V)

            print(f"Q形状: {Q.shape}")
            print(f"K形状: {K.shape}")
            print(f"V形状: {V.shape}")
            print(f"注意力权重形状: {attention_weights.shape}")
            print(f"输出形状: {output.shape}")
            ---

03.图像处理中的矩阵
    a.卷积操作
        a.卷积核
            小矩阵在图像上滑动,提取特征。
        b.代码示例
            ---
            # 简单的卷积操作
            from scipy.signal import convolve2d

            # 输入图像(灰度)
            image = np.random.rand(28, 28)

            # 卷积核(边缘检测)
            kernel = np.array([
                [-1, -1, -1],
                [-1,  8, -1],
                [-1, -1, -1]
            ])

            # 卷积操作
            feature_map = convolve2d(image, kernel, mode='valid')

            print(f"原图像形状: {image.shape}")
            print(f"卷积核形状: {kernel.shape}")
            print(f"特征图形状: {feature_map.shape}")

            # 多通道卷积(��色图像)
            color_image = np.random.rand(224, 224, 3)
            print(f"彩色图像形状: {color_image.shape}")
            ---
    b.图像变换
        旋转、缩放、平移等操作都是矩阵变换。

3 微积分

3.1 导数与偏导数

01.导数的定义
    a.极限定义
        a.数学定义
            f'(x) = lim(h→0) [f(x+h) - f(x)] / h,表示函数在某点的变化率。
        b.几何意义
            函数曲线在某点的切线斜率。
        c.代码示例
            ---
            # 数值计算导数
            def numerical_derivative(f, x, h=1e-5):
                return (f(x + h) - f(x)) / h

            # 测试函数:f(x) = x^2
            def f(x):
                return x ** 2

            # 计算x=3处的导数
            x = 3
            derivative = numerical_derivative(f, x)
            analytical = 2 * x  # 解析解:f'(x) = 2x
            print(f"数值导数: {derivative:.6f}")
            print(f"解析导数: {analytical}")
            print(f"误差: {abs(derivative - analytical):.8f}")

            # 可视化
            import matplotlib.pyplot as plt
            x_vals = np.linspace(0, 5, 100)
            y_vals = f(x_vals)
            plt.plot(x_vals, y_vals, label='f(x) = x²')
            plt.plot(x, f(x), 'ro', label=f'点({x}, {f(x)})')
            # 切线
            tangent_y = f(x) + analytical * (x_vals - x)
            plt.plot(x_vals, tangent_y, 'r--', label=f'切线斜率={analytical}')
            plt.legend()
            plt.grid(True)
            plt.title('导数的几何意义')
            ---
    b.常见函数的导数
        a.基本导数公式
            (x^n)' = n*x^(n-1),(e^x)' = e^x,(ln x)' = 1/x。
        b.代码验证
            ---
            # 验证常见函数的导数
            def verify_derivative(f, f_prime, x_test):
                numerical = numerical_derivative(f, x_test)
                analytical = f_prime(x_test)
                error = abs(numerical - analytical)
                print(f"x={x_test}: 数值={numerical:.6f}, 解析={analytical:.6f}, 误差={error:.8f}")

            # 测试 f(x) = x^3
            verify_derivative(lambda x: x**3, lambda x: 3*x**2, 2.0)

            # 测试 f(x) = e^x
            verify_derivative(lambda x: np.exp(x), lambda x: np.exp(x), 1.0)

            # 测试 f(x) = ln(x)
            verify_derivative(lambda x: np.log(x), lambda x: 1/x, 2.0)

            # 测试 f(x) = sin(x)
            verify_derivative(lambda x: np.sin(x), lambda x: np.cos(x), np.pi/4)
            ---

02.偏导数
    a.多元函数的导数
        a.定义
            对多元函数f(x,y),偏导数∂f/∂x表示固定y时f对x的变化率。
        b.几何意义
            曲面在某个方向上的斜率。
        c.代码示例
            ---
            # 计算偏导数
            def partial_derivative_x(f, x, y, h=1e-5):
                return (f(x + h, y) - f(x, y)) / h

            def partial_derivative_y(f, x, y, h=1e-5):
                return (f(x, y + h) - f(x, y)) / h

            # 测试函数:f(x,y) = x^2 + y^2
            def f(x, y):
                return x**2 + y**2

            x, y = 3, 4
            df_dx = partial_derivative_x(f, x, y)
            df_dy = partial_derivative_y(f, x, y)

            print(f"∂f/∂x at ({x},{y}): {df_dx:.6f} (解析解: {2*x})")
            print(f"∂f/∂y at ({x},{y}): {df_dy:.6f} (解析解: {2*y})")

            # 可视化曲面
            x_range = np.linspace(-5, 5, 50)
            y_range = np.linspace(-5, 5, 50)
            X, Y = np.meshgrid(x_range, y_range)
            Z = X**2 + Y**2

            from mpl_toolkits.mplot3d import Axes3D
            fig = plt.figure(figsize=(10, 8))
            ax = fig.add_subplot(111, projection='3d')
            ax.plot_surface(X, Y, Z, alpha=0.7, cmap='viridis')
            ax.set_xlabel('X')
            ax.set_ylabel('Y')
            ax.set_zlabel('f(x,y)')
            ax.set_title('f(x,y) = x² + y²')
            ---
    b.在神经网络中的应用
        a.损失函数的偏导数
            计算损失对每个参数的偏导数,用于梯度下降。
        b.代码示例
            ---
            # 简单神经网络的偏导数
            # 损失函数:L = (y_pred - y_true)^2
            def loss(w, b, x, y_true):
                y_pred = w * x + b
                return (y_pred - y_true) ** 2

            # 计算偏导数
            w, b, x, y_true = 2.0, 1.0, 3.0, 10.0

            dL_dw = partial_derivative_x(lambda w, b: loss(w, b, x, y_true), w, b)
            dL_db = partial_derivative_y(lambda w, b: loss(w, b, x, y_true), w, b)

            # 解析解
            y_pred = w * x + b
            error = y_pred - y_true
            dL_dw_analytical = 2 * error * x
            dL_db_analytical = 2 * error

            print(f"∂L/∂w: 数值={dL_dw:.6f}, 解析={dL_dw_analytical:.6f}")
            print(f"∂L/∂b: 数值={dL_db:.6f}, 解析={dL_db_analytical:.6f}")
            ---

3.2 梯度

01.梯度的定义
    a.数学定义
        梯度是所有偏导数组成的向量,∇f = [∂f/∂x₁, ∂f/∂x₂, ..., ∂f/∂xₙ]。
    b.几何意义
        梯度指向函数增长最快的方向,梯度的模是最大变化率。
    c.代码示例
        ---
        # 计算梯度
        def gradient(f, x, h=1e-5):
            grad = np.zeros_like(x)
            for i in range(len(x)):
                x_plus = x.copy()
                x_plus[i] += h
                grad[i] = (f(x_plus) - f(x)) / h
            return grad

        # 测试函数:f(x,y) = x^2 + y^2
        def f(x):
            return x[0]**2 + x[1]**2

        point = np.array([3.0, 4.0])
        grad = gradient(f, point)
        print(f"梯度 at {point}: {grad}")
        print(f"解析梯度: [6.0, 8.0]")

        # 可视化梯度场
        x = np.linspace(-5, 5, 20)
        y = np.linspace(-5, 5, 20)
        X, Y = np.meshgrid(x, y)
        U = 2 * X  # ∂f/∂x
        V = 2 * Y  # ∂f/∂y

        plt.figure(figsize=(10, 8))
        plt.quiver(X, Y, U, V, alpha=0.6)
        plt.contour(X, Y, X**2 + Y**2, levels=20, alpha=0.4)
        plt.xlabel('x')
        plt.ylabel('y')
        plt.title('梯度场:f(x,y) = x² + y²')
        plt.grid(True)
        ---

02.梯度在优化中的应用
    a.梯度下降法
        a.基本思想
            沿着梯度的反方向更新参数,逐步找到最小值。
        b.更新公式
            θ = θ - α * ∇L(θ),其中α是学习率。
        c.代码示例
            ---
            # 梯度下降优化
            def gradient_descent(f, grad_f, x_init, learning_rate=0.1, iterations=100):
                x = x_init.copy()
                history = [x.copy()]

                for i in range(iterations):
                    grad = grad_f(x)
                    x = x - learning_rate * grad
                    history.append(x.copy())

                    if i % 10 == 0:
                        print(f"Iteration {i}: x={x}, f(x)={f(x):.6f}")

                return x, np.array(history)

            # 目标函数:f(x,y) = (x-2)^2 + (y-3)^2
            def f(x):
                return (x[0] - 2)**2 + (x[1] - 3)**2

            def grad_f(x):
                return np.array([2*(x[0] - 2), 2*(x[1] - 3)])

            # 从(0,0)开始优化
            x_init = np.array([0.0, 0.0])
            x_opt, history = gradient_descent(f, grad_f, x_init, learning_rate=0.1, iterations=50)

            print(f"\n最优解: {x_opt}")
            print(f"最优值: {f(x_opt):.6f}")
            print(f"理论最优解: [2, 3]")

            # 可视化优化过程
            plt.figure(figsize=(10, 8))
            x = np.linspace(-1, 5, 100)
            y = np.linspace(-1, 6, 100)
            X, Y = np.meshgrid(x, y)
            Z = (X - 2)**2 + (Y - 3)**2
            plt.contour(X, Y, Z, levels=30, alpha=0.6)
            plt.plot(history[:, 0], history[:, 1], 'ro-', linewidth=2, markersize=4)
            plt.plot(2, 3, 'g*', markersize=20, label='最优点')
            plt.xlabel('x')
            plt.ylabel('y')
            plt.title('梯度下降优化过程')
            plt.legend()
            plt.grid(True)
            ---

3.3 链式法则

01.链式法则的定义
    a.单变量链式法则
        如果y=f(u)且u=g(x),则dy/dx = (dy/du) * (du/dx)。
    b.多变量链式法则
        对于复合函数z=f(x,y),x=g(t),y=h(t),则dz/dt = (∂z/∂x)*(dx/dt) + (∂z/∂y)*(dy/dt)。
    c.代码示例
        ---
        # 链式法则示例
        # z = (x + y)^2, x = 2t, y = 3t
        def z(x, y):
            return (x + y) ** 2

        def x(t):
            return 2 * t

        def y(t):
            return 3 * t

        # 数值计算 dz/dt
        def dz_dt_numerical(t, h=1e-5):
            z1 = z(x(t + h), y(t + h))
            z0 = z(x(t), y(t))
            return (z1 - z0) / h

        # 解析计算 dz/dt = ∂z/∂x * dx/dt + ∂z/∂y * dy/dt
        def dz_dt_analytical(t):
            x_val = x(t)
            y_val = y(t)
            dz_dx = 2 * (x_val + y_val)  # ∂z/∂x
            dz_dy = 2 * (x_val + y_val)  # ∂z/∂y
            dx_dt = 2  # dx/dt
            dy_dt = 3  # dy/dt
            return dz_dx * dx_dt + dz_dy * dy_dt

        t = 1.0
        numerical = dz_dt_numerical(t)
        analytical = dz_dt_analytical(t)
        print(f"数值导数: {numerical:.6f}")
        print(f"解析导数: {analytical:.6f}")
        print(f"误差: {abs(numerical - analytical):.8f}")
        ---

02.在神经网络中的应用
    a.反向传播算法
        a.核心思想
            使用链式法则从输出层向输入层逐层计算梯度。
        b.代码示例
            ---
            # 简单神经网络的反向传播
            # 网络结构:输入 -> 隐藏层 -> 输出
            # f(x) = W2 * relu(W1 * x + b1) + b2

            def relu(x):
                return np.maximum(0, x)

            def relu_derivative(x):
                return (x > 0).astype(float)

            # 前向传播
            x = np.array([1.0, 2.0])
            W1 = np.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]])
            b1 = np.array([0.1, 0.2, 0.3])
            W2 = np.array([[0.7, 0.8, 0.9]])
            b2 = np.array([0.4])

            # 第一层
            z1 = np.dot(W1, x) + b1
            a1 = relu(z1)

            # 第二层
            z2 = np.dot(W2, a1) + b2
            y_pred = z2[0]

            print(f"前向传播结果: {y_pred:.4f}")

            # 反向传播
            y_true = 1.0
            loss = (y_pred - y_true) ** 2

            # 输出层梯度
            dL_dy = 2 * (y_pred - y_true)
            dL_dz2 = dL_dy
            dL_dW2 = dL_dz2 * a1
            dL_db2 = dL_dz2

            # 隐藏层梯度(链式法则)
            dL_da1 = dL_dz2 * W2[0]
            dL_dz1 = dL_da1 * relu_derivative(z1)
            dL_dW1 = np.outer(dL_dz1, x)
            dL_db1 = dL_dz1

            print(f"\n梯度:")
            print(f"dL/dW2 形状: {dL_dW2.shape}")
            print(f"dL/dW1 形状: {dL_dW1.shape}")
            print(f"dL/db2: {dL_db2}")
            print(f"dL/db1: {dL_db1}")
            ---

3.4 梯度下降算法

01.批量梯度下降
    a.算法原理
        使用全部训练数据计算梯度,更新参数。
    b.代码实现
        ---
        # 批量梯度下降实现线性回归
        def batch_gradient_descent(X, y, learning_rate=0.01, iterations=1000):
            m, n = X.shape
            theta = np.zeros(n)
            loss_history = []

            for i in range(iterations):
                # 预测
                y_pred = np.dot(X, theta)

                # 计算损失
                loss = np.mean((y_pred - y) ** 2)
                loss_history.append(loss)

                # 计算梯度
                gradient = (2/m) * np.dot(X.T, (y_pred - y))

                # 更新参数
                theta = theta - learning_rate * gradient

                if i % 100 == 0:
                    print(f"Iteration {i}: Loss = {loss:.6f}")

            return theta, loss_history

        # 生成数据
        np.random.seed(42)
        X = np.random.rand(100, 1)
        X_with_bias = np.c_[np.ones((100, 1)), X]
        true_theta = np.array([2.0, 3.0])
        y = np.dot(X_with_bias, true_theta) + np.random.randn(100) * 0.1

        # 训练
        theta, loss_history = batch_gradient_descent(X_with_bias, y, learning_rate=0.1, iterations=1000)

        print(f"\n学习到的参数: {theta}")
        print(f"真实参数: {true_theta}")

        # 可视化
        plt.figure(figsize=(12, 5))
        plt.subplot(1, 2, 1)
        plt.plot(loss_history)
        plt.xlabel('Iteration')
        plt.ylabel('Loss')
        plt.title('训练损失曲线')
        plt.grid(True)

        plt.subplot(1, 2, 2)
        plt.scatter(X, y, alpha=0.5, label='数据点')
        plt.plot(X, np.dot(X_with_bias, theta), 'r-', linewidth=2, label='拟合直线')
        plt.xlabel('X')
        plt.ylabel('y')
        plt.title('线性回归结果')
        plt.legend()
        plt.grid(True)
        ---

02.随机梯度下降
    a.算法原理
        每次只使用一个样本计算梯度,更新参数。
    b.代码实现
        ---
        # 随机梯度下降
        def stochastic_gradient_descent(X, y, learning_rate=0.01, epochs=100):
            m, n = X.shape
            theta = np.zeros(n)
            loss_history = []

            for epoch in range(epochs):
                # 打乱数据
                indices = np.random.permutation(m)
                X_shuffled = X[indices]
                y_shuffled = y[indices]

                for i in range(m):
                    xi = X_shuffled[i:i+1]
                    yi = y_shuffled[i:i+1]

                    # 预测
                    y_pred = np.dot(xi, theta)

                    # 计算梯度
                    gradient = 2 * np.dot(xi.T, (y_pred - yi)).flatten()

                    # 更新参数
                    theta = theta - learning_rate * gradient

                # 计算整体损失
                y_pred_all = np.dot(X, theta)
                loss = np.mean((y_pred_all - y) ** 2)
                loss_history.append(loss)

                if epoch % 10 == 0:
                    print(f"Epoch {epoch}: Loss = {loss:.6f}")

            return theta, loss_history

        # 训练
        theta_sgd, loss_history_sgd = stochastic_gradient_descent(
            X_with_bias, y, learning_rate=0.01, epochs=100
        )

        print(f"\nSGD学习到的参数: {theta_sgd}")
        ---

03.小批量梯度下降
    a.算法原理
        每次使用一小批样本计算梯度,平衡效率和稳定性。
    b.代码实现
        ---
        # 小批量梯度下降
        def mini_batch_gradient_descent(X, y, batch_size=32, learning_rate=0.01, epochs=100):
            m, n = X.shape
            theta = np.zeros(n)
            loss_history = []

            for epoch in range(epochs):
                # 打乱数据
                indices = np.random.permutation(m)
                X_shuffled = X[indices]
                y_shuffled = y[indices]

                # 分批处理
                for i in range(0, m, batch_size):
                    Xi = X_shuffled[i:i+batch_size]
                    yi = y_shuffled[i:i+batch_size]

                    # 预测
                    y_pred = np.dot(Xi, theta)

                    # 计算梯度
                    gradient = (2/len(yi)) * np.dot(Xi.T, (y_pred - yi))

                    # 更新参数
                    theta = theta - learning_rate * gradient

                # 计算整体损失
                y_pred_all = np.dot(X, theta)
                loss = np.mean((y_pred_all - y) ** 2)
                loss_history.append(loss)

                if epoch % 10 == 0:
                    print(f"Epoch {epoch}: Loss = {loss:.6f}")

            return theta, loss_history

        # 训练
        theta_mini, loss_history_mini = mini_batch_gradient_descent(
            X_with_bias, y, batch_size=16, learning_rate=0.05, epochs=100
        )

        print(f"\nMini-batch GD学习到的参数: {theta_mini}")

        # 对比三种方法
        plt.figure(figsize=(10, 6))
        plt.plot(loss_history, label='Batch GD', linewidth=2)
        plt.plot(loss_history_sgd, label='SGD', alpha=0.7)
        plt.plot(loss_history_mini, label='Mini-batch GD', linewidth=2)
        plt.xlabel('Epoch/Iteration')
        plt.ylabel('Loss')
        plt.title('三种梯度下降方法对比')
        plt.legend()
        plt.grid(True)
        ---

3.5 在深度学习中的应用

01.反向传播算法
    a.算法流程
        前向传播计算输出,反向传播计算梯度,梯度下降更新参数。
    b.完整实现
        ---
        # 完整的两层神经网络实现
        class TwoLayerNet:
            def __init__(self, input_size, hidden_size, output_size):
                # 初始化权重
                self.W1 = np.random.randn(input_size, hidden_size) * 0.01
                self.b1 = np.zeros(hidden_size)
                self.W2 = np.random.randn(hidden_size, output_size) * 0.01
                self.b2 = np.zeros(output_size)

            def forward(self, X):
                # 第一层
                self.z1 = np.dot(X, self.W1) + self.b1
                self.a1 = np.maximum(0, self.z1)  # ReLU

                # 第二层
                self.z2 = np.dot(self.a1, self.W2) + self.b2
                return self.z2

            def backward(self, X, y, learning_rate=0.01):
                m = X.shape[0]

                # 输出层梯度
                dz2 = self.z2 - y
                dW2 = (1/m) * np.dot(self.a1.T, dz2)
                db2 = (1/m) * np.sum(dz2, axis=0)

                # 隐藏层梯度
                da1 = np.dot(dz2, self.W2.T)
                dz1 = da1 * (self.z1 > 0)  # ReLU导数
                dW1 = (1/m) * np.dot(X.T, dz1)
                db1 = (1/m) * np.sum(dz1, axis=0)

                # 更新参数
                self.W1 -= learning_rate * dW1
                self.b1 -= learning_rate * db1
                self.W2 -= learning_rate * dW2
                self.b2 -= learning_rate * db2

            def train(self, X, y, epochs=1000, learning_rate=0.01):
                loss_history = []

                for epoch in range(epochs):
                    # 前向传播
                    output = self.forward(X)

                    # 计算损失
                    loss = np.mean((output - y) ** 2)
                    loss_history.append(loss)

                    # 反向传播
                    self.backward(X, y, learning_rate)

                    if epoch % 100 == 0:
                        print(f"Epoch {epoch}: Loss = {loss:.6f}")

                return loss_history

        # 生成数据
        np.random.seed(42)
        X = np.random.rand(100, 2)
        y = (X[:, 0] + X[:, 1] > 1).astype(float).reshape(-1, 1)

        # 训练网络
        net = TwoLayerNet(input_size=2, hidden_size=10, output_size=1)
        loss_history = net.train(X, y, epochs=1000, learning_rate=0.1)

        # 测试
        test_X = np.array([[0.3, 0.4], [0.7, 0.8]])
        predictions = net.forward(test_X)
        print(f"\n测试预测: {predictions.flatten()}")

        # 可视化
        plt.figure(figsize=(12, 5))
        plt.subplot(1, 2, 1)
        plt.plot(loss_history)
        plt.xlabel('Epoch')
        plt.ylabel('Loss')
        plt.title('训练损失')
        plt.grid(True)

        plt.subplot(1, 2, 2)
        plt.scatter(X[y.flatten()==0, 0], X[y.flatten()==0, 1], c='blue', label='Class 0')
        plt.scatter(X[y.flatten()==1, 0], X[y.flatten()==1, 1], c='red', label='Class 1')
        plt.xlabel('X1')
        plt.ylabel('X2')
        plt.title('分类结果')
        plt.legend()
        plt.grid(True)
        ---

02.优化器
    a.Momentum
        a.原理
            累积历史梯度,加速收敛。
        b.代码实现
            ---
            # Momentum优化器
            class MomentumOptimizer:
                def __init__(self, learning_rate=0.01, momentum=0.9):
                    self.lr = learning_rate
                    self.momentum = momentum
                    self.velocity = {}

                def update(self, params, grads):
                    if not self.velocity:
                        for key in params.keys():
                            self.velocity[key] = np.zeros_like(params[key])

                    for key in params.keys():
                        self.velocity[key] = self.momentum * self.velocity[key] - self.lr * grads[key]
                        params[key] += self.velocity[key]

            # 测试Momentum
            def test_momentum():
                # 目标函数:f(x,y) = x^2 + 10*y^2
                def f(x):
                    return x[0]**2 + 10*x[1]**2

                def grad_f(x):
                    return np.array([2*x[0], 20*x[1]])

                x = np.array([5.0, 5.0])
                optimizer = MomentumOptimizer(learning_rate=0.01, momentum=0.9)
                params = {'x': x}
                history = [x.copy()]

                for i in range(100):
                    grads = {'x': grad_f(params['x'])}
                    optimizer.update(params, grads)
                    history.append(params['x'].copy())

                    if i % 10 == 0:
                        print(f"Iter {i}: x={params['x']}, f(x)={f(params['x']):.6f}")

                return np.array(history)

            history_momentum = test_momentum()
            ---
    b.Adam
        结合Momentum和RMSprop,是目前最常用的优化器。

4 概率论与统计

4.1 概率基础

01.概率的定义
    a.古典概型
        P(A) = 有利结果数 / 总结果数。
    b.频率定义
        大量重复实验中,事件发生的频率趋于概率。
    c.代码示例
        ---
        # 模拟抛硬币
        def coin_flip_simulation(n_flips=10000):
            results = np.random.choice(['正面', '反面'], size=n_flips)
            prob_heads = np.sum(results == '正面') / n_flips
            print(f"抛{n_flips}次硬币,正面概率: {prob_heads:.4f}")
            return prob_heads

        # 模拟不同次数
        for n in [100, 1000, 10000, 100000]:
            coin_flip_simulation(n)

        # 可视化收敛过程
        n_flips = 10000
        flips = np.random.choice([0, 1], size=n_flips)
        cumulative_prob = np.cumsum(flips) / np.arange(1, n_flips + 1)

        plt.figure(figsize=(10, 6))
        plt.plot(cumulative_prob)
        plt.axhline(y=0.5, color='r', linestyle='--', label='理论概率=0.5')
        plt.xlabel('抛硬币次数')
        plt.ylabel('正面累积概率')
        plt.title('大数定律:频率收敛到概率')
        plt.legend()
        plt.grid(True)
        ---

02.概率分布
    a.离散分布
        a.伯努利分布
            单次试验,成功概率为p。
        b.二项分布
            n次独立试验,成功k次的概率。
        c.代码示例
            ---
            from scipy import stats

            # 伯努利分布
            p = 0.3
            bernoulli_dist = stats.bernoulli(p)
            print(f"伯努利分布 P(X=1) = {bernoulli_dist.pmf(1)}")

            # 二项分布
            n, p = 10, 0.3
            binomial_dist = stats.binom(n, p)
            k_values = np.arange(0, n+1)
            probabilities = binomial_dist.pmf(k_values)

            plt.figure(figsize=(10, 6))
            plt.bar(k_values, probabilities)
            plt.xlabel('成功次数 k')
            plt.ylabel('概率 P(X=k)')
            plt.title(f'二项分布 B({n}, {p})')
            plt.grid(True)
            ---
    b.连续分布
        a.均匀分布
            在区间[a,b]上概率密度相等。
        b.正态分布
            最重要的连续分布,呈钟形曲线。
        c.代码示例
            ---
            # 正态分布
            mu, sigma = 0, 1
            normal_dist = stats.norm(mu, sigma)

            x = np.linspace(-4, 4, 1000)
            pdf = normal_dist.pdf(x)
            cdf = normal_dist.cdf(x)

            plt.figure(figsize=(12, 5))
            plt.subplot(1, 2, 1)
            plt.plot(x, pdf, linewidth=2)
            plt.xlabel('x')
            plt.ylabel('概率密度')
            plt.title('正态分布 PDF')
            plt.grid(True)

            plt.subplot(1, 2, 2)
            plt.plot(x, cdf, linewidth=2)
            plt.xlabel('x')
            plt.ylabel('累积概率')
            plt.title('正态分布 CDF')
            plt.grid(True)

            # 采样
            samples = normal_dist.rvs(size=10000)
            plt.figure(figsize=(10, 6))
            plt.hist(samples, bins=50, density=True, alpha=0.7, label='采样直方图')
            plt.plot(x, pdf, 'r-', linewidth=2, label='理论PDF')
            plt.xlabel('x')
            plt.ylabel('密度')
            plt.title('正态分布采样验证')
            plt.legend()
            plt.grid(True)
            ---

03.在AI中的应用
    a.数据分布假设
        很多机器学习算法假设数据服从正态分布。
    b.随机初始化
        神经网络权重通常用正态分布或均匀分布初始化。
    c.代码示例
        ---
        # 权重初始化
        def xavier_init(n_in, n_out):
            limit = np.sqrt(6 / (n_in + n_out))
            return np.random.uniform(-limit, limit, (n_in, n_out))

        def he_init(n_in, n_out):
            std = np.sqrt(2 / n_in)
            return np.random.randn(n_in, n_out) * std

        # 测试不同初始化方法
        n_in, n_out = 100, 50
        w_xavier = xavier_init(n_in, n_out)
        w_he = he_init(n_in, n_out)

        print(f"Xavier初始化: 均值={w_xavier.mean():.4f}, 标准差={w_xavier.std():.4f}")
        print(f"He初始化: 均值={w_he.mean():.4f}, 标准差={w_he.std():.4f}")

        # 可视化
        plt.figure(figsize=(12, 5))
        plt.subplot(1, 2, 1)
        plt.hist(w_xavier.flatten(), bins=50, alpha=0.7)
        plt.title('Xavier初始化分布')
        plt.xlabel('权重值')
        plt.ylabel('频数')

        plt.subplot(1, 2, 2)
        plt.hist(w_he.flatten(), bins=50, alpha=0.7)
        plt.title('He初始化分布')
        plt.xlabel('权重值')
        plt.ylabel('频数')
        ---

4.2 条件概率与贝叶斯定理

01.条件概率
    a.定义
        P(A|B) = P(A∩B) / P(B),表示在B发生的条件下A发生的概率。
    b.代码示例
        ---
        # 条件概率示例:疾病检测
        # P(病) = 0.01, P(阳性|病) = 0.99, P(阳性|健康) = 0.05

        P_disease = 0.01
        P_healthy = 1 - P_disease
        P_positive_given_disease = 0.99
        P_positive_given_healthy = 0.05

        # 计算 P(阳性)
        P_positive = (P_positive_given_disease * P_disease +
                     P_positive_given_healthy * P_healthy)

        print(f"P(阳性) = {P_positive:.4f}")

        # 模拟验证
        n_people = 100000
        has_disease = np.random.rand(n_people) < P_disease
        test_positive = np.where(
            has_disease,
            np.random.rand(n_people) < P_positive_given_disease,
            np.random.rand(n_people) < P_positive_given_healthy
        )

        simulated_P_positive = test_positive.sum() / n_people
        print(f"模拟 P(阳性) = {simulated_P_positive:.4f}")
        ---

02.贝叶斯定理
    a.公式
        P(A|B) = P(B|A) * P(A) / P(B)。
    b.在AI中的应用
        朴素贝叶斯分类器、贝叶斯优化。
    c.代码示例
        ---
        # 贝叶斯定理:计算 P(病|阳性)
        P_disease_given_positive = (P_positive_given_disease * P_disease) / P_positive
        print(f"P(病|阳性) = {P_disease_given_positive:.4f}")

        # 模拟验证
        positive_people = test_positive
        disease_and_positive = has_disease & positive_people
        simulated_P_disease_given_positive = disease_and_positive.sum() / positive_people.sum()
        print(f"模拟 P(病|阳性) = {simulated_P_disease_given_positive:.4f}")

        # 朴素贝叶斯分类器
        from sklearn.naive_bayes import GaussianNB

        # 生成数据
        from sklearn.datasets import make_classification
        X, y = make_classification(n_samples=1000, n_features=4, n_classes=2, random_state=42)

        # 训练
        nb = GaussianNB()
        nb.fit(X, y)

        # 预测
        y_pred = nb.predict(X[:5])
        y_proba = nb.predict_proba(X[:5])

        print(f"\n朴素贝叶斯预测:")
        print(f"类别: {y_pred}")
        print(f"概率:\n{y_proba}")
        ---

4.3 概率分布

01.期望与方差
    a.期望
        E[X] = Σ x * P(X=x),表示随机变量的平均值。
    b.方差
        Var(X) = E[(X - E[X])²],表示随机变量的离散程度。
    c.代码示例
        ---
        # 计算期望和方差
        # 离散分布
        x_values = np.array([1, 2, 3, 4, 5, 6])
        probabilities = np.array([1/6] * 6)

        expectation = np.sum(x_values * probabilities)
        variance = np.sum((x_values - expectation)**2 * probabilities)
        std = np.sqrt(variance)

        print(f"骰子期望: {expectation:.4f}")
        print(f"骰子方差: {variance:.4f}")
        print(f"骰子标准差: {std:.4f}")

        # 模拟验证
        n_rolls = 100000
        rolls = np.random.choice(x_values, size=n_rolls, p=probabilities)
        print(f"\n模拟期望: {rolls.mean():.4f}")
        print(f"模拟方差: {rolls.var():.4f}")

        # 连续分布
        mu, sigma = 5, 2
        normal_dist = stats.norm(mu, sigma)
        print(f"\n正态分布 N({mu}, {sigma}²)")
        print(f"理论期望: {mu}")
        print(f"理论方差: {sigma**2}")

        samples = normal_dist.rvs(size=100000)
        print(f"采样期望: {samples.mean():.4f}")
        print(f"采样方差: {samples.var():.4f}")
        ---

02.常见分布
    a.指数分布
        描述事件发生的时间间隔。
    b.泊松分布
        描述单位时间内事件发生的次数。
    c.代码示例
        ---
        # 指数分布
        lambda_param = 0.5
        exp_dist = stats.expon(scale=1/lambda_param)

        x = np.linspace(0, 10, 1000)
        pdf = exp_dist.pdf(x)

        plt.figure(figsize=(10, 6))
        plt.plot(x, pdf, linewidth=2)
        plt.xlabel('时间')
        plt.ylabel('概率密度')
        plt.title(f'指数分布 λ={lambda_param}')
        plt.grid(True)

        # 泊松分布
        lambda_poisson = 3
        poisson_dist = stats.poisson(lambda_poisson)

        k = np.arange(0, 15)
        pmf = poisson_dist.pmf(k)

        plt.figure(figsize=(10, 6))
        plt.bar(k, pmf)
        plt.xlabel('事件次数')
        plt.ylabel('概率')
        plt.title(f'泊松分布 λ={lambda_poisson}')
        plt.grid(True)
        ---

4.4 期望与方差

01.协方差与相关系数
    a.协方差
        Cov(X,Y) = E[(X-E[X])(Y-E[Y])],衡量两个变量的线性相关性。
    b.相关系数
        ρ = Cov(X,Y) / (σ_X * σ_Y),标准化的协方差,范围[-1, 1]。
    c.代码示例
        ---
        # 计算协方差和相关系数
        np.random.seed(42)
        n = 1000

        # 正相关
        X = np.random.randn(n)
        Y = 2 * X + np.random.randn(n) * 0.5

        cov_matrix = np.cov(X, Y)
        corr_matrix = np.corrcoef(X, Y)

        print("协方差矩阵:")
        print(cov_matrix)
        print("\n相关系数矩阵:")
        print(corr_matrix)

        # 可视化
        plt.figure(figsize=(15, 5))

        # 正相关
        plt.subplot(1, 3, 1)
        plt.scatter(X, Y, alpha=0.5)
        plt.xlabel('X')
        plt.ylabel('Y')
        plt.title(f'正相关 (ρ={corr_matrix[0,1]:.2f})')
        plt.grid(True)

        # 负相关
        Y_neg = -2 * X + np.random.randn(n) * 0.5
        corr_neg = np.corrcoef(X, Y_neg)[0, 1]
        plt.subplot(1, 3, 2)
        plt.scatter(X, Y_neg, alpha=0.5)
        plt.xlabel('X')
        plt.ylabel('Y')
        plt.title(f'负相关 (ρ={corr_neg:.2f})')
        plt.grid(True)

        # 无相关
        Y_indep = np.random.randn(n)
        corr_indep = np.corrcoef(X, Y_indep)[0, 1]
        plt.subplot(1, 3, 3)
        plt.scatter(X, Y_indep, alpha=0.5)
        plt.xlabel('X')
        plt.ylabel('Y')
        plt.title(f'无相关 (ρ={corr_indep:.2f})')
        plt.grid(True)
        ---

02.在特征工程中的应用
    a.特征相关性分析
        识别高度相关的特征,进行特征选择。
    b.代码示例
        ---
        # 特征相关性分析
        from sklearn.datasets import load_boston
        import seaborn as sns

        # 加载数据
        boston = load_boston()
        X = boston.data
        feature_names = boston.feature_names

        # 计算相关系数矩阵
        corr_matrix = np.corrcoef(X.T)

        # 可视化热力图
        plt.figure(figsize=(12, 10))
        sns.heatmap(corr_matrix, annot=True, fmt='.2f',
                   xticklabels=feature_names,
                   yticklabels=feature_names,
                   cmap='coolwarm', center=0)
        plt.title('特征相关性热力图')

        # 找出高度相关的特征对
        threshold = 0.8
        high_corr_pairs = []
        for i in range(len(feature_names)):
            for j in range(i+1, len(feature_names)):
                if abs(corr_matrix[i, j]) > threshold:
                    high_corr_pairs.append((feature_names[i], feature_names[j], corr_matrix[i, j]))

        print("\n高度相关的特征对 (|ρ| > 0.8):")
        for pair in high_corr_pairs:
            print(f"{pair[0]} - {pair[1]}: {pair[2]:.3f}")
        ---

4.5 在机器学习中的应用

01.损失函数的概率解释
    a.均方误差
        假设误差服从正态分布,最小化MSE等价于最大似然估计。
    b.交叉熵
        基于信息论,衡量预测分布与真实分布的差异。
    c.代码示例
        ---
        # 交叉熵损失
        def cross_entropy(y_true, y_pred):
            epsilon = 1e-15
            y_pred = np.clip(y_pred, epsilon, 1 - epsilon)
            return -np.mean(y_true * np.log(y_pred) + (1 - y_true) * np.log(1 - y_pred))

        # 测试
        y_true = np.array([1, 0, 1, 1, 0])
        y_pred_good = np.array([0.9, 0.1, 0.85, 0.95, 0.05])
        y_pred_bad = np.array([0.5, 0.5, 0.5, 0.5, 0.5])

        loss_good = cross_entropy(y_true, y_pred_good)
        loss_bad = cross_entropy(y_true, y_pred_bad)

        print(f"好的预测损失: {loss_good:.4f}")
        print(f"差的预测损失: {loss_bad:.4f}")

        # 可视化
        y_pred_range = np.linspace(0.01, 0.99, 100)
        loss_y1 = -np.log(y_pred_range)  # y_true=1
        loss_y0 = -np.log(1 - y_pred_range)  # y_true=0

        plt.figure(figsize=(10, 6))
        plt.plot(y_pred_range, loss_y1, label='y_true=1', linewidth=2)
        plt.plot(y_pred_range, loss_y0, label='y_true=0', linewidth=2)
        plt.xlabel('预测概率')
        plt.ylabel('交叉熵损失')
        plt.title('交叉熵损失函数')
        plt.legend()
        plt.grid(True)
        ---

02.最大似然估计
    a.原理
        找到使观测数据出现概率最大的参数。
    b.代码示例
        ---
        # 最大似然估计:估计正态分布参数
        # 生成数据
        true_mu, true_sigma = 5, 2
        data = np.random.normal(true_mu, true_sigma, 1000)

        # 最大似然估计
        mu_mle = np.mean(data)
        sigma_mle = np.std(data, ddof=0)

        print(f"真实参数: μ={true_mu}, σ={true_sigma}")
        print(f"MLE估计: μ={mu_mle:.4f}, σ={sigma_mle:.4f}")

        # 可视化
        x = np.linspace(data.min(), data.max(), 100)
        true_pdf = stats.norm(true_mu, true_sigma).pdf(x)
        mle_pdf = stats.norm(mu_mle, sigma_mle).pdf(x)

        plt.figure(figsize=(10, 6))
        plt.hist(data, bins=30, density=True, alpha=0.5, label='数据')
        plt.plot(x, true_pdf, 'r-', linewidth=2, label='真实分布')
        plt.plot(x, mle_pdf, 'g--', linewidth=2, label='MLE估计')
        plt.xlabel('x')
        plt.ylabel('密度')
        plt.title('最大似然估计')
        plt.legend()
        plt.grid(True)
        ---

03.模型评估指标
    a.混淆矩阵
        分类模型的评估基础。
    b.代码示例
        ---
        from sklearn.metrics import confusion_matrix, classification_report
        from sklearn.model_selection import train_test_split
        from sklearn.linear_model import LogisticRegression

        # 生成数据
        X, y = make_classification(n_samples=1000, n_features=10, n_classes=2, random_state=42)
        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

        # 训练模型
        model = LogisticRegression()
        model.fit(X_train, y_train)
        y_pred = model.predict(X_test)

        # 混淆矩阵
        cm = confusion_matrix(y_test, y_pred)
        print("混淆矩阵:")
        print(cm)

        # 可视化
        plt.figure(figsize=(8, 6))
        sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
        plt.xlabel('预测标签')
        plt.ylabel('真实标签')
        plt.title('混淆矩阵')

        # 分类报告
        print("\n分类报告:")
        print(classification_report(y_test, y_pred))
        ---

5 Python编程基础

5.1 Python核心语法

01.数据类型与变量
    a.基本数据类型
        整数、浮点数、字符串、布尔值。
    b.代码示例
        ---
        # 基本数据类型
        integer_var = 42
        float_var = 3.14
        string_var = "Hello AI"
        bool_var = True

        print(f"整数: {integer_var}, 类型: {type(integer_var)}")
        print(f"浮点数: {float_var}, 类型: {type(float_var)}")
        print(f"字符串: {string_var}, 类型: {type(string_var)}")
        print(f"布尔值: {bool_var}, 类型: {type(bool_var)}")

        # 类型转换
        str_num = "123"
        int_num = int(str_num)
        float_num = float(str_num)
        print(f"\n字符串转整数: {int_num}")
        print(f"字符串转浮点数: {float_num}")
        ---

02.数据结构
    a.列表
        a.定义
            有序可变序列,用方括号表示。
        b.代码示例
            ---
            # 列表操作
            numbers = [1, 2, 3, 4, 5]
            print(f"列表: {numbers}")

            # 索引和切片
            print(f"第一个元素: {numbers[0]}")
            print(f"最后一个元素: {numbers[-1]}")
            print(f"前三个元素: {numbers[:3]}")
            print(f"后两个元素: {numbers[-2:]}")

            # 添加和删除
            numbers.append(6)
            print(f"添加后: {numbers}")
            numbers.remove(3)
            print(f"删除3后: {numbers}")

            # 列表推导式
            squares = [x**2 for x in range(10)]
            print(f"平方数: {squares}")

            # 过滤
            evens = [x for x in numbers if x % 2 == 0]
            print(f"偶数: {evens}")
            ---
    b.字典
        a.定义
            键值对集合,用花括号表示。
        b.代码示例
            ---
            # 字典操作
            student = {
                'name': 'Alice',
                'age': 20,
                'scores': [85, 90, 92]
            }

            print(f"学生信息: {student}")
            print(f"姓名: {student['name']}")
            print(f"年龄: {student.get('age')}")

            # 添加和修改
            student['major'] = 'AI'
            student['age'] = 21
            print(f"更新后: {student}")

            # 遍历
            for key, value in student.items():
                print(f"{key}: {value}")

            # 字典推导式
            squared_dict = {x: x**2 for x in range(5)}
            print(f"平方字典: {squared_dict}")
            ---
    c.元组和集合
        元组不可变,集合无序且元素唯一。

03.控制流
    a.条件语句
        ---
        # if-elif-else
        score = 85

        if score >= 90:
            grade = 'A'
        elif score >= 80:
            grade = 'B'
        elif score >= 70:
            grade = 'C'
        else:
            grade = 'D'

        print(f"分数{score}对应等级{grade}")

        # 三元表达式
        result = "及格" if score >= 60 else "不及格"
        print(f"结果: {result}")
        ---
    b.循环语句
        ---
        # for循环
        for i in range(5):
            print(f"i = {i}")

        # while循环
        count = 0
        while count < 5:
            print(f"count = {count}")
            count += 1

        # enumerate
        fruits = ['apple', 'banana', 'orange']
        for idx, fruit in enumerate(fruits):
            print(f"{idx}: {fruit}")

        # zip
        names = ['Alice', 'Bob', 'Charlie']
        ages = [20, 21, 22]
        for name, age in zip(names, ages):
            print(f"{name} is {age} years old")
        ---

04.函数
    a.函数定义
        ---
        # 基本函数
        def greet(name):
            return f"Hello, {name}!"

        print(greet("Alice"))

        # 默认参数
        def power(x, n=2):
            return x ** n

        print(f"2^3 = {power(2, 3)}")
        print(f"2^2 = {power(2)}")

        # 可变参数
        def sum_all(*args):
            return sum(args)

        print(f"求和: {sum_all(1, 2, 3, 4, 5)}")

        # 关键字参数
        def print_info(**kwargs):
            for key, value in kwargs.items():
                print(f"{key}: {value}")

        print_info(name="Alice", age=20, major="AI")

        # Lambda函数
        square = lambda x: x ** 2
        print(f"5的平方: {square(5)}")

        # map和filter
        numbers = [1, 2, 3, 4, 5]
        squared = list(map(lambda x: x**2, numbers))
        evens = list(filter(lambda x: x % 2 == 0, numbers))
        print(f"平方: {squared}")
        print(f"偶数: {evens}")
        ---

5.2 NumPy数值计算

01.数组创建与操作
    a.创建数组
        ---
        import numpy as np

        # 从列表创建
        arr1 = np.array([1, 2, 3, 4, 5])
        print(f"一维数组: {arr1}")

        # 二维数组
        arr2 = np.array([[1, 2, 3], [4, 5, 6]])
        print(f"二维数组:\n{arr2}")

        # 特殊数组
        zeros = np.zeros((3, 4))
        ones = np.ones((2, 3))
        identity = np.eye(3)
        random_arr = np.random.rand(3, 3)

        print(f"\n零数组:\n{zeros}")
        print(f"单位矩阵:\n{identity}")
        print(f"随机数组:\n{random_arr}")

        # arange和linspace
        range_arr = np.arange(0, 10, 2)
        linspace_arr = np.linspace(0, 1, 5)
        print(f"\narange: {range_arr}")
        print(f"linspace: {linspace_arr}")
        ---
    b.数组属性
        ---
        arr = np.random.rand(3, 4, 5)
        print(f"形状: {arr.shape}")
        print(f"维度: {arr.ndim}")
        print(f"元素总数: {arr.size}")
        print(f"数据类型: {arr.dtype}")
        print(f"每个元素字节数: {arr.itemsize}")
        ---

02.数组运算
    a.基本运算
        ---
        # 元素级运算
        a = np.array([1, 2, 3, 4])
        b = np.array([5, 6, 7, 8])

        print(f"加法: {a + b}")
        print(f"减法: {a - b}")
        print(f"乘法: {a * b}")
        print(f"除法: {a / b}")
        print(f"幂运算: {a ** 2}")

        # 数学函数
        print(f"\nsin: {np.sin(a)}")
        print(f"exp: {np.exp(a)}")
        print(f"log: {np.log(a)}")
        print(f"sqrt: {np.sqrt(a)}")
        ---
    b.矩阵运算
        ---
        # 矩阵乘法
        A = np.array([[1, 2], [3, 4]])
        B = np.array([[5, 6], [7, 8]])

        # 点积
        C = np.dot(A, B)
        print(f"矩阵乘法:\n{C}")

        # @运算符(Python 3.5+)
        C2 = A @ B
        print(f"使用@运算符:\n{C2}")

        # 转置
        print(f"\nA的转置:\n{A.T}")

        # 逆矩阵
        A_inv = np.linalg.inv(A)
        print(f"A的逆矩阵:\n{A_inv}")

        # 验证
        I = A @ A_inv
        print(f"A * A^(-1):\n{I}")
        ---

03.广播机制
    a.原理
        不同形状的数组进行运算时,自动扩展维度。
    b.代码示例
        ---
        # 广播示例
        a = np.array([[1, 2, 3], [4, 5, 6]])
        b = np.array([10, 20, 30])

        # 广播相加
        c = a + b
        print(f"广播相加:\n{c}")

        # 标准化
        data = np.random.rand(100, 5)
        mean = data.mean(axis=0)
        std = data.std(axis=0)
        normalized = (data - mean) / std

        print(f"\n原始数据形状: {data.shape}")
        print(f"均值形状: {mean.shape}")
        print(f"标准化后形状: {normalized.shape}")
        print(f"标准化后均值: {normalized.mean(axis=0)}")
        print(f"标准化后标准差: {normalized.std(axis=0)}")
        ---

04.索引与切片
    a.高级索引
        ---
        arr = np.arange(20).reshape(4, 5)
        print(f"原数组:\n{arr}")

        # 布尔索引
        mask = arr > 10
        print(f"\n大于10的元素: {arr[mask]}")

        # 花式索引
        rows = [0, 2, 3]
        cols = [1, 3, 4]
        print(f"指定行列的元素: {arr[rows, cols]}")

        # 条件赋值
        arr[arr > 15] = 15
        print(f"\n限制最大值后:\n{arr}")
        ---

05.实用函数
    a.统计函数
        ---
        data = np.random.randn(1000)

        print(f"均值: {np.mean(data):.4f}")
        print(f"中位数: {np.median(data):.4f}")
        print(f"标准差: {np.std(data):.4f}")
        print(f"方差: {np.var(data):.4f}")
        print(f"最小值: {np.min(data):.4f}")
        print(f"最大值: {np.max(data):.4f}")

        # 按轴统计
        matrix = np.random.rand(5, 3)
        print(f"\n矩阵:\n{matrix}")
        print(f"每列均值: {matrix.mean(axis=0)}")
        print(f"每行均值: {matrix.mean(axis=1)}")
        ---
    b.排序和搜索
        ---
        arr = np.array([3, 1, 4, 1, 5, 9, 2, 6])

        # 排序
        sorted_arr = np.sort(arr)
        print(f"排序后: {sorted_arr}")

        # 排序索引
        indices = np.argsort(arr)
        print(f"排序索引: {indices}")

        # 查找
        print(f"最大值索引: {np.argmax(arr)}")
        print(f"最小值索引: {np.argmin(arr)}")

        # 唯一值
        unique_vals = np.unique(arr)
        print(f"唯一值: {unique_vals}")
        ---

5.3 Pandas数据处理

01.Series和DataFrame
    a.Series
        ---
        import pandas as pd

        # 创建Series
        s = pd.Series([1, 3, 5, 7, 9])
        print(f"Series:\n{s}")

        # 带索引的Series
        s2 = pd.Series([100, 200, 300], index=['a', 'b', 'c'])
        print(f"\n带索引的Series:\n{s2}")
        print(f"访问元素: s2['b'] = {s2['b']}")
        ---
    b.DataFrame
        ---
        # 从字典创建
        data = {
            'name': ['Alice', 'Bob', 'Charlie', 'David'],
            'age': [25, 30, 35, 28],
            'score': [85, 90, 78, 92]
        }
        df = pd.DataFrame(data)
        print(f"DataFrame:\n{df}")

        # 基本信息
        print(f"\n形状: {df.shape}")
        print(f"列名: {df.columns.tolist()}")
        print(f"数据类型:\n{df.dtypes}")
        print(f"\n���述统计:\n{df.describe()}")
        ---

02.数据读取与保存
    a.读取CSV
        ---
        # 创建示例CSV
        df.to_csv('students.csv', index=False)

        # 读取CSV
        df_read = pd.read_csv('students.csv')
        print(f"读取的数据:\n{df_read}")

        # 读取部分列
        df_partial = pd.read_csv('students.csv', usecols=['name', 'score'])
        print(f"\n部分列:\n{df_partial}")

        # 读取前N行
        df_head = pd.read_csv('students.csv', nrows=2)
        print(f"\n前2行:\n{df_head}")
        ---
    b.其他格式
        ---
        # Excel
        df.to_excel('students.xlsx', index=False)
        df_excel = pd.read_excel('students.xlsx')

        # JSON
        df.to_json('students.json', orient='records')
        df_json = pd.read_json('students.json')

        print(f"从JSON读取:\n{df_json}")
        ---

03.数据选择与过滤
    a.列选择
        ---
        # 单列
        names = df['name']
        print(f"姓名列:\n{names}")

        # 多列
        subset = df[['name', 'score']]
        print(f"\n姓名和分数:\n{subset}")
        ---
    b.行选择
        ---
        # 按位置
        first_row = df.iloc[0]
        print(f"第一行:\n{first_row}")

        # 按标签
        row_by_label = df.loc[0]
        print(f"\n标签0的行:\n{row_by_label}")

        # 切片
        rows_slice = df.iloc[1:3]
        print(f"\n第2-3行:\n{rows_slice}")
        ---
    c.条件过滤
        ---
        # 单条件
        high_scores = df[df['score'] > 85]
        print(f"高分学生:\n{high_scores}")

        # 多条件
        young_high = df[(df['age'] < 30) & (df['score'] > 85)]
        print(f"\n年轻且高分:\n{young_high}")

        # isin
        selected = df[df['name'].isin(['Alice', 'Bob'])]
        print(f"\n指定学生:\n{selected}")
        ---

04.数据清洗
    a.缺失值处理
        ---
        # 创建含缺失值的数据
        df_missing = pd.DataFrame({
            'A': [1, 2, np.nan, 4],
            'B': [5, np.nan, np.nan, 8],
            'C': [9, 10, 11, 12]
        })
        print(f"含缺失值:\n{df_missing}")

        # 检测缺失值
        print(f"\n缺失值统计:\n{df_missing.isnull().sum()}")

        # 删除缺失值
        df_dropped = df_missing.dropna()
        print(f"\n删除缺失值后:\n{df_dropped}")

        # 填充缺失值
        df_filled = df_missing.fillna(0)
        print(f"\n填充0后:\n{df_filled}")

        # 前向填充
        df_ffill = df_missing.fillna(method='ffill')
        print(f"\n前向填充:\n{df_ffill}")
        ---
    b.重复值处理
        ---
        # 创建含重复的数据
        df_dup = pd.DataFrame({
            'A': [1, 2, 2, 3],
            'B': [4, 5, 5, 6]
        })
        print(f"含重复:\n{df_dup}")

        # 检测重复
        print(f"\n重复行:\n{df_dup.duplicated()}")

        # 删除重复
        df_unique = df_dup.drop_duplicates()
        print(f"\n删除重复后:\n{df_unique}")
        ---

05.数据转换
    a.应用函数
        ---
        # apply
        df['age_group'] = df['age'].apply(lambda x: '青年' if x < 30 else '中年')
        print(f"添加年龄组:\n{df}")

        # map
        grade_map = {85: 'B', 90: 'A', 78: 'C', 92: 'A'}
        df['grade'] = df['score'].map(grade_map)
        print(f"\n添加等级:\n{df}")
        ---
    b.分组聚合
        ---
        # groupby
        grouped = df.groupby('age_group')['score'].mean()
        print(f"按年龄组平均分:\n{grouped}")

        # 多重聚合
        agg_result = df.groupby('age_group').agg({
            'score': ['mean', 'max', 'min'],
            'age': 'mean'
        })
        print(f"\n多重聚合:\n{agg_result}")
        ---

5.4 Matplotlib可视化

01.基础绘图
    a.折线图
        ---
        import matplotlib.pyplot as plt

        # 简单折线图
        x = np.linspace(0, 10, 100)
        y = np.sin(x)

        plt.figure(figsize=(10, 6))
        plt.plot(x, y, linewidth=2, label='sin(x)')
        plt.xlabel('x')
        plt.ylabel('y')
        plt.title('正弦函数')
        plt.legend()
        plt.grid(True)
        plt.show()

        # 多条曲线
        plt.figure(figsize=(10, 6))
        plt.plot(x, np.sin(x), label='sin(x)', linewidth=2)
        plt.plot(x, np.cos(x), label='cos(x)', linewidth=2)
        plt.plot(x, np.sin(x) * np.cos(x), label='sin(x)*cos(x)', linewidth=2)
        plt.xlabel('x')
        plt.ylabel('y')
        plt.title('三角函数')
        plt.legend()
        plt.grid(True)
        plt.show()
        ---
    b.散点图
        ---
        # 散点图
        np.random.seed(42)
        x = np.random.randn(100)
        y = 2 * x + np.random.randn(100) * 0.5

        plt.figure(figsize=(10, 6))
        plt.scatter(x, y, alpha=0.6, s=50)
        plt.xlabel('X')
        plt.ylabel('Y')
        plt.title('散点图')
        plt.grid(True)
        plt.show()

        # 带颜色映射
        colors = np.random.rand(100)
        sizes = np.random.rand(100) * 100

        plt.figure(figsize=(10, 6))
        plt.scatter(x, y, c=colors, s=sizes, alpha=0.6, cmap='viridis')
        plt.colorbar(label='颜色值')
        plt.xlabel('X')
        plt.ylabel('Y')
        plt.title('彩色散点图')
        plt.grid(True)
        plt.show()
        ---

02.统计图表
    a.直方图
        ---
        # 直方图
        data = np.random.randn(1000)

        plt.figure(figsize=(10, 6))
        plt.hist(data, bins=30, alpha=0.7, edgecolor='black')
        plt.xlabel('值')
        plt.ylabel('频数')
        plt.title('直方图')
        plt.grid(True, alpha=0.3)
        plt.show()

        # 多组直方图
        data1 = np.random.randn(1000)
        data2 = np.random.randn(1000) + 2

        plt.figure(figsize=(10, 6))
        plt.hist(data1, bins=30, alpha=0.5, label='组1')
        plt.hist(data2, bins=30, alpha=0.5, label='组2')
        plt.xlabel('值')
        plt.ylabel('频数')
        plt.title('多组直方图')
        plt.legend()
        plt.grid(True, alpha=0.3)
        plt.show()
        ---
    b.箱线图
        ---
        # 箱线图
        data = [np.random.randn(100) for _ in range(5)]

        plt.figure(figsize=(10, 6))
        plt.boxplot(data, labels=['A', 'B', 'C', 'D', 'E'])
        plt.ylabel('值')
        plt.title('箱线图')
        plt.grid(True, alpha=0.3)
        plt.show()
        ---

03.子图布局
    a.subplot
        ---
        # 2x2子图
        fig, axes = plt.subplots(2, 2, figsize=(12, 10))

        # 子图1:折线图
        x = np.linspace(0, 10, 100)
        axes[0, 0].plot(x, np.sin(x))
        axes[0, 0].set_title('sin(x)')
        axes[0, 0].grid(True)

        # 子图2:散点图
        axes[0, 1].scatter(np.random.randn(50), np.random.randn(50))
        axes[0, 1].set_title('散点图')
        axes[0, 1].grid(True)

        # 子图3:直方图
        axes[1, 0].hist(np.random.randn(1000), bins=30)
        axes[1, 0].set_title('直方图')
        axes[1, 0].grid(True)

        # 子图4:条形图
        axes[1, 1].bar(['A', 'B', 'C', 'D'], [3, 7, 2, 5])
        axes[1, 1].set_title('条形图')
        axes[1, 1].grid(True)

        plt.tight_layout()
        plt.show()
        ---

04.高级可视化
    a.热力图
        ---
        # 热力图
        data = np.random.rand(10, 10)

        plt.figure(figsize=(10, 8))
        plt.imshow(data, cmap='hot', interpolation='nearest')
        plt.colorbar(label='值')
        plt.title('热力图')
        plt.show()

        # 相关系数热力图
        df = pd.DataFrame(np.random.randn(100, 5), columns=['A', 'B', 'C', 'D', 'E'])
        corr = df.corr()

        plt.figure(figsize=(10, 8))
        plt.imshow(corr, cmap='coolwarm', vmin=-1, vmax=1)
        plt.colorbar(label='相关系数')
        plt.xticks(range(5), corr.columns)
        plt.yticks(range(5), corr.columns)
        plt.title('相关系数矩阵')

        # 添加数值标注
        for i in range(5):
            for j in range(5):
                plt.text(j, i, f'{corr.iloc[i, j]:.2f}',
                        ha='center', va='center', color='black')
        plt.show()
        ---
    b.3D图
        ---
        from mpl_toolkits.mplot3d import Axes3D

        # 3D曲面
        fig = plt.figure(figsize=(12, 8))
        ax = fig.add_subplot(111, projection='3d')

        x = np.linspace(-5, 5, 50)
        y = np.linspace(-5, 5, 50)
        X, Y = np.meshgrid(x, y)
        Z = np.sin(np.sqrt(X**2 + Y**2))

        surf = ax.plot_surface(X, Y, Z, cmap='viridis', alpha=0.8)
        ax.set_xlabel('X')
        ax.set_ylabel('Y')
        ax.set_zlabel('Z')
        ax.set_title('3D曲面图')
        fig.colorbar(surf)
        plt.show()
        ---

5.5 实战项目

01.线性回归实现
    a.从零实现
        ---
        # 完整的线性回归实现
        class LinearRegression:
            def __init__(self, learning_rate=0.01, iterations=1000):
                self.lr = learning_rate
                self.iterations = iterations
                self.weights = None
                self.bias = None
                self.loss_history = []

            def fit(self, X, y):
                n_samples, n_features = X.shape
                self.weights = np.zeros(n_features)
                self.bias = 0

                for i in range(self.iterations):
                    # 预测
                    y_pred = np.dot(X, self.weights) + self.bias

                    # 计算损失
                    loss = np.mean((y_pred - y) ** 2)
                    self.loss_history.append(loss)

                    # 计算梯度
                    dw = (2/n_samples) * np.dot(X.T, (y_pred - y))
                    db = (2/n_samples) * np.sum(y_pred - y)

                    # 更新参数
                    self.weights -= self.lr * dw
                    self.bias -= self.lr * db

                    if i % 100 == 0:
                        print(f"Iteration {i}: Loss = {loss:.6f}")

            def predict(self, X):
                return np.dot(X, self.weights) + self.bias

        # 生成数据
        np.random.seed(42)
        X = 2 * np.random.rand(100, 1)
        y = 4 + 3 * X.flatten() + np.random.randn(100)

        # 训练
        model = LinearRegression(learning_rate=0.1, iterations=1000)
        model.fit(X, y)

        # 预测
        y_pred = model.predict(X)

        # 可视化
        plt.figure(figsize=(15, 5))

        plt.subplot(1, 3, 1)
        plt.scatter(X, y, alpha=0.5, label='数据')
        plt.plot(X, y_pred, 'r-', linewidth=2, label='拟合线')
        plt.xlabel('X')
        plt.ylabel('y')
        plt.title('线性回归结果')
        plt.legend()
        plt.grid(True)

        plt.subplot(1, 3, 2)
        plt.plot(model.loss_history)
        plt.xlabel('Iteration')
        plt.ylabel('Loss')
        plt.title('训练损失')
        plt.grid(True)

        plt.subplot(1, 3, 3)
        residuals = y - y_pred
        plt.scatter(y_pred, residuals, alpha=0.5)
        plt.axhline(y=0, color='r', linestyle='--')
        plt.xlabel('预测值')
        plt.ylabel('残差')
        plt.title('残差图')
        plt.grid(True)

        plt.tight_layout()
        plt.show()

        print(f"\n学习到的参数:")
        print(f"权重: {model.weights}")
        print(f"偏置: {model.bias:.4f}")
        ---

02.K-Means聚类实现
    a.算法实现
        ---
        # K-Means聚类
        class KMeans:
            def __init__(self, n_clusters=3, max_iters=100):
                self.n_clusters = n_clusters
                self.max_iters = max_iters
                self.centroids = None

            def fit(self, X):
                # 随机初始化中心点
                n_samples = X.shape[0]
                random_indices = np.random.choice(n_samples, self.n_clusters, replace=False)
                self.centroids = X[random_indices]

                for i in range(self.max_iters):
                    # 分配样本到最近的中心
                    labels = self._assign_clusters(X)

                    # 更新中心点
                    new_centroids = np.array([X[labels == k].mean(axis=0)
                                            for k in range(self.n_clusters)])

                    # 检查收敛
                    if np.allclose(self.centroids, new_centroids):
                        print(f"收敛于第{i}次迭代")
                        break

                    self.centroids = new_centroids

                return labels

            def _assign_clusters(self, X):
                distances = np.sqrt(((X - self.centroids[:, np.newaxis])**2).sum(axis=2))
                return np.argmin(distances, axis=0)

            def predict(self, X):
                return self._assign_clusters(X)

        # 生成数据
        from sklearn.datasets import make_blobs
        X, y_true = make_blobs(n_samples=300, centers=3, n_features=2,
                              cluster_std=0.6, random_state=42)

        # 训练
        kmeans = KMeans(n_clusters=3, max_iters=100)
        y_pred = kmeans.fit(X)

        # 可视化
        plt.figure(figsize=(12, 5))

        plt.subplot(1, 2, 1)
        plt.scatter(X[:, 0], X[:, 1], c=y_true, cmap='viridis', alpha=0.6)
        plt.title('真实标签')
        plt.xlabel('特征1')
        plt.ylabel('特征2')
        plt.grid(True)

        plt.subplot(1, 2, 2)
        plt.scatter(X[:, 0], X[:, 1], c=y_pred, cmap='viridis', alpha=0.6)
        plt.scatter(kmeans.centroids[:, 0], kmeans.centroids[:, 1],
                   c='red', marker='X', s=200, edgecolors='black', label='中心点')
        plt.title('K-Means聚类结果')
        plt.xlabel('特征1')
        plt.ylabel('特征2')
        plt.legend()
        plt.grid(True)

        plt.tight_layout()
        plt.show()
        ---

03.数据分析项目
    a.完整流程
        ---
        # 数据分析完整流程
        # 1. 加载数据
        from sklearn.datasets import load_iris
        iris = load_iris()
        df = pd.DataFrame(iris.data, columns=iris.feature_names)
        df['species'] = iris.target

        print("数据概览:")
        print(df.head())
        print(f"\n数据形状: {df.shape}")
        print(f"\n数据类型:\n{df.dtypes}")

        # 2. 探索性数据分析
        print(f"\n描述统计:\n{df.describe()}")

        # 3. 可视化
        fig, axes = plt.subplots(2, 2, figsize=(15, 12))

        # 特征分布
        for idx, col in enumerate(iris.feature_names):
            ax = axes[idx // 2, idx % 2]
            for species in range(3):
                data = df[df['species'] == species][col]
                ax.hist(data, alpha=0.5, label=f'Species {species}', bins=20)
            ax.set_xlabel(col)
            ax.set_ylabel('频数')
            ax.set_title(f'{col}分布')
            ax.legend()
            ax.grid(True, alpha=0.3)

        plt.tight_layout()
        plt.show()

        # 4. 相关性分析
        corr = df.iloc[:, :-1].corr()
        plt.figure(figsize=(10, 8))
        sns.heatmap(corr, annot=True, fmt='.2f', cmap='coolwarm', center=0)
        plt.title('特征相关性矩阵')
        plt.show()

        # 5. 特征工程
        df['petal_area'] = df['petal length (cm)'] * df['petal width (cm)']
        df['sepal_area'] = df['sepal length (cm)'] * df['sepal width (cm)']

        print(f"\n新特征:\n{df[['petal_area', 'sepal_area']].head()}")

        # 6. 建模
        from sklearn.model_selection import train_test_split
        from sklearn.ensemble import RandomForestClassifier
        from sklearn.metrics import accuracy_score, classification_report

        X = df.drop('species', axis=1)
        y = df['species']

        X_train, X_test, y_train, y_test = train_test_split(
            X, y, test_size=0.2, random_state=42
        )

        model = RandomForestClassifier(n_estimators=100, random_state=42)
        model.fit(X_train, y_train)

        y_pred = model.predict(X_test)
        accuracy = accuracy_score(y_test, y_pred)

        print(f"\n模型准确率: {accuracy:.4f}")
        print(f"\n分类报告:\n{classification_report(y_test, y_pred)}")

        # 7. 特征重要性
        importances = model.feature_importances_
        indices = np.argsort(importances)[::-1]

        plt.figure(figsize=(10, 6))
        plt.bar(range(len(importances)), importances[indices])
        plt.xticks(range(len(importances)), X.columns[indices], rotation=45, ha='right')
        plt.xlabel('特征')
        plt.ylabel('重要性')
        plt.title('特征重要性')
        plt.tight_layout()
        plt.show()
        ---

6 学习路径与资源

6.1 推荐学习顺序

01.第一阶段
    a.线性代数基础
        a.学习内容
            向量、矩阵、矩阵运算、特征值与特征向量。
        b.学习时长
            2-3周,每天2-3小时。
        c.学习方法
            先看视频理解概念,再用NumPy实现算法,最后做练习题巩固。
        d.检验标准
            能手算简单矩阵运算,能用NumPy实现矩阵分解,理解神经网络中的矩阵运算。
    b.Python基础
        a.学习内容
            Python语法、NumPy、Pandas基础操作。
        b.学习时长
            1-2周,每天2-3小时。
        c.学习方法
            边学边练,每个知识点都要写代码验证,完成小项目。
        d.检验标准
            能独立完成数据读取、清洗、分析、可视化的完整流程。

02.第二阶段
    a.微积分
        a.学习内容
            导数、偏导数、梯度、链式法则、梯度下降算法。
        b.学习时长
            2-3周,每天2-3小时。
        c.学习方法
            理解几何意义,用NumPy实现数值计算,手推简单网络的梯度。
        d.检验标准
            能手推梯度下降公式,能实现完整的反向传播算法。
    b.概率论
        a.学习内容
            概率分布、期望方差、贝叶斯定理、最大似然估计。
        b.学习时长
            1-2周,每天2-3小时。
        c.学习方法
            理论结合实践,用代码模拟验证概率定理。
        d.检验标准
            理解损失函数的概率解释,能实现朴素贝叶斯分类器。

03.第三阶段
    a.综合实践
        a.项目一
            从零实现线性回归,包括梯度下降、损失计算、可视化。
        b.项目二
            从零实现两层神经网络,包括前向传播、反向传播、训练。
        c.项目三
            完整的数据分析项目,从数据加载到建模评估。
    b.时间安排
        每个项目1周,共3周。

04.学习建议
    a.理论与实践结合
        每学一个概念,立即用代码实现,加深理解。
    b.循序渐进
        不要跳过基础,扎实掌握每个知识点再进入下一阶段。
    c.多做练习
        数学需要大量练习才能熟练,编程需要大量代码才能精通。
    d.及时复习
        每周复习前一周内容,防止遗忘。

6.2 在线课程推荐

01.数学课程
    a.线性代数
        a.3Blue1Brown线性代数本质
            视频课程,用动画讲解线性代数的几何直觉,强烈推荐。
        b.MIT线性代数
            Gilbert Strang教授的经典课程,理论严谨,适合深入学习。
        c.Khan Academy线性代数
            免费在线课程,适合零基础入门。
    b.微积分
        a.3Blue1Brown微积分本质
            用动画讲解微积分的核心思想,直观易懂。
        b.MIT单变量微积分
            系统的微积分课程,适合有一定基础的学习者。
    c.概率论
        a.Khan Academy概率论
            从基础到进阶,循序渐进。
        b.MIT概率论导论
            理论严谨,适合深入学习。

02.Python课程
    a.Python基础
        a.Python官方教程
            最权威的入门教程,免费在线阅读。
        b.Coursera Python for Everybody
            密歇根大学的Python入门课程,适合零基础。
    b.数据科学Python
        a.DataCamp
            交互式学习平台,边学边练。
        b.Kaggle Learn
            免费的数据科学课程,包含NumPy、Pandas、可视化。

03.综合课程
    a.吴恩达机器学习
        Coursera上的经典课程,包含数学基础和编程实践。
    b.Fast.ai
        实践导向的深度学习课程,适合快速上手。
    c.Udacity AI编程基础
        系统的AI入门课程,包含Python、NumPy、Pandas。

6.3 书籍推荐

01.数学书籍
    a.线性代数
        a.线性代数及其应用
            作者Gilbert Strang,经典教材,理论与应用并重。
        b.线性代数的几何意义
            用几何直觉讲解线性代数,适合入门。
        c.程序员的数学
            结合编程讲解数学,适合程序员学习。
    b.微积分
        a.托马斯微积分
            经典教材,内容全面,适合系统学习。
        b.普林斯顿微积分读本
            通俗易懂,适合自学。
    c.概率论
        a.概率论与数理统计
            经典教材,理论严谨。
        b.深度学习的数学
            专门为深度学习准备的数学书籍。

02.Python书籍
    a.Python基础
        a.Python编程从入门到实践
            适合零基础,实践项目丰富。
        b.流畅的Python
            进阶书籍,深入Python特性。
    b.数据科学
        a.利用Python进行数据分析
            Pandas作者Wes McKinney所著,权威教材。
        b.Python数据科学手册
            涵盖NumPy、Pandas、Matplotlib、Scikit-learn。

03.综合书籍
    a.深度学习入门
        斋藤康毅著,用Python从零实现深度学习,适合入门。
    b.机器学习实战
        Peter Harrington著,实践导向,代码丰富。
    c.统计学习方法
        李航著,理论严谨,适合深入学习。

6.4 实践项目

01.入门项目
    a.项目一
        a.项目名称
            手写数字识别(MNIST)。
        b.技术要点
            NumPy实现神经网络,理解前向传播和反向传播。
        c.学习目标
            掌握矩阵运算在神经网络中的应用。
        d.参考代码
            ---
            # MNIST手写数字识别框架
            # 1. 数据加载
            from sklearn.datasets import load_digits
            digits = load_digits()
            X, y = digits.data, digits.target

            # 2. 数据预处理
            X = X / 16.0  # 归一化
            y_onehot = np.eye(10)[y]  # one-hot编码

            # 3. 划分数据集
            from sklearn.model_selection import train_test_split
            X_train, X_test, y_train, y_test = train_test_split(
                X, y_onehot, test_size=0.2, random_state=42
            )

            # 4. 构建神经网络(参考前面的TwoLayerNet)
            # 5. 训练模型
            # 6. 评估性能
            # 7. 可视化结果
            ---
    b.项目二
        a.项目名称
            房价预测(线性回归)。
        b.技术要点
            特征工程、梯度下降、模型评估。
        c.学习目标
            掌握完整的机器学习流程。
    c.项目三
        a.项目名称
            鸢尾花分类(多分类)。
        b.技术要点
            数据可视化、特征分析、模型对比。
        c.学习目标
            掌握数据分析和建模的完整流程。

02.进阶项目
    a.项目一
        a.项目名称
            图像分类(CIFAR-10)。
        b.技术要点
            卷积神经网络、数据增强、模型调优。
        c.学习目标
            理解卷积操作的数学原理。
    b.项目二
        a.项目名称
            文本情感分析。
        b.技术要点
            词向量、RNN/LSTM、序列建模。
        c.学习目标
            理解序列模型的数学基础。
    c.项目三
        a.项目名称
            推荐系统。
        b.技术要点
            矩阵分解、协同过滤、评估指标。
        c.学习目标
            理解矩阵分解在推荐系统中的应用。

03.Kaggle竞赛
    a.入门竞赛
        a.Titanic生存预测
            经典入门竞赛,适合练习数据处理和建模。
        b.House Prices
            房价预测,适合练习特征工程。
    b.进阶竞赛
        根据兴趣选择图像、文本、表格数据等不同类型的竞赛。

6.5 常见问题

01.学习困难
    a.数学太难怎么办
        a.降低期望
            不需要掌握所有数学知识,重点理解AI中常用的部分。
        b.从应用入手
            先学会用,再理解原理,逐步深入。
        c.多看可视化
            利用3Blue1Brown等可视化资源,建立几何直觉。
        d.多做练习
            数学需要大量练习,从简单题目开始,逐步提高。
    b.编程基础薄弱
        a.从Python基础开始
            不要急于学AI,先打好Python基础。
        b.多写代码
            每天至少写1小时代码,熟能生巧。
        c.参考优秀代码
            阅读开源项目,学习编程规范和技巧。
        d.做小项目
            从简单项目开始,逐步提高复杂度。
    c.学习进度慢
        a.制定计划
            每天固定时间学习,养成习惯。
        b.专注重点
            不要贪多,先掌握核心知识。
        c.及时复习
            定期复习已学内容,巩固记忆。
        d.寻求帮助
            遇到问题及时求助,不要钻牛角尖。

02.工具问题
    a.环境配置
        a.推荐Anaconda
            集成Python和常用库,一键安装。
        b.使用Jupyter Notebook
            交互式编程,适合学习和实验。
        c.遇到问题查文档
            官方文档是最权威的参考资料。
    b.GPU问题
        a.基础学习不需要GPU
            CPU足够完成本课程的所有内容。
        b.需要GPU时
            可以使用Google Colab免费GPU资源。
        c.本地GPU
            有条件可以购买NVIDIA显卡,安装CUDA。

03.职业发展
    a.如何找工作
        a.扎实基础
            数学和编程基础是面试重点。
        b.项目经验
            完成2-3个完整项目,写入简历。
        c.刷题准备
            LeetCode算法题,机器学习面试题。
        d.持续学习
            关注最新技术,保持竞争力。
    b.薪资水平
        a.初级工程师
            15-25K,要求扎实的基础和1-2个项目经验。
        b.中级工程师
            25-40K,要求独立完成项目,有优化经验。
        c.高级工程师
            40K+,要求架构设计能力,技术深度���
    c.职业路径
        a.算法工程师
            偏重算法研究和优化,需要强数学背景。
        b.应用工程师
            偏重工程实现和部署,需要强编程能力。
        c.研究科学家
            偏重前沿研究,需要博士学位和论文发表。

04.学习资源
    a.在线社区
        a.GitHub
            开源代码和项目,学习优秀实践。
        b.Stack Overflow
            编程问题求助,快速解决bug。
        c.Reddit机器学习
            讨论最新技术和论文。
        d.知乎AI话题
            中文社区,适合交流学习经验。
    b.论文阅读
        a.arXiv
            最新AI论文预印本。
        b.Papers With Code
            论文+代码,方便复现。
        c.Google Scholar
            学术搜索引擎。
    c.博客推荐
        a.Distill
            高质量可视化AI文章。
        b.Towards Data Science
            Medium上的数据科学博客。
        c.机器之心
            中文AI资讯和技术文章。