ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

Scikit-learn入门教程:从环境搭建到模型评估的机器学习全流程

Scikit-learn入门教程:从环境搭建到模型评估的机器学习全流程 最近身边不少朋友开始学机器学习第一个问题基本都是“我从哪个库入手”。我的回答永远一致先别碰框架老老实实把Scikit-learn学明白。这个库在机器学习生态里的地位相当于螺丝刀在工具箱里的地位干不了所有活但几乎所有活都离不开它。尤其对新手来说Scikit-learn能帮你把分类、回归、聚类、降维、数据预处理这些机器学习核心流程全部跑通而且API设计极其统一学一个模型等于会了十几个模型。这篇教程我按自己带新人踩坑的经验来写目标是让一个完全没接触过机器学习、只有一点点Python基础的人也能在半天内跑通第一个项目并且明白每一步到底在做什么。文中的代码我都会贴出可直接运行的版本用的数据集也是Scikit-learn自带的不需要额外下载任何数据文件。1. 先搞清楚Scikit-learn能做什么以及它凭什么成为入门首选1.1 它解决的到底是什么问题很多人把“机器学习”想象得很玄其实剥开看就四件事准备数据、训练模型、评估效果、用模型做预测。Scikit-learn的作用就是把这四个环节的工具全部打包好并且接口风格高度一致。举个例子你想让电脑学会“认识猫”。本质上你要做的是收集一堆标注好的图片特征比如毛发颜色、耳朵形状、体型大小把这些特征整理成表格然后让算法从表格中总结出一套规律——什么样的特征组合更像猫。有了规律之后来一张新图片提取出同样的特征喂给这套规律模型输出“猫”或“不是猫”。Scikit-learn就负责“让算法总结规律”和“用规律做预测”这两件事前期的数据收集和特征整理通常配合pandas和numpy来做。它覆盖的算法非常全线性回归、逻辑回归、决策树、随机森林、支持向量机、K近邻、K均值聚类、主成分分析等等只要是传统机器学习范畴的经典算法基本都实现了。深度学习相关的内容不在它的范围内那是PyTorch和TensorFlow的主场。1.2 为什么新手第一站就选它我见过很多人一上来就学TensorFlow结果被计算图、张量、GPU配置这些概念劝退。Scikit-learn最大的优势就是统一API——所有模型都长一个样都要经历fit、predict、score这三个阶段。这意味着你今天学会了用K近邻做分类明天换成随机森林只需要改一行引入模型的代码后面几乎不用动。它的官方文档也是我在所有开源库里见过最友好的每个算法都有完整案例每一步都能看懂。相比读论文或者啃源码新手用Scikit-learn学到的不是某个算法的数学推导而是机器学习的完整工作流。这个工作流思维恰恰是后面学任何框架都通用的底层能力。另外Scikit-learn的代码风格非常Pythonic底层用Cython做了大量优化训练小规模数据的速度相当快。你在笔记本上跑一个随机森林可能几秒钟就出结果这种即时反馈对新手建立信心特别重要。2. 环境准备从零搭建一套能跑通的Python机器学习环境2.1 用Anaconda还是纯pip我推荐后者关于安装方式网上一搜全是“装Anaconda一键搞定”。Anaconda确实省事但它自带的Python环境和包版本往往比较旧而且整包体积好几个G里面大部分工具你根本用不到。我自己现在的做法是直接用系统Python加上venv虚拟环境再用pip装包。这种方式更干净排查问题也更容易。如果你是在Windows上我建议装一个稳定版Python3.9到3.12之间都行别追最新版有些库的预编译包还没跟上安装时记得勾选“Add Python to PATH”。然后在终端里执行mkdir ml_project cd ml_project python -m venv venvWindows下激活虚拟环境venv\Scripts\activatemacOS或Linux下激活source venv/bin/activate看到命令行前面出现(venv)字样说明虚拟环境已经激活接下来装的包都只在这个项目里生效不会污染全局环境。2.2 快速安装并验证5分钟确认全家桶是否工作在激活的虚拟环境里直接一条命令装齐入门四件套pip install numpy pandas matplotlib scikit-learn装完千万别急着关命令行先做一次验证确认所有包都能正常导入并且版本兼容python -c import numpy, pandas, matplotlib, sklearn; print(numpy.__version__); print(pandas.__version__); print(matplotlib.__version__); print(sklearn.__version__)这四个包的关系我习惯这么理解numpy管多维数组pandas管表格数据matplotlib管可视化scikit-learn管建模。前三个可以看成是给Scikit-learn打杂的一个机器学习项目里基本离不开它们。再跑一段最简单的测试代码加载Scikit-learn自带的鸢尾花数据集确认数据能读出来from sklearn.datasets import load_iris iris load_iris() print(iris.data.shape) print(iris.target_names) print(iris.feature_names)如果输出结果是(150, 4)和[setosa versicolor virginica]以及四个特征名说明环境完全没问题可以开始写真正的项目了。注意常见的一个坑是Python版本太高导致Scikit-learn安装失败。如果pip install报错优先检查Python版本是否为3.12或以下再检查是否有网络代理干扰。实在不行换成Python 3.10这个版本兼容性最好。3. 第一个完整项目用鸢尾花数据走通机器学习全流程3.1 加载数据别急着写模型先认识你的数据鸢尾花数据集是机器学习界的Hello World包含150条样本每条有4个特征花瓣长度、花瓣宽度、花萼长度、花萼宽度标签是三种鸢尾花品种。这个数据集干净、量小、分类界限清晰非常适合新手跑通流程。先加载并观察数据的形式from sklearn.datasets import load_iris import pandas as pd iris load_iris() df pd.DataFrame(iris.data, columnsiris.feature_names) df[target] iris.target print(df.head()) print(df[target].value_counts())为什么先把数据转成DataFrame因为pandas的表格形式更接近真实世界的数据形态你能直观看到每一列的含义和取值分布。真实项目中数据乱七八糟CSV、Excel、数据库导出的都有第一步永远是“看懂数据长什么样”而不是马上敲模型代码。我观察数据时一般问三个问题有几行几列、每列是数值还是类别、目标列有多少种取值、分布是否均衡。这三个问题直接决定后面选什么模型、需不需要做数据增强或类别平衡处理。3.2 数据拆分训练集和测试集不能乱切模型训练前必须把数据拆成训练集和测试集。训练集用来让模型学习规律测试集用来检验模型学得怎么样。如果拿同一份数据又训练又测试就相当于考试前把答案给考生看了一眼分数再高也没有意义。Scikit-learn的train_test_split就是干这个的from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test train_test_split( iris.data, iris.target, test_size0.2, random_state42, stratifyiris.target )这里test_size0.2表示留出20%的数据做测试stratifyiris.target表示按标签比例分层抽样保证训练集和测试集里三种花的比例跟原始数据一致。random_state42是个随便写的整数作用是固定随机数生成过程这样你每次运行代码得到的拆分结果都一样方便复现实验结果。注意stratify这个参数很多人会漏掉在分类任务里尤其重要。假设原始数据里猫占90%、狗占10%如果不分层随机拆分可能测试集里全是猫模型训练时没见过几条狗的数据测试时遇到狗自然全错。这个坑我在实际项目中踩过不止一次。3.3 训练模型三行代码跑出一个基线结果数据准备好之后训练一个K近邻分类器只需要三步from sklearn.neighbors import KNeighborsClassifier model KNeighborsClassifier(n_neighbors3) model.fit(X_train, y_train) print(model.score(X_test, y_test))就这三行一个能用的分类器已经诞生了。score方法内部会自动做预测并与真实标签比对返回准确率。在鸢尾花数据集上通常能得到0.93到1.0的准确率。K近邻的原理很直白一个新样本进来找到训练集里离它最近的K个样本这K个样本中哪个类别最多就预测成哪一类。n_neighbors3就是只看最近的3个邻居。你可以试试把这个参数改成1、5、10观察准确率怎么变这是感受模型复杂度与效果关系最直观的一个实验。跑完你会注意到我们完全没做标准化却也能得到高分。这是因为鸢尾花数据本身四个特征的量级差不多但真实数据里如果身高的数值是厘米、体重是千克、年龄是岁这三个特征直接拼在一起算距离身高就会主导结果模型基本学不到其他特征的信息。这个问题的解法下一部分会详细说。4. 核心概念拆解fit、predict、transform到底在干嘛4.1 fit是什么从“认猫”这个类比说开去Scikit-learn里面所有的模型和数据转换器都有fit方法。fit的中文意思接近“拟合”你可以把它理解成“让模型学习训练数据里的规律”的动作。我经常用“认识猫”的例子给学生讲你小时候看了一百张猫的图片脑子里慢慢形成了对猫的判断标准这个过程就是fit。训练好的模型里存下来的不是那些图片本身而是从图片特征里提取出来的规律参数。K近邻稍微特殊一点它没有显式的参数fit之后只是把训练数据原封不动存起来真正计算发生在predict的时候所以它被叫做“惰性学习”算法。data_transform也一样比如StandardScaler的fit是在计算训练集每一列的均值和标准差并把这两个数值存在scaler对象里。注意计算出的均值和标准差只来自训练集测试集和未来的新数据都沿用这套参数去做标准化不能重新计算。这是防止数据泄露的关键。4.2 predict和score模型出来之后怎么用fit完成之后模型进入可用状态。predict就是喂新数据、拿预测结果predictions model.predict(X_test) print(predictions[:10]) print(y_test[:10])用predictions和y_test做对比就能人工检查模型预测得对不对。score则是一个快捷方法直接返回准确率内部相当于先predict再与真实标签比对算平均值。如果你用的是逻辑回归这样的概率模型还能用predict_proba拿到每个类别的概率值。这个接口在真实业务里特别常用比如银行风控系统最后不是简单输出“欺诈”或“正常”而是输出一个欺诈概率再根据概率阈值决定是否触发人工审核。这也是为什么逻辑回归常被称为实时评分系统的“主引擎”之一。4.3 为什么明明代码能跑准确率却不行很多人跑到这一步会来问我老师我代码跟你的完全一样为什么准确率只有0.3这种情况我碰到太多次了十有八九是下面几种原因第一没有随机种子且数据量很小。train_test_split默认是随机拆分的对150条这种小数据不同拆分方式可能导致结果波动很大。解决办法就是在train_test_split和模型中都固定random_state。第二分类目标是字符串而不是数字。Scikit-learn要求y是整数编码如果你直接塞一列“cat”“dog”进去很多模型会报错或者把字符串当成类别编号。解决办法是用LabelEncoder做一次编码。第三模型没fit或者fit的是数据转换器而不是模型。我见过有人把StandardScaler当模型来fit然后拿score去评估结果肯定是错的因为scaler根本没有score方法。这些问题的共性就是没有理解fit的对象是谁、训练数据和测试数据有没有混用。所以我一直强调学Scikit-learn前期不用背API先把自己做过的每组代码里“谁在fit、谁在transform、谁在predict”搞清楚比什么都重要。5. 数据预处理与特征工程新手最该花时间的地方5.1 缺失值处理不是删掉就完事真实数据集基本没有perfect的缺失值处理是第一道坎。最省事的方法是整行删除但只要数据量不大删一行可能就丢掉了宝贵的信息。更稳的做法是填充Scikit-learn提供了SimpleImputerfrom sklearn.impute import SimpleImputer import numpy as np imputer SimpleImputer(strategymedian) X_filled imputer.fit_transform(X_with_missing)strategy可以选mean、median、most_frequent、constant。我一般优先用median而不是mean因为mean对异常值敏感一个极端值就能把平均值拉得很远median则稳健得多。要记住的是imputer只能拿训练集的数据去fit然后transform训练集和测试集。如果直接用全量数据fit后再拆分测试集的信息已经渗透到填充值里了评估结果会虚高这属于典型的数据泄露。5.2 标准化与归一化影响巨大但极易忽略标准化和归一化是特征缩放的两类做法。标准化StandardScaler把数据变成均值为0、标准差为1归一化MinMaxScaler把数据缩放到0到1之间。新手最容易犯的错误是拿到数据直接建模完全不考虑特征量级问题。K近邻、支持向量机、逻辑回归、主成分分析这些基于距离或梯度的算法对特征尺度非常敏感。比如房价预测里“面积”是80到200的数值“建造年份”是1900到2020的数值两者直接算欧几里得距离面积几乎不起作用。下面这段代码演示了标准化的标准用法from sklearn.preprocessing import StandardScaler scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test)注意测试集只能调用transform不能重新fit。scaler用训练集算出的均值和标准差已经是全部信息测试集再说自己是新来数据里的合法成员但规则要用老规矩。什么时候不需要标准化决策树和随机森林这类树模型完全不受量纲影响因为它们做的是特征的切分判断而不是计算距离所以可以不做标准化。反过来线性回归如果不做正则化特征量级差异大时正则化项会把小量级特征的特征系数压得特别狠导致模型偏向大量级特征这时候标准化就很有必要。5.3 类别特征编码LabelEncoder和OneHotEncoder的选择很多原始数据里含有类别文字比如颜色“红”“绿”“蓝”城市“北京”“上海”“广州”。这类数据不能直接喂给模型需要编码成数字。新手最容易踩的坑是把全部分类变量统一用LabelEncoder编码成0、1、2。问题是LabelEncoder编码出来的是有序整数模型会误以为1比0大、2比1大这在不具有内在顺序的分类变量里会产生虚假的排序关系。比如颜色“红”编码成1“蓝”编码成2模型就会认为“蓝”在数值上比“红”大这毫无意义。正确的做法通常是对无序类别特征用OneHotEncoder或者直接用pandas的get_dummiesimport pandas as pd df_encoded pd.get_dummies(df, columns[color], drop_firstTrue)OneHotEncoder把“红”“绿”“蓝”变成三个二值特征是不是红、是不是绿、是不是蓝。损失的是数据中原本不存在的顺序信息换来的是模型不会误用顺序关系。对有序类别特征比如“低”“中”“高”可以用OrdinalEncoder或者手动映射成0、1、2因为这时候顺序确实有意义。实操心得真实项目里我强烈建议用Pipeline把标准化、编码、建模串在一起。Pipeline的好处是能把数据预处理的参数和模型参数作为一个整体来调优Cross-validation时也不会发生数据泄露因为每一折都会在训练子集上重新fit预处理步骤。新手可能一时体会不到但等你开始用GridSearchCV调参时就会明白Pipeline有多省心。6. 模型选择实用指南KNN、逻辑回归与随机森林6.1 KNN最适合入门的模型K近邻是新手第一个模型因为它几乎不需要训练原理就是“物以类聚”。但KNN有两个致命短板一是预测时需要计算新样本与所有训练样本的距离数据量大时非常慢二是它对特征缩放非常敏感不做标准化的KNN在真实数据上表现通常很差。实际使用中K值的选择可以通过交叉验证来确定。K太小容易过拟合K太大模型过于平滑容易忽略局部规律。我自己在项目里一般从3、5、7、9这几个值里挑配合交叉验证选最好的。KNN适合小规模数据、低维特征、类别边界比较清晰的场景比如手写数字识别的小demo、个性化推荐的初始版本。大规模高维场景就别用KNN了不光慢距离在高维空间里也容易失效。6.2 逻辑回归实时评分系统的主引擎很多人以为逻辑回归只能做二分类其实它做多分类也行只是默认的二分类场景用得最多。逻辑回归输出的不是类别而是属于正类的概率这个特性让它在金融风控、广告点击率预估、推荐排序这些需要概率分数的场景里成为主力。逻辑回归的核心是在线性回归基础上套了一个Sigmoid函数把输出压缩到0到1之间。它的训练速度快、推理速度更快模型内存占用小所以非常适合做实时评分系统。在CTR预估这类高维稀疏特征场景里即使深度学习大行其道的今天逻辑回归依然有大量应用。代码同样很简单from sklearn.linear_model import LogisticRegression logreg LogisticRegression(max_iter1000) logreg.fit(X_train, y_train) print(logreg.score(X_test, y_test)) print(logreg.predict_proba(X_test[:5]))一个我踩过的坑是忘记调max_iter逻辑回归默认迭代次数是100有些数据集上没收敛就停了控制台会弹出ConvergenceWarning虽然代码没报错但模型效果已经不对了。训练前把max_iter设成1000或更高是最省事的做法。6.3 决策树与随机森林效果与可解释性的平衡决策树最大的优点是透明可解释。训练完可以把整棵树画出来每一步怎么判断一目了然这在医疗、金融等需要向用户解释原因的行业特别重要。缺点是单棵决策树容易过拟合稍微动一点数据树的结构可能完全变样。随机森林就是批量训练一大堆决策树再投票表决通过引入随机性来降低方差效果比单棵树稳得多几乎不调参也能得到不错的结果from sklearn.ensemble import RandomForestClassifier rf RandomForestClassifier(n_estimators100, random_state42) rf.fit(X_train, y_train) print(rf.score(X_test, y_test))n_estimators是树的数量100是常用默认值。随机森林里有几个重要的调参方向max_depth控制单棵树的深度限制过拟合min_samples_leaf控制叶子节点的最少样本数值越大模型越保守。新手阶段不需要深究直接跑默认效果已经能碾压很多模型。注意树模型不需要特征标准化但它们对特征重要性有天然的“偏见”取值多的特征容易被选中。如果你发现随机森林给出的特征重要性完全不符合业务直觉可以用permutation_importance做一次无偏的重要性评估这个函数在很多比赛里帮我发现了关键特征。7. 模型评估准确率不是唯一指标7.1 混淆矩阵比准确率更诚实准确率是最常见的评估指标但在类别不平衡的数据集上会骗人。举个例子100个样本里只有5个异常模型把所有样本都预测成正常准确率是95%看着很高但异常一个都没抓出来。这种模型在风控里约等于废物。这时候要看的是一张混淆矩阵from sklearn.metrics import confusion_matrix, classification_report cm confusion_matrix(y_test, model.predict(X_test)) print(cm) print(classification_report(y_test, model.predict(X_test)))混淆矩阵的四个格子分别是真正例、假正例、真反例、假反例。从这个矩阵里能算出精确率precision和召回率recall。精确率是“预测为正类的样本里有多少是真正类”召回率是“真实正类样本里有多少被找了出来”。风控场景更看重召回率因为漏掉一个欺诈交易损失巨大推荐系统则更看重精确率因为推荐了10个内容用户一个都不点体验会很差。7.2 交叉验证别让你的评估结果靠运气train_test_split把数据分一次就训练一次结果受随机性影响很大。更稳的做法是k折交叉验证把数据分成K份每次拿K-1份训练、1份验证轮流K次最后把K次结果取平均from sklearn.model_selection import cross_val_score scores cross_val_score(rf, iris.data, iris.target, cv5) print(scores) print(scores.mean())cv5是常用设置。交叉验证的价值在于你得到的是模型在5种不同数据划分下的平均表现比单次划分的结果可靠得多。GridSearchCV调参的原理就是配合交叉验证来做——在参数网格中尝试每一组参数每组都跑K折交叉验证选出平均得分最高的一组。Newer用户一定要建立这个习惯任何模型评估都不该依赖单次划分的分数交叉验证才是默认选项。8. 新手最常踩的坑安装、维度、过拟合一次说清8.1 安装报错怎么办安装Scikit-learn最常见的报错是pip install时找不到匹配版本或者编译过程中各种依赖报错。先确认Python版本Scikit-learn新版本一般只支持3.9以上过旧的版本可能装不上。另一个经常碰到的坑是电脑里装了多个Python解释器pip和python来自不同环境装完导入却失败。这种问题推荐用python -m pip install来装确保装的包对应当前解释器。8.2 维度不匹配报错很多新手遇到的报错长这样Expected 2D array, got 1D array instead。原因是模型要求输入是二维数组行是样本、列是特征你传进去的却是一维数组。解决办法是给数据增加一个维度import numpy as np single_sample np.array([[5.1, 3.5, 1.4, 0.2]]) model.predict(single_sample)这种情况尤其在只预测一条新样本时最容易发生。另外用pandas处理完数据后要确认X是DataFrame或二维NumPy数组别把Series传进去当特征数据。8.3 模型过拟合或欠拟合怎么调过拟合的表现是训练集准确率很高、测试集准确率暴跌。常见原因有模型太复杂、特征太多、训练数据太少。解决办法是正则化、剪枝、增大数据集、降低模型复杂度。以决策树为例限制max_depth、提高min_samples_leaf都能有效抑制过拟合。欠拟合则是模型太简单训练集和测试集准确率都不高。解决办法反过来增加特征、换更强的模型、降低正则化强度。判断是过拟合还是欠拟合有个简单经验先看训练集得分如果训练集都学不好就是欠拟合训练集学得很好、测试集很差就是过拟合。8.4 常见问题速查表问题现象可能原因解决方案安装时报红字找不到包Python版本不匹配或网络问题换Python 3.10用镜像源重试Expected 2D array报错特征维度不足用reshape调整数组形状准确率只有0.3左右随机种子未固定、数据泄露固定random_state检查预处理只用训练集fit训练集分数高测试集分数低过拟合限制模型复杂度、数据增强、交叉验证逻辑回归收敛警告迭代次数不足max_iter调大到1000以上字符串标签报错需要数值标签用LabelEncoder对y编码最后再说一个我觉得对新手特别值得养成的习惯每次跑实验都把自己用到的参数、随机种子、数据版本、最后得分记录下来。不要觉得这是多余的我后来做项目调模型最痛苦的就是想复现一周前跑出的好结果却完全不记得当时是什么参数。这个习惯从入门第一天开始建立你后面会感谢自己。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表