Iridescent:Day29

https://blog.youkuaiyun.com/weixin_45655710?type=blog
@浙大疏锦行

DAY 29 复习日:类的装饰器
知识点回顾
1.类的装饰器
2.装饰器思想的进一步理解:外部修改、动态
3.类方法的定义:内部定义和外部定义

作业:复习类和函数的知识点,写下自己过去29天的学习心得,如对函数和类的理解,对python这门工具的理解等,未来再过几个专题部分我们即将开启深度学习部分。

1. 知识脉络图谱

我们可以把这几天的学习内容看作构建一个智能工厂的过程:

  • Day 28 面向对象 (OOP):这是工厂的蓝图。我们将数据和操作封装成“类”,比如“模型训练器”、“数据处理器”。
  • Day 23 管道 (Pipeline):这是流水线。我们将数据预处理、特征工程、模型训练串联起来,一键运行,防止数据泄露。
  • Day 26 函数参数 (*args, kwargs):这是灵活的控制台**。允许我们传入任意数量的配置和参数,增加工厂的通用性。
  • Day 27 装饰器 (@decorator):这是监控探头。在不拆开机器(修改函数源码)的情况下,给流水线加上计时、日志记录功能。
  • Day 25 异常处理 (try-except):这是安全气囊。防止某个零件出错(如除零、文件丢失)导致整个工厂爆炸(程序崩溃)。
  • Day 24 元组 & OS 模块:这是档案室和文件柜。元组定义不可修改的配置(如输入形状),OS 模块管理文件的路径和存储。

2. 核心知识点速查表

模块核心代码/概念在 ML/DL 中的应用场景
PipelinePipeline(steps=[('scaler', scaler), ('clf', model)])自动化数据清洗与训练,防止验证集数据泄露
OS 模块os.path.join(), os.walk(), os.makedirs()数据集管理:批量读取图片,自动创建模型保存目录。
异常处理try: ... except Error: ... finally: ...鲁棒性训练:遇到损坏图片跳过不报错;训练中断时保存进度。
函数参数def func(*args, **kwargs):超参数调优:接收不确定数量的模型配置参数(如 layer_num, dropout_rate)。
装饰器@timer, @logger实验监控:自动记录每个实验的训练耗时、显存占用。
面向对象class Model(object): def __init__(self): ...模型封装:PyTorch/Sklearn 中几乎所有模型都是类。

3. 综合实战作业:打造一个“智能模型训练器”

这个代码案例同时使用了:class (OOP), pipeline (管道), try-except (异常处理), os (路径管理), @decorator (装饰器), 和 **kwargs (参数)。

请仔细阅读代码和注释,这就是你这周学习成果的集大成者

import os
import time
import functools
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.impute import SimpleImputer

# --- Day 27: 装饰器 (用于记录日志和时间) ---
def experiment_logger(func):
    """记录实验开始和结束时间,以及运行状态"""
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print(f"\n[LOG] >>> 开始执行: {func.__name__}")
        start_time = time.time()
        try:
            result = func(*args, **kwargs) # 执行原函数
            print(f"[LOG] <<< 执行成功,耗时: {time.time() - start_time:.2f}s")
            return result
        except Exception as e:
            print(f"[LOG] !!! 执行出错: {e}")
            raise # 继续抛出异常,让外部捕获
    return wrapper

# --- Day 28: 面向对象 (封装整个训练流程) ---
class HousingModelTrainer:
    
    # --- Day 26: 默认参数与初始化 ---
    def __init__(self, data_path, save_dir="models"):
        self.data_path = data_path
        self.save_dir = save_dir
        # --- Day 24: OS 模块 (创建目录) ---
        if not os.path.exists(self.save_dir):
            os.makedirs(self.save_dir)
            print(f"已创建模型保存目录: {self.save_dir}")

    # --- Day 25: 异常处理 (数据加载) ---
    def load_data(self):
        print("正在加载数据...")
        try:
            # 假设数据是 Day 23-24 用到的 housing.csv
            if not os.path.exists(self.data_path):
                raise FileNotFoundError(f"文件未找到: {self.data_path}")
            
            df = pd.read_csv(self.data_path)
            # 简单处理:仅选取部分数值列演示
            X = df[['longitude', 'latitude', 'housing_median_age', 'total_rooms', 'median_income']]
            y = df['median_house_value']
            return train_test_split(X, y, test_size=0.2, random_state=42)
            
        except FileNotFoundError as e:
            print(f"严重错误: {e}")
            return None, None, None, None
        except Exception as e:
            print(f"读取数据时发生未知错误: {e}")
            return None, None, None, None

    # --- Day 23: Pipeline (构建管道) ---
    def _build_pipeline(self, n_estimators=100):
        """内部方法:构建预处理和模型管道"""
        pipeline = Pipeline([
            ('imputer', SimpleImputer(strategy='median')), # 缺失值填充
            ('scaler', StandardScaler()),                  # 标准化
            ('regressor', RandomForestRegressor(n_estimators=n_estimators, random_state=42))
        ])
        return pipeline

    # --- Day 26 & 27: 装饰器应用 + **kwargs 动态参数 ---
    @experiment_logger 
    def train(self, **kwargs):
        """
        训练模型
        **kwargs: 接收如 n_estimators 等模型超参数
        """
        X_train, X_test, y_train, y_test = self.load_data()
        
        if X_train is None:
            print("数据加载失败,终止训练。")
            return

        # 获取参数,如果没传则使用默认值 100
        n_est = kwargs.get('n_estimators', 100)
        
        print(f"构建 Pipeline,参数 n_estimators={n_est}...")
        self.pipeline = self._build_pipeline(n_estimators=n_est)

        # Day 25: 异常处理 (训练过程)
        try:
            self.pipeline.fit(X_train, y_train)
            score = self.pipeline.score(X_test, y_test)
            print(f"模型训练完成!测试集 R2 分数: {score:.4f}")
            
            # --- Day 24: OS 路径拼接 ---
            model_save_path = os.path.join(self.save_dir, f"rf_model_{n_est}.pkl")
            # 这里假装保存模型
            with open(model_save_path, 'w') as f:
                f.write("Simulated Model Binary")
            print(f"模型已保存至: {model_save_path}")
            
        except Exception as e:
            print(f"训练过程中断: {e}")
        finally:
            print("训练流程结束 (清理临时资源...)")

# --- 主程序运行 ---
if __name__ == "__main__":
    # 假设当前目录下有 housing.csv,如果没有,你可以换成自己的路径
    # Day 24: 使用原始字符串处理路径
    data_file = 'housing.csv' 
    
    # 1. 实例化对象
    trainer = HousingModelTrainer(data_path=data_file)
    
    # 2. 调用方法 (传入 **kwargs)
    # 即使 housing.csv 不存在,程序也不会崩溃,而是会打印错误日志
    trainer.train(n_estimators=50)


4. 复习总结语

这段代码展示了一个成熟的 Python 程序员是如何思考的:

  1. 不写死逻辑:用 class 封装,用 **kwargs 传参。
  2. 不裸奔运行:用 pipeline 保护数据流,用 try-except 保护程序流。
  3. 自动化管理:用 os 处理路径,用 decorator 自动记录日志。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值