数据准备与模型评估
首先是库的导入问题
我们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 以避免错误。