【机器学习】Scikit-learn 框架基础
机器学习
- Scikit-learn
- Scikit-learn 框架基础
- Scikit-learn 概念
- 核心模块结构
- 统一接口设计
- 典型机器学习流程
- 实战:Iris 鸢尾花分类
- fit /predict/score 工作机制
- 思考
Scikit-learn
Scikit-learn 框架基础
Scikit-learn 概念
Scikit-learn 到底是什么?
Scikit-learn(简称 sklearn)是 Python 生态中最成熟、应用最广泛的机器学习库之一。它不是用来做底层算法研发的(比如从零实现神经网络),而是把机器学习领域经过验证的经典算法(如线性回归、决策树、SVM 等)封装成 “即用型工具”,让你不用关心算法的数学细节,就能快速实现从数据到模型的全流程。
可以把它类比为:
如果你想做木工,不需要自己造锯子、锤子(算法原理),sklearn 就是一套现成的、标准化的工具套装,你只需要学会怎么用这些工具做出椅子、桌子(解决实际问题)。
它能解决什么问题?
sklearn 覆盖了机器学习的全流程需求,具体来说:
- 数据层面:加载内置数据集(如鸢尾花、波士顿房价)、处理外部数据;
- 预处理层面:清洗数据(填缺失值、标准化)、转换特征(编码分类变量);
- 模型层面:提供几十种经典模型(分类、回归、聚类、降维等);
- 评估层面:计算模型性能指标(准确率、MSE 等)、做交叉验证;
- 工程层面:把流程封装成管道(Pipeline)、保存 / 加载模型。
简单说:从 “拿到数据” 到 “模型上线”,sklearn 能搞定中间几乎所有环节(除了极复杂的深度学习任务,那是 TensorFlow/PyTorch 的领域)。
核心思想:“好用”的原因
sklearn 的流行,核心在于它的三大设计哲学:
-
统一接口
不管是简单的线性回归,还是复杂的随机森林,所有模型都长一个 “样子”—— 都用
fit()训练、predict()预测、score()评估。举个例子:
# 线性回归 from sklearn.linear_model import LinearRegression model1 = LinearRegression() model1.fit(X_train, y_train) # 训练 y_pred1 = model1.predict(X_test) # 预测# 随机森林 from sklearn.ensemble import RandomForestRegressor model2 = RandomForestRegressor() model2.fit(X_train, y_train) # 同样用 fit 训练 y_pred2 = model2.predict(X_test) # 同样用 predict 预测这种 “统一” 意味着:学会一个模型的用法,就相当于学会了所有模型的用法,极大降低了学习成本。
-
模块化设计
sklearn 把机器学习流程拆成了一个个独立的 “模块”(比如数据加载模块、预处理模块、模型模块等),每个模块专注做一件事,而且可以自由组合。
比如:用
preprocessing模块处理数据后,可以接linear_model模块的模型,也可以接ensemble模块的模型,像搭积木一样灵活。 -
流水线式工作流
机器学习的实际流程是 “数据加载→预处理→训练→评估” 的线性步骤,sklearn 专门设计了
Pipeline工具,能把这些步骤串成一条 “流水线”,避免手动操作的繁琐和出错(比如防止数据泄露)。
核心模块结构
-
数据加载:
sklearn.datasets功能:提供内置数据集,或帮助加载外部数据。
- 内置经典数据集:比如
load_iris()(鸢尾花分类)、load_boston()(房价回归,注意新版已移除,可用fetch_california_housing()替代)、load_digits()(手写数字识别)。 - 加载外部数据:
load_csv()等工具(不过实际中更常用 Pandas 读数据,这个模块主要方便入门练习)。
作用:让你不用自己找数据,直接上手练模型。
- 内置经典数据集:比如
-
数据集处理:
sklearn.model_selection功能:解决 “如何用数据训练和验证模型” 的问题,核心是 “划分数据” 和 “评估策略”。
- 数据集划分:
train_test_split()—— 把数据分成训练集(供模型学习)和测试集(检验模型效果),是入门必用函数。 - 交叉验证:
cross_val_score()、KFold()—— 避免单次划分的偶然性,用多组数据验证模型稳定性。 - 模型选择:
GridSearchCV、RandomizedSearchCV—— 自动调参,找最优模型
作用:确保模型评估的科学性,避免 “自欺欺人”。
- 数据集划分:
-
数据预处理:
sklearn.preprocessing功能:对原始数据 “加工”,让它适合模型输入(大部分模型对数据格式、分布敏感)。
- 缺失值处理:
SimpleImputer—— 用均值、中位数或特定值填补缺失数据。 - 标准化 / 归一化:
StandardScaler(标准化,让数据均值为 0、方差为 1)、MinMaxScaler(归一化,缩放到 0-1 范围)—— 消除量纲影响(比如 “身高(厘米)” 和 “体重(公斤)” 的单位差异)。 - 编码:
OneHotEncoder(对分类特征做独热编码,比如 “颜色 = 红”→[1,0,0])、LabelEncoder(对标签做整数编码,比如 “类别 A”→0,“类别 B”→1)。
作用:数据预处理直接影响模型效果,这是 “Feature Engineering(特征工程)” 的核心工具。
- 缺失值处理:
-
特征选择:
sklearn.feature_selection功能:从众多特征中挑出 “有用” 的,剔除 “噪音” 或 “冗余” 特征。
VarianceThreshold:移除方差过小的特征(比如某特征 90% 样本都是同一个值,几乎没信息量)。SelectKBest:根据统计指标(如相关性)选择排名前 K 的特征。
作用:简化模型、减少计算量、避免过拟合。
-
模型模块
这部分是 sklearn 的 “武器库”,按任务类型划分:
-
线性模型:
sklearn.linear_model包含:
LinearRegression(线性回归,解决回归问题)、LogisticRegression(逻辑回归,解决分类问题)、Ridge(岭回归,带正则化的线性回归)等。特点:简单、解释性强,适合做 baseline(基准模型)。
-
树模型:
sklearn.tree包含:
DecisionTreeClassifier(分类决策树)、DecisionTreeRegressor(回归决策树)。特点:可解释性强,能处理非线性关系,但容易过拟合。
-
集成学习:
sklearn.ensemble包含:
RandomForestClassifier(随机森林,多个决策树的 “投票”)、GradientBoostingClassifier(梯度提升树,如 GBDT)等。特点:性能强,在竞赛和实际业务中常用,是 “大杀器”。
-
支持向量机:
sklearn.svm包含:
SVC(分类)、SVR(回归)。特点:在小样本、高维数据上表现好,但计算量大,调参复杂。
-
聚类算法:
sklearn.cluster包含:
KMeans(K 均值聚类)、DBSCAN(密度聚类)等。 -
降维算法:
sklearn.decomposition包含:
PCA(主成分分析)—— 减少特征维度,同时保留主要信息。
-
-
模型评估:
sklearn.metrics功能:提供衡量模型好坏的 “尺子”。
- 分类任务:
accuracy_score(准确率)、precision_score(精确率)、recall_score(召回率)、f1_score(F1 值)、roc_auc_score(AUC 值)等。 - 回归任务:
mean_squared_error(MSE,均方误差)、mean_absolute_error(MAE,平均绝对误差)、r2_score(R² 分数)等。 - 其他:
confusion_matrix(混淆矩阵)、classification_report(分类报告,一站式输出多个指标)。
作用:客观评价模型性能,指导模型优化。
- 分类任务:
-
流程封装:
sklearn.pipeline功能:把 “预处理→模型训练” 的步骤串成一个 “流水线”,避免重复操作和数据泄露(比如用训练集的统计量去标准化测试集)。
核心工具:
Pipeline、ColumnTransformer(对不同列用不同预处理方法)。作用:让流程更规范、代码更简洁,是工业级建模的必备工具。
-
模型持久化:
sklearn.externals.joblib(或直接用joblib)功能:把训练好的模型保存到本地,下次用的时候直接加载,不用重新训练。
核心函数:
joblib.dump(model, 'model.pkl')(保存)、joblib.load('model.pkl')(加载)。作用:方便模型部署和复用。
统一接口设计
Sklearn 的统一接口设计:所有模型 “长一个样”
不管是简单的线性回归,还是复杂的随机森林,甚至是聚类、降维模型,sklearn 都让它们遵循完全一致的调用方式。这种 “统一” 不是表面功夫,而是深入到了模型的核心逻辑中。
核心:三大基础方法
所有监督学习模型(分类、回归)都包含这三个方法:
| 方法名 | 功能 | 输入参数 | 输出结果 |
|---|---|---|---|
fit(X, y) | 训练模型:让模型从数据中 “学习” 规律(计算最优参数) | X:特征数据(二维数组,形状 [样本数,特征数]);y:标签(一维数组,形状 [样本数]) | 无(模型自身更新参数) |
predict(X) | 预测新样本:用训练好的模型对未知样本做判断 | X:新样本的特征数据(格式同训练时的 X) | 预测结果(一维数组,形状 [样本数]) |
score(X, y) | 快速评估:自动计算模型在给定数据上的性能(默认指标因任务而异) | X:特征数据;y:真实标签 | 评分(浮点数,如准确率、R² 值) |
为什么 “统一接口” 如此重要?
-
极大降低学习成本
只需要记住一套调用逻辑,就能玩转所有模型。比如:
-
用 KNN 时:
model = KNeighborsClassifier()→model.fit()→model.predict() -
换逻辑回归时:
model = LogisticRegression()→ 同样model.fit()→model.predict()不需要因为换模型而重新学习全新的调用方式。
-
-
方便对比不同模型
比如你想比较 KNN 和逻辑回归在鸢尾花数据集上的效果,代码可以这样写:
from sklearn.neighbors import KNeighborsClassifier from sklearn.linear_model import LogisticRegression# 定义两个模型 model1 = KNeighborsClassifier() model2 = LogisticRegression()# 训练(调用方式完全一样) model1.fit(X_train, y_train) model2.fit(X_train, y_train)# 评估(调用方式完全一样) print("KNN 准确率:", model1.score(X_test, y_test)) print("逻辑回归准确率:", model2.score(X_test, y_test))这种一致性让模型对比变得极其简单。
-
支持流水线与自动化
后续学习的
Pipeline(流水线)能把 “预处理 + 模型” 串起来,核心就是因为所有模型的接口统一,流水线可以用同样的逻辑调用任何模型的fit和predict。
无监督学习模型的接口
对于无监督学习(如聚类、降维),接口略有调整(因为没有标签 y),但核心思想一致:
- 训练:
fit(X)(只需要特征数据,不需要y) - 转换:
transform(X)(对数据做转换,如降维、聚类标注) - 训练 + 转换:
fit_transform(X)(等价于先fit再transform,更高效)
例如 PCA 降维:
from sklearn.decomposition import PCApca = PCA(n_components=2) # 降成2维
pca.fit(X) # 用数据学习降维规则
X_new = pca.transform(X) # 对数据做降维转换
# 等价于:X_new = pca.fit_transform(X)
案例:鸢尾花分类
分别用 KNN 和逻辑回归做分类,看看如何用 “同一套代码框架” 实现不同模型的训练与评估。
-
准备工作(导入库和数据)
首先先导入必要的模块,加载数据并划分训练集 / 测试集(这部分对所有模型都通用):
# 导入数据集模块 from sklearn.datasets import load_iris # 导入数据集划分工具 from sklearn.model_selection import train_test_split # 导入评估指标(准确率) from sklearn.metrics import accuracy_score# 加载鸢尾花数据 iris = load_iris() X = iris.data # 特征(4个特征:花萼长度、宽度,花瓣长度、宽度) y = iris.target # 标签(0、1、2 代表三种鸢尾花)# 划分训练集(70%)和测试集(30%) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42 # random_state固定划分方式,保证结果可复现 ) -
用 KNN 模型训练与评估
# 导入 KNN 分类器 from sklearn.neighbors import KNeighborsClassifier# 1. 定义模型(参数n_neighbors=3表示用最近的3个样本投票) model_knn = KNeighborsClassifier(n_neighbors=3)# 2. 训练模型(接口:fit) model_knn.fit(X_train, y_train)# 3. 预测测试集(接口:predict) y_pred_knn = model_knn.predict(X_test)# 4. 评估准确率(接口:score 或 accuracy_score) print("KNN 准确率(用score):", model_knn.score(X_test, y_test)) print("KNN 准确率(用accuracy_score):", accuracy_score(y_test, y_pred_knn))输出:
KNN 准确率(用score): 1.0 KNN 准确率(用accuracy_score): 1.0 -
用逻辑回归模型训练与评估
现在换模型,你会发现代码框架完全不变,只需要替换 “导入的模型类” 和 “模型定义” 这两行:
# 导入逻辑回归分类器 from sklearn.linear_model import LogisticRegression# 1. 定义模型(逻辑回归默认参数即可) model_lr = LogisticRegression(max_iter=200) # 增加迭代次数,确保收敛# 2. 训练模型(接口:fit,和KNN完全一样) model_lr.fit(X_train, y_train)# 3. 预测测试集(接口:predict,和KNN完全一样) y_pred_lr = model_lr.predict(X_test)# 4. 评估准确率(接口:score 或 accuracy_score,和KNN完全一样) print("逻辑回归准确率(用score):", model_lr.score(X_test, y_test)) print("逻辑回归准确率(用accuracy_score):", accuracy_score(y_test, y_pred_lr))输出:
逻辑回归准确率(用score): 1.0 逻辑回归准确率(用accuracy_score): 1.0
对比上面两段代码,除了 “模型类” 不同(KNeighborsClassifier vs LogisticRegression),其他步骤(fit/predict/score)的调用方式一模一样。
这意味着:
- 可以用同样的代码框架快速测试不同模型(比如再试试决策树、随机森林);
- 如果想比较 10 种模型的效果,只需要写一个循环,依次传入 10 个模型类即可,无需重复编写训练 / 预测代码。
典型机器学习流程
任何机器学习任务,从 “拿到数据” 到 “得到可用模型”,都遵循一套固定的流程。记住这个流程,就像掌握了做菜的 “菜谱步骤”,无论食材(数据)和菜品(任务)怎么变,步骤逻辑不变。
完整流程可分为 7 步,结合鸢尾花案例逐一拆解:
-
数据加载(获取 “原材料”)
目标:把数据加载到程序中,变成模型能识别的格式(通常是 NumPy 数组或 Pandas DataFrame)。
工具:
- 内置数据:用
sklearn.datasets中的load_xxx()或fetch_xxx()(如load_iris()); - 外部数据:用 Pandas 的
pd.read_csv()、pd.read_excel()等(更常用)。
示例:
from sklearn.datasets import load_iris iris = load_iris() X = iris.data # 特征数据(原材料) y = iris.target # 标签(告诉模型“这是什么菜”) - 内置数据:用
-
数据预处理(“清洗 / 处理食材”)
目标:让原始数据符合模型要求(比如处理缺失值、标准化、编码分类特征等)。
为什么需要:模型对数据很 “挑剔”,比如线性模型不喜欢量纲差异大的数据,树模型虽然不敏感但也怕缺失值。
常见操作:
- 缺失值处理:用
SimpleImputer填补; - 标准化 / 归一化:用
StandardScaler或MinMaxScaler; - 分类特征编码:用
OneHotEncoder或LabelEncoder。
鸢尾花案例特殊性:数据干净(无缺失、全数值、量纲一致),可跳过此步,但实际项目中这是核心步骤。
- 缺失值处理:用
-
数据集划分(“分食材”:一部分做菜,一部分尝味)
目标:把数据分成 “训练集”(供模型学习)和 “测试集”(检验模型效果)。
为什么必须分:如果用同一批数据既训练又测试,模型可能 “死记硬背” 了数据,看似效果好,实际对新数据无效(即 “过拟合”)。
工具:
sklearn.model_selection.train_test_split()示例:
from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42 # 30%做测试集,固定随机种子保证结果一致 ) -
模型训练(“做菜”:让模型学习规律)
目标:用训练集让模型 “学会” 特征和标签的关系(计算模型参数)。
工具:选择合适的模型类(如
KNeighborsClassifier),调用fit()方法。示例:
from sklearn.neighbors import KNeighborsClassifier model = KNeighborsClassifier(n_neighbors=3) # 选模型(选厨具) model.fit(X_train, y_train) # 训练(开火做菜) -
模型预测(“试做”:用模型判断新数据)
目标:用训练好的模型对测试集(或新数据)做预测,得到预测结果。
工具:调用模型的
predict()方法。示例:
y_pred = model.predict(X_test) # 用测试集特征预测标签 -
模型评估(“尝味”:判断模型好坏)
目标:对比预测结果(
y_pred)和真实标签(y_test),用指标衡量模型性能。工具:
sklearn.metrics中的评估函数(如分类用accuracy_score,回归用mean_squared_error)。示例:
from sklearn.metrics import accuracy_score accuracy = accuracy_score(y_test, y_pred) print(f"模型准确率:{accuracy:.2f}") # 输出:模型准确率:0.98 -
模型保存(“存菜”:复用模型)
目标:把训练好的模型保存到本地,下次用的时候直接加载,不用重新训练。
工具:
joblib.dump()和joblib.load()示例:
import joblib joblib.dump(model, "iris_knn_model.pkl") # 保存模型 loaded_model = joblib.load("iris_knn_model.pkl") # 加载模型,可直接用于预测
这个 7 步流程适用于所有机器学习任务:
- 分类(如垃圾邮件识别)、回归(如房价预测)、聚类(如客户分群)都离不开这个框架;
- 区别仅在于 “模型选择”(第 4 步)和 “评估指标”(第 6 步)—— 比如回归用 MSE 而不是准确率。
实战:Iris 鸢尾花分类
鸢尾花数据集是机器学习入门的 “Hello World”,包含 3 种鸢尾花(标签),每种花有 4 个特征(花萼长度、花萼宽度、花瓣长度、花瓣宽度)。我们的任务是:用这些特征预测鸢尾花的种类(分类任务)。
完整代码:
# 1. 导入需要的模块
from sklearn.datasets import load_iris # 数据加载
from sklearn.model_selection import train_test_split # 数据集划分
from sklearn.neighbors import KNeighborsClassifier # KNN模型
from sklearn.metrics import accuracy_score # 评估指标# 2. 加载数据
iris = load_iris()
X = iris.data # 特征:shape=(150, 4),150个样本,4个特征
y = iris.target # 标签:shape=(150,),0/1/2分别代表三种鸢尾花# 3. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42 # 30%数据作为测试集,固定随机种子
)# 4. 初始化模型(KNN分类器,参数n_neighbors=3)
model = KNeighborsClassifier(n_neighbors=3)# 5. 训练模型(用训练集的特征和标签)
model.fit(X_train, y_train)# 6. 用训练好的模型预测测试集
y_pred = model.predict(X_test)# 7. 评估模型性能(对比预测值和真实值)
accuracy = accuracy_score(y_test, y_pred)
print(f"模型准确率:{accuracy:.2f}") # 输出:模型准确率:0.98# 8. 查看部分预测结果(直观对比)
print("预测标签:", y_pred[:10]) # 前10个测试样本的预测结果
print("真实标签:", y_test[:10]) # 前10个测试样本的真实结果
输出:
模型准确率:1.00
预测标签: [1 0 2 1 1 0 1 2 1 1]
真实标签: [1 0 2 1 1 0 1 2 1 1]
每一步的意义
-
导入模块
这里用到了 4 个核心模块:
load_iris:从datasets模块加载数据;train_test_split:从model_selection模块划分数据集;KNeighborsClassifier:从neighbors模块选择 KNN 模型;accuracy_score:从metrics模块评估准确率。
-
加载数据
iris = load_iris()返回一个 “字典 - like” 对象,包含数据和元信息;X = iris.data:特征数据,是一个二维数组(每行一个样本,每列一个特征);y = iris.target:标签数据,是一个一维数组(每个元素对应样本的类别)。
可以打印看看数据格式:
print("特征示例:", X[:3]) # 前3个样本的特征 print("标签示例:", y[:3]) # 前3个样本的标签输出:
特征示例: [[5.1 3.5 1.4 0.2][4.9 3. 1.4 0.2][4.7 3.2 1.3 0.2]] 标签示例: [0 0 0] # 前3个样本都是第0类鸢尾花 -
划分训练集和测试集
train_test_split(X, y, test_size=0.3):把 X 和 y 按 7:3 的比例拆分;random_state=42:固定随机数种子,确保每次运行划分结果相同(方便复现);- 拆分后得到 4 个变量:
X_train:训练集特征(供模型学习);y_train:训练集标签(模型学习的 “答案”);X_test:测试集特征(检验模型的新数据);y_test:测试集标签(判断模型预测是否正确的 “标准答案”)。
-
初始化模型
KNeighborsClassifier(n_neighbors=3):创建一个 KNN 分类器,n_neighbors=3是核心参数(表示 “用最近的 3 个邻居的类别投票决定当前样本的类别”)。可以理解为:你想用水壶烧水,先选一个 “水壶”(模型),并设定 “火力大小”(参数)。
-
训练模型(fit)
model.fit(X_train, y_train):模型通过训练集 “学习” 特征和标签的关系。对 KNN 来说,
fit过程其实是 “记住所有训练样本的特征和标签”(因为 KNN 是 “惰性学习”,训练时不计算参数,预测时才找最近邻);对逻辑回归等 “积极学习” 模型,fit会计算出最优参数(如权重系数)。 -
预测(predict)
y_pred = model.predict(X_test):用训练好的模型对测试集特征做预测,得到预测标签。对 KNN 来说,这个过程是:对每个测试样本,在训练集中找最近的 3 个样本,看这 3 个样本多数属于哪类,就预测为哪类。
-
评估(accuracy_score)
accuracy_score(y_test, y_pred):计算 “准确率”(正确预测的样本数 ÷ 总样本数)。 -
对比预测结果
打印前 10 个样本的预测值和真实值,能直观看到模型的表现(这里前 10 个全对)。
fit /predict/score 工作机制
模型到底在做什么?
以 KNN 和逻辑回归这两个典型模型为例,拆解这三个方法的底层逻辑(不同模型的细节有差异,但核心流程一致)。
-
fit(X, y):模型 “学习” 的过程fit是模型的 “训练阶段”,核心任务是:从训练数据(X, y)中学习规律,计算出模型的核心参数。-
对 KNN 模型:
KNN 是 “惰性学习”(lazy learner),
fit过程非常简单 —— 它不计算任何复杂参数,只是把训练集的特征(X_train)和标签(y_train)“记下来”(存储在模型内部),为后续predict做准备。可以理解为:老师把课本(训练数据)给学生,学生先把课本存起来,暂时不做笔记。
-
对逻辑回归模型:
逻辑回归是 “积极学习”(eager learner),
fit过程会通过数学计算(梯度下降法)优化模型参数(比如每个特征的权重w和偏置b),最终得到一组能让 “预测值尽可能接近真实标签” 的参数。可以理解为:老师给课本,学生不仅存起来,还会提炼出公式(参数),方便以后快速答题。
-
共性:无论哪种模型,
fit之后,模型内部都会存储 “用于预测的关键信息”(KNN 存数据,逻辑回归存参数)。
-
-
predict(X):模型 “判断” 的过程predict是 “预测阶段”,核心任务是:用fit阶段学到的信息,对新样本(X)做出判断。-
对 KNN 模型:
当输入新样本
X_test时,KNN 会做三件事:-
计算
X_test中每个样本与训练集X_train中所有样本的距离(如欧氏距离); -
为每个样本找出距离最近的
n_neighbors个训练样本(比如 n=3 时找 3 个最近邻); -
对这 3 个邻居的标签做 “投票”,出现次数最多的标签就是该样本的预测结果。
例:3 个邻居的标签是 [1,1,2],则预测结果为 1。
-
-
对逻辑回归模型:
逻辑回归会用
fit学到的权重w和偏置b,对新样本计算 “概率得分”,再根据阈值(通常 0.5)判断类别:- 计算线性组合:
z = w1*x1 + w2*x2 + ... + b(x 是新样本的特征); - 用 sigmoid 函数把
z转换为概率:p = 1/(1+e^(-z))(p 是样本属于 “正类” 的概率); - 若
p ≥ 0.5,预测为 1;否则预测为 0(多分类时逻辑类似,用 softmax 函数)。
- 计算线性组合:
-
共性:
predict必须在fit之后调用(否则模型没学到任何信息,无法预测),且输入的X格式必须和fit时的X_train一致(比如特征数量、数据类型)。
-
-
score(X, y):模型 “打分” 的过程score是 “快速评估阶段”,核心任务是:自动计算模型在数据(X, y)上的性能,返回一个分数。-
底层逻辑:
score本质是 “懒人函数”,它会先调用predict(X)得到预测结果y_pred,再用内置的评估指标对比y_pred和真实标签y,最后返回分数。即:
def score(X, y):y_pred = self.predict(X)return 评估指标(y, y_pred) # 不同模型的评估指标不同 -
不同模型的默认指标:
- 分类模型(如 KNN、逻辑回归):默认用准确率(accuracy)(正确预测数 / 总样本数);
- 回归模型(如线性回归):默认用R² 分数(越接近 1 越好,表示模型解释数据的能力越强)。
-
示例验证:
在鸢尾花案例中,
model.score(X_test, y_test)和accuracy_score(y_test, model.predict(X_test))结果完全一致,因为它们本质是同一过程。
-
关键事项
fit只能用训练集:fit(X_train, y_train)是正确用法,若用测试集fit,模型会 “偷看答案”,导致评估结果失真(过拟合)。predict和score可用测试集或新数据:这两个方法是用来检验模型对 “未知数据” 的表现,所以输入应该是模型没见过的数据(X_test 或新样本)。- 不要依赖
score的默认指标:比如分类任务中,准确率在 “样本不平衡” 时会骗人(比如 99 个负样本 1 个正样本,全预测负样本也有 99% 准确率),此时需要用metrics模块的其他指标(如精确率、召回率)。
思考
-
为什么我们需要划分训练集和测试集?
答:核心是为了评估模型的泛化能力(对新数据的预测能力)。
- 如果不划分,直接用全部数据训练并评估,模型可能 “死记硬背” 了所有数据的特征和标签(过拟合),看似准确率很高,但对没见过的新数据预测效果会很差。
- 训练集的作用是让模型 “学习规律”,测试集的作用是模拟 “新数据”,检验模型是否真的学会了规律,而不是单纯记忆数据。
-
如果不设置
random_state,每次结果都不同,会带来什么问题?答:
random_state的作用是固定随机数生成器的种子,确保train_test_split每次划分的训练集 / 测试集是一样的。- 不设置时,每次运行代码会得到不同的训练集和测试集,导致模型训练和评估的结果不稳定(比如这次准确率 98%,下次 92%)。
- 问题:无法客观对比不同模型或参数的效果(因为数据划分变了,结果差异可能不是模型导致的),也难以复现实验结果(别人跑你的代码可能得到完全不同的结论)。
-
如果将
n_neighbors从 3 改为 1,会发生什么?为什么?答:
n_neighbors是 KNN 的核心参数,代表 “投票的邻居数量”。- 当
n_neighbors=1时,模型会只根据距离最近的 1 个样本的标签做预测(“一票定音”)。 - 可能的结果:训练集准确率会更高(甚至 100%,因为每个样本的最近邻是自己),但测试集准确率可能下降(容易受噪声数据影响,泛化能力变差)。
- 原因:K 值太小,模型容易 “过拟合”(对训练数据太敏感,把噪声当成规律);K 值太大,模型可能 “欠拟合”(过度平滑,丢失关键规律)。
- 当
-
打印分类报告(更详细的评估)
分类报告(
classification_report)会同时输出准确率、精确率、召回率、F1 值,适合多分类任务:from sklearn.metrics import classification_report# 对逻辑回归的预测结果生成报告 print("逻辑回归分类报告:") print(classification_report(y_test, y_pred_lr))输出结果:
逻辑回归分类报告:precision recall f1-score support0 1.00 1.00 1.00 191 1.00 1.00 1.00 132 1.00 1.00 1.00 13accuracy 1.00 45macro avg 1.00 1.00 1.00 45 weighted avg 1.00 1.00 1.00 45解释:每个类别(0/1/2)的精确率、召回率、F1 值都是 1.0,说明逻辑回归在测试集上所有样本都预测正确。
