ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Python机器学习入门:从环境搭建到K近邻分类实战

Python机器学习入门:从环境搭建到K近邻分类实战 最近后台收到不少私信都是同一个问题“我想学机器学习但完全不知道从哪下手网上教程又多又乱到底该先干什么”说实话我特别能理解这种焦虑。Python、机器学习这两个词现在简直成了技术圈的热门标签好像不学就落伍了。但真正动手时光是装环境就能劝退一批人更别提那些抽象的概念和一堆讲得云里雾里的算法推导了。我自己的学习路径也是摸着石头过河踩了无数坑才把这条线捋顺。今天这篇文章我就把自己从零开始搭建Python机器学习基础的过程、核心思路和实操中常踩的坑一次性讲清楚。不讲那种绕来绕去的理论推导重点放在“怎么开始”以及“怎么把一个最小可用项目跑通”上。内容适合刚接触Python、想学机器学习的同学或者已经有点基础但总感觉知识点散成一盘沙的朋友——你缺的不是某个算法而是一条清晰的实践主线。1. 环境搭建先解决“跑不起来”的问题1.1 为什么要用Anaconda而不是直接装Python很多人第一步就卡在环境上。你在官网下载Python装完开个命令行输入python能弹出交互界面就以为万事大吉了。真开始写代码的时候import numpy报错、import sklearn又报错一个一个装依赖装到怀疑人生。我刚开始也是这么折腾的后来直接转换思路别再用裸Python改用Anaconda这个开箱即用的发行版。Anaconda自带Python解释器同时预装了几百个数据分析和机器学习的核心库包括numpy、pandas、scikit-learn、matplotlib、jupyter等等。装好之后几乎所有机器学习入门阶段要用到的工具都齐了。你可能会问那为什么不直接用纯Python加pip一个个装因为依赖关系太容易打架。比如某个库要求numpy版本不低于1.20另一个库却只兼容1.18用pip装到后面整个环境就是一团乱麻。Anaconda用conda包管理器解决这个问题它会自动帮你分析依赖冲突选择一个能兼容的版本组合。这就像你装修房子与其自己买一堆零散的建材还要考虑螺丝型号匹不匹配不如直接拎包入住一个精装房。如果你已经有了Python但不想换发行版那至少用虚拟环境。在项目目录下执行python -m venv venv然后激活它再装依赖也能把项目之间的包隔离开。不过对于纯新手我仍然建议直接用Anaconda省心。1.2 编辑器选VS Code还是PyCharm怎么配置编辑器这块我两种都用过各有适用场景。PyCharm功能全智能提示比VS Code强调试器也很直观适合写大型工程。但启动速度慢内存吃得厉害我笔记本上开个PyCharm风扇就开始狂转。VS Code轻量配合Python插件体验非常接近而且对Jupyter Notebook支持得也不错。如果你是初学者我建议用VS Code门槛低遇到问题搜资料也方便。配置就三步。第一步装Python插件第二步打开命令面板CtrlShiftP输入“Python: Select Interpreter”把解释器指向Anaconda里那个python.exe第三步在终端输入conda activate确认环境没问题就行。这里有个很容易踩的坑明明在终端能import pandas但在VS Code里运行脚本就是ModuleNotFoundError。原因基本就是解释器没切换对VS Code默认用了系统自带Python。解决方式就是在右下角状态栏点一下Python版本号重新选一遍。1.3 搭建Minimal环境需要哪些包用Anaconda的话默认就带了一整套但你得知道自己日常在用什么。我习惯创建一个独立的conda环境不污染base环境。命令很简单conda create -n ml_env python3.10 conda activate ml_env conda install numpy pandas matplotlib scikit-learn jupyter这几样就是机器学习的“四大件”。numpy负责数组运算pandas负责表格数据处理matplotlib负责画图scikit-learn负责模型训练和评估。装完之后跑一下python -c import numpy, pandas, sklearn, matplotlib; print(OK)不报错就说明环境没问题了。后面所有实践代码都跑在这个环境里。2. 核心概念拆解从三个小问题入门2.1 机器学习到底在干什么先别急着看公式。我用人话解释机器学习的本质是“从数据中自动总结规律”然后用这个规律去预测新数据。传统的写程序思路是“规则决定结果”比如你写if x 18: 成年人这是你自己定的规则。机器学习反过来你给程序一堆“x值”和“对应的答案”让它自己找一个函数f使得f(x)能尽量正确地输出答案。这个找函数的过程叫“训练”训练出来的f就是我们说的“模型”。类比成学生考试更容易理解。你给学生一本习题册里面有题目和标准答案学生通过反复做题总结出解题方法最后参加高考面对新题目也能答对。习题册就是训练数据标准答案就是标签总结出的解题方法就是模型。机器学习里把“习题册”叫训练集把“高考题”叫测试集。这里还要理解两个最核心的词特征和标签。特征是你用来判断一件事的所有信息。比如判断一部电影是不是喜剧你可能看它的导演、主演、片长、豆瓣评分这些就是特征。标签就是你最终要预测的那个结果比如“喜剧”或“非喜剧”。机器学习的任务就是找到一个特征到标签的映射关系。2.2 监督学习、非监督学习到底怎么区分这是初学者必问的问题。我的理解特别简单如果有标签就是监督学习如果没标签就是非监督学习。把标签想象成“标准答案”。你在学校做的练习题有标准答案你对着正确答案去总结规律这叫监督学习。常见的有分类和回归。分类是预测类别比如邮件是垃圾邮件还是正常邮件回归是预测连续数值比如房价是500万还是600万。非监督学习就相当于你没有标准答案自己给一堆没有分类的文件按内容归堆。最常见的任务叫聚类比如把一批新闻按主题自动分成体育、财经、娱乐几类至于每个类叫什么名字得人再去定义。还有一种非监督学习是降维把高维数据压缩到两三维方便可视化这不是重点先了解就行。还有个“半监督学习”和“强化学习”的概念初学者阶段不用太纠结。我先说清楚方向后面实践时集中在监督学习里最经典的两类任务分类和回归。2.3 电影分类案例从身边事感受数据不知道你有没有听过一个经典的入门案例基于电影镜头数量来分类电影类型。假设我们有一些电影的数据包含“打斗镜头数量”和“接吻镜头数量”这两个特征标签是“动作片”和“爱情片”。比如电影A有100个打斗镜头、1个接吻镜头标签是动作片电影B有1个打斗镜头、100个接吻镜头标签是爱情片。现在来了一部新电影《唐人街探案》我们知道它有10个打斗镜头、20个接吻镜头但不知道它的分类让你猜它是哪种类型你的直觉大概是“更接近爱情片”。这个判断依据就是离它最近的已知电影是什么类型。这就是K近邻算法——机器学习里最直观、最适合入门的算法。K近邻的原理是“跟谁长得像就归谁”通过计算特征空间中的距离找出新样本的K个最近邻居让他们投票决定分类。这个例子特别适合入门因为它不需要任何数学公式就能让你明白机器学习处理分类问题的基本思路特征、距离、邻居、投票。3. 一个最小项目用K近邻给电影分类3.1 数据准备手工造一份小数据集纸上谈兵没意思我们直接写代码跑一个最小项目。目标就是复现刚才的电影分类场景。这里我不用现成的sklearn内置数据集因为手工数据更能理解数据形态。import pandas as pd data { 打斗镜头: [100, 95, 88, 1, 5, 2, 10, 8, 15, 90], 接吻镜头: [1, 3, 2, 100, 98, 105, 20, 25, 15, 8] } labels [动作片, 动作片, 动作片, 爱情片, 爱情片, 爱情片, 爱情片, 爱情片, 爱情片, 动作片] df pd.DataFrame(data) df[标签] labels这里我故意设计了10条样本。前6条是典型数据动作片的打斗镜头多接吻镜头少爱情片相反。后4条我加入了点“噪声”比如第7条有10个打斗镜头和20个接吻镜头标签却是爱情片——这就模拟了真实世界的不完美。真实数据里往往存在许多不典型的样本加入噪声是为了之后让你直观看到K近邻的效果和局限。3.2 距离计算与K值选择K近邻的核心是距离。最常用的是欧氏距离也就是在二维平面上两点之间的直线距离。公式很简单学过勾股定理就能理解对特征值分别求差、平方、求和、开根号。示例中《唐人街探案》的特征是[10, 20]我们算出它和电影1[100, 1]的距离是sqrt((100-10)² (1-20)²)等于sqrt(8100361)约92。跟电影7[10, 20]的距离是0但注意电影7是爱情片那么新电影离最近的点是爱情片自然会被判为爱情片。K值的选取直接影响结果。K1时只用一个最近邻居容易受到噪声影响K3时用三个最近邻居投票噪声影响被稀释K太大也不行比如K5时如果前5个邻居里正好有3个动作片结果就翻转了。初学者常问K怎么设常见做法是取奇数避免平票然后用交叉验证选一个合适的值。我们小数据里设K3就够。3.3 用sklearn实现完整流程Sklearn把K近邻封装得很完善几行代码搞定但为了让你知道背后发生了什么我先把原理写出来。from sklearn.neighbors import KNeighborsClassifier import numpy as np x df[[打斗镜头, 接吻镜头]].values y df[标签].values model KNeighborsClassifier(n_neighbors3) model.fit(x, y) new np.array([[10, 20]]) pred model.predict(new) print(pred) # [爱情片]这段代码先构造特征矩阵x和标签yx必须是二维数组y是一维数组。然后创建K近邻分类器指定邻居数3调用fit方法训练。注意这里的“训练”其实没有任何数学运算只是把数据存下来因为K近邻是懒学习模型真正计算发生在预测时。最后predict传入新样本的特征得到预测结果。跑完你会看到输出[爱情片]。跟我直觉判断一致。但你别高兴太早这个结果只是“训练集内部预测”如果拿这批数据测模型效果得到100%准确率根本不代表模型好。为什么因为模型“背答案”了。所以真正的实践必须把数据划分为训练集和测试集。3.4 训练集与测试集划分别让模型作弊正确做法是拿一部分数据训练另一部分数据验证。我们手动划分一下from sklearn.model_selection import train_test_split x_train, x_test, y_train, y_test train_test_split( x, y, test_size0.3, random_state42, stratifyy )这里test_size0.3表示留出30%的数据作测试集。random_state42意思是随机种子设成42这样别人复现你的代码时结果一致。stratifyy是分层抽样保证训练集和测试集里不同类别的比例和原始数据一致这在分类问题中很重要尤其是类别不平衡的时候。当我用这样划分后的数据重新训练并预测测试集时准确率会变得不好看因为有些测试样本就是之前说的噪声点。比如第7条数据特征完全不典型它如果被分进测试集模型很可能猜错。这时候你才真正体会到“泛化”的含义模型不只要记住训练集更要对没见过的新数据有判断力。我顺手把完整流程串成一块代码from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import accuracy_score knn KNeighborsClassifier(n_neighbors3) knn.fit(x_train, y_train) y_pred knn.predict(x_test) print(测试集准确率:, accuracy_score(y_test, y_pred))这一步下来你已经走完了一个标准机器学习项目的全流程数据准备、特征选择、模型选择、数据划分、训练、预测、评估。别看用到的代码少但这套流程骨架在后续任何项目里都不会变。4. 从最小项目迈向通用流程以鸢尾花为例4.1 换一个经典数据集感受通用性电影例子太小无法展示数据处理中的各种细节所以接下来我以机器学习入门必用的Iris鸢尾花数据集为例把整个流程再走一遍。Iris数据集有150条样本4个特征花萼长度、花萼宽度、花瓣长度、花瓣宽度3个类别Setosa、Versicolour、Virginica。sklearn内置了这个数据集用代码加载就行。from sklearn.datasets import load_iris iris load_iris() X iris.data y iris.target这个数据集的强大之处在于各类别在特征空间中有明显的区分很适合初学者直观理解分类边界。你还可以用matplotlib画一个二维散点图取其中两个特征把不同类别用不同颜色画出来你会看到Setosa类很轻松就被一条线分开另外两类却纠缠在一起。这就是“线性可分”和“线性不可分”的直观体验。4.2 完整训练流程模型选择、交叉验证、评估分类算法不止K近邻一个接下来我加上一个逻辑回归模型做对比。很多人以为逻辑回归是回归算法其实它是分类算法。它通过一个Sigmoid函数把线性输出映射到0到1之间当作概率。用sklearn实现也就几行from sklearn.linear_model import LogisticRegression from sklearn.model_selection import cross_val_score models { KNN: KNeighborsClassifier(n_neighbors3), LogisticRegression: LogisticRegression(max_iter200) } for name, model in models.items(): scores cross_val_score(model, X, y, cv5) print(f{name} 交叉验证准确率: {scores.mean():.3f} (/- {scores.std():.3f}))这里我用了5折交叉验证。什么叫交叉验证你可以理解成更保险的数据划分方式把数据分成5份轮流拿其中4份训练、1份验证最后得到5个准确率取平均。这比只划分一次训练集和测试集更可靠因为它让每个样本都有机会被验证减少了因数据划分偶然性导致的误判。运行之后你会看到KNN和逻辑回归的准确率都在0.95左右这已经很不错了。4.3 探索机器学习算法地图这篇文章不打算挨个讲算法但你要在脑袋里建立一张地图。机器学习算法大致分成几族线性模型逻辑回归、线性回归、树模型决策树、随机森林、梯度提升树、支持向量机SVM、基于距离的模型K近邻、神经网络模型。每个算法都有适合自己的场景。比如数据量小、特征少时逻辑回归很稳数据有明显的非线性关系时树模型更强图像数据则基本要靠深度学习。我见过很多人一上来就看西瓜书周志华《机器学习》的前几章被贝叶斯定理和概率论劝退。其实入门阶段应该先掌握“用哪类算法解决哪类任务”把sklearn里的模型接口玩熟再回头看理论推导你会突然通透很多。理论像是一张地图实操像是开着车在里面转你不先开两圈光看地图也是白看。5. 常见问题与避坑指南5.1 数据泄漏最常见的隐藏大坑数据泄漏是新手甚至资深工程师都会犯的错表现是模型在训练时表现奇好一到真实场景就拉胯。典型例子是先对全量数据做标准化再划分训练集和测试集。标准化会用到全量数据的均值和方差而测试集的均值和方差就已经在训练过程中被模型间接看到了这等于提前把测试集信息泄露给了模型。正确做法是先划分数据再在训练集上计算均值和方差然后用这个均值和方差去变换测试集。sklearn里用Pipeline可以避免这个问题它是把预处理和建模流程打包成一个整体交叉验证时不会产生泄漏。5.2 遇到报错怎么办从ModuleNotFoundError到维度不匹配实操中报错是家常便饭。常见的ModuleNotFoundError: No module named sklearn说明环境没装对先跑一下conda list | grep scikit-learn看看包在不在。ValueError: Expected 2D array, got 1D array instead是因为sklearn的模型接收的特征矩阵必须至少是二维的即使你只有一个特征也要用X.reshape(-1, 1)把它变成列向量。这个报错出现的频率极高理解了维度规则就不会慌。5.3 过拟合与欠拟合怎么判断训练集准确率接近100%但测试集准确率只有70%这是过拟合的典型信号。模型把训练数据中的噪声也学进去了缺乏泛化能力。解决思路有增加训练数据量、简化模型、加正则化参数或交叉验证调整超参数。反过来如果训练集准确率连60%都上不去多半是欠拟合模型太简单学不进规律那就得选更复杂的模型或者增加特征。我见过有同学用非常复杂的高阶多项式去拟合几个点画出来的曲线精确穿过每个点但换个新点直接偏离到天边。这就是“死记硬背”和“理解规律”的区别机器学习的核心要义永远是泛化。5.4 依赖版本问题与可复现性机器学习库更新非常频繁你网上抄一段代码可能因为一个API参数的改动就报错。比如老版本的sklearn里KNeighborsClassifier的参数是n_neighbors新版还是这个但很多其他模型的参数有变化。为了保险我在项目根目录维护一个requirements.txt把主要依赖版本锁死numpy1.24.3 pandas2.0.3 scikit-learn1.3.0 matplotlib3.7.2这样换台机器、过几个月再回来跑结果都能复现。初学者踩过几次这种坑之后就会明白环境管理不是形式主义而是省时间的关键。个人心得我学习机器学习的过程中最大的转折不是学会某个算法而是意识到“跑通代码”和“做对实验”之间隔着一道鸿沟。有时候模型准确率高了不是因为它聪明而是因为我的数据处理有纰漏。所以你现在看到任何一篇教程里给出漂亮的数字先别激动想一想它的数据是怎么划分的有没有防止数据泄漏评估指标选得是否合理。把心思花在这些“基础”上比追着新算法看十遍教程都管用。这篇内容如果你能从环境搭到鸢尾花实验完整走一遍已经算正式迈进机器学习的门槛了。下一步可以尝试找一个自己感兴趣的数据集比如房价预测、豆瓣电影评分预测把同样的流程套上去遇到问题再回来查。踩坑本身就是学习的一部分别怕报错报错信息才是老师傅最愿意教你的东西。
返回列表