数据准备与模型评估

首先是库的导入问题

 我们win+R镜像下载python -m pip install scikit-learn  -i https://pypi.tuna.tsinghua.edu.cn/simple

 我们来看效果

 运行代码

 下面是我的实验报告

实验一:数据准备与模型评估

一、实验目的

熟悉 Python 的基本操作,掌握对数据集的读写实现、对模型性能的评估实现的能力;

加深对训练集、测试集、N 折交叉验证、模型评估标准的理解。

 

 

二、实验内容

 

(1)利用 pandas 库从本地读取 iris 数据集;

(2)从 scikit-learn 库中直接加载 iris 数据集;

(3)实现折交叉验证进行模型训练;

(4)计算并输出模型的准确度、精度、召回率和 F1 值。

 

 

三、算法步骤、代码、及结果

   1. 算法伪代码

输入: 数据集 D,最大深度 max_depth,最小样本分裂数 min_samples_split

输出: 训练好的决策树模型

 

函数 构建决策树 (D, depth)

    如果 所有样本属于同一类 或者 depth >= max_depth 或者 数据集样本数 < min_samples_split

        返回 当前节点类别标签

    否则

        寻找最佳分裂特征和分裂点

        将数据集 D 根据最佳分裂点分为两个子集 D_left D_right

        创建新节点,存储分裂特征和分裂点

        递归调用构建决策树函数:

            左子树 = 构建决策树(D_left, depth + 1)

            右子树 = 构建决策树(D_right, depth + 1)

        将左子树和右子树连接到当前节点

    返回 当前节点

结束函数

 

函数 预测 (输入样本 x)

    从根节点开始,沿决策路径遍历树

    在叶节点返回预测类别

结束函数

 

   2. 算法主要代码

1)完整源代码

import numpy as np
from sklearn.datasets import load_iris
from sklearn.metrics import precision_score, recall_score, f1_score, accuracy_score

# 1. 加载 iris 数据集
iris = load_iris()
X = iris.data  # 特征数据
y = iris.target  # 标签数据


# 2. 自定义随机森林分类器(简化版)
class SimpleRandomForest:
    def __init__(self, n_estimators=100):
        self.n_estimators = n_estimators
        self.trees = []

    def fit(self, X, y):
        """简化的训练方法,使用决策树训练随机森林"""
        from sklearn.tree import DecisionTreeClassifier
        self.trees = []
        for _ in range(self.n_estimators):
            tree = DecisionTreeClassifier(max_depth=5)  # 限制树的深度
            tree.fit(X, y)
            self.trees.append(tree)

    def predict(self, X):
        """简化的预测方法,使用每棵树的预测结果进行投票"""
        predictions = np.zeros((self.n_estimators, X.shape[0]))
        for i, tree in enumerate(self.trees):
            predictions[i] = tree.predict(X)
        return np.array([np.bincount(predictions[:, i].astype(int)).argmax() for i in range(X.shape[0])])


# 3. 手动实现五折交叉验证
def cross_val_score_custom(X, y, model, cv=5):
    n_samples = len(X)
    fold_size = n_samples // cv
    accuracy_list = []
    precision_list = []
    recall_list = []
    f1_list = []

    for i in range(cv):
        # 划分训练集和验证集
        test_idx = list(range(i * fold_size, (i + 1) * fold_size))
        train_idx = list(set(range(n_samples)) - set(test_idx))

        X_train, X_test = X[train_idx], X[test_idx]
        y_train, y_test = y[train_idx], y[test_idx]

        # 训练模型
        model.fit(X_train, y_train)

        # 预测
        y_pred = model.predict(X_test)

        # 计算准确度、精度、召回率、F1 值
        accuracy = accuracy_score(y_test, y_pred)
        precision = precision_score(y_test, y_pred, average='weighted', zero_division=1)
        recall = recall_score(y_test, y_pred, average='weighted', zero_division=1)
        f1 = f1_score(y_test, y_pred, average='weighted', zero_division=1)

        accuracy_list.append(accuracy)
        precision_list.append(precision)
        recall_list.append(recall)
        f1_list.append(f1)

    # 输出结果
    print(f'五折交叉验证的准确度: {np.mean(accuracy_list):.4f} (+/- {np.std(accuracy_list):.4f})')
    print(f'五折交叉验证的精度: {np.mean(precision_list):.4f} (+/- {np.std(precision_list):.4f})')
    print(f'五折交叉验证的召回率: {np.mean(recall_list):.4f} (+/- {np.std(recall_list):.4f})')
    print(f'五折交叉验证的 F1 值: {np.mean(f1_list):.4f} (+/- {np.std(f1_list):.4f})')


# 4. 创建模型并运行自定义五折交叉验证
rf_model = SimpleRandomForest(n_estimators=10)
cross_val_score_custom(X, y, rf_model, cv=5)

 

(2)调用库方法

import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score, StratifiedKFold
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import make_scorer, precision_score, recall_score, f1_score
import numpy as np
 
# scikit-learn 加载 iris 数据集
iris = load_iris()
X = iris.data  # 特征数据
y = iris.target  # 标签数据

# 实现五折交叉验证并训练模型
# 创建分类器
rf_classifier = RandomForestClassifier(n_estimators=100)

# 使用 StratifiedKFold 进行五折交叉验证
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

# 计算模型的准确度
accuracy = cross_val_score(rf_classifier, X, y, cv=cv, scoring='accuracy')
print(f'五折交叉验证的准确度: {accuracy.mean():.4f} (+/- {accuracy.std():.4f})')

# 4. 计算并输出模型的准确度、精度、召回率和 F1 值
def evaluate_model(model, X, y, cv):
    # 创建自定义的评估函数
    precision = make_scorer(precision_score, average='weighted', zero_division=1)
    recall = make_scorer(recall_score, average='weighted', zero_division=1)
    f1 = make_scorer(f1_score, average='weighted', zero_division=1)

    # 计算精度、召回率和 F1 值
    precision_scores = cross_val_score(model, X, y, cv=cv, scoring=precision)
    recall_scores = cross_val_score(model, X, y, cv=cv, scoring=recall)
    f1_scores = cross_val_score(model, X, y, cv=cv, scoring=f1)

    print(f'五折交叉验证的精度: {precision_scores.mean():.4f} (+/- {precision_scores.std():.4f})')
    print(f'五折交叉验证的召回率: {recall_scores.mean():.4f} (+/- {recall_scores.std():.4f})')
    print(f'五折交叉验证的 F1 值: {f1_scores.mean():.4f} (+/- {f1_scores.std():.4f})')

# 运行模型评估
evaluate_model(rf_classifier, X, y, cv)

 

 注(参数解释):

RandomForestClassifier 参数:

 n_estimators=100:表示随机森林中树的数量为 100。树的数量越多,模型的表现会更稳定,但计算成本也会增加。

StratifiedKFold 参数:

n_splits=5:将数据集划分为 5 份,即进行五折交叉验证。

shuffle=True:在划分数据集前将数据进行随机打乱,以确保每折数据更具代表性。

random_state=42:随机数种子,保证每次运行代码时数据划分一致。

 cross_val_score 参数:

 model:传入的模型(如 rf_classifier),在本例中是随机森林分类器。

X, y:特征数据和标签数据。

cv=cv:指定交叉验证的方式,这里使用了 StratifiedKFold 进行五折交叉验证。

scoring:指定评估标准。代码中用了多种评分标准来分别计算准确度、精度、召回率和 F1 值。

make_scorer 参数:

 precision_score, recall_score, f1_score:用于评估模型的精度、召回率和 F1 值的指标。

average='weighted':在多分类问题中,使用加权平均方式计算整体分数。

zero_division=1:在分母为 0 的情况下,返回 1 以避免错误。

posted @ 2024-11-13 10:33  艾鑫4646  阅读(6)  评论(0编辑  收藏  举报