據(jù)挖掘與機(jī)器學(xué)習(xí)入門(mén):從零跑通第一個(gè)分類(lèi)項(xiàng)目)
我最早開(kāi)始整理數(shù)據(jù)挖掘與機(jī)器學(xué)習(xí)學(xué)習(xí)筆記是因?yàn)橐粋€(gè)很現(xiàn)實(shí)的原因?qū)W得太快忘得更快。機(jī)器學(xué)習(xí)這個(gè)方向每翻幾頁(yè)教材就會(huì)蹦出來(lái)一個(gè)算法每個(gè)算法背后又拖著數(shù)學(xué)、代碼、案例三條尾巴。今天覺(jué)得自己懂了明天打開(kāi)電腦寫(xiě)代碼才發(fā)現(xiàn)連數(shù)據(jù)從哪來(lái)、模型怎么評(píng)估都理不清。于是我自己定了個(gè)規(guī)矩每學(xué)完一個(gè)主題就把它整理成一篇筆記把原理、代碼、踩坑全部寫(xiě)下來(lái)。這篇就是系列筆記的第一篇先不聊太深的公式把機(jī)器學(xué)習(xí)入門(mén)階段必須理清楚的那些事情一次性講透。如果你是那種剛接觸數(shù)據(jù)挖掘和機(jī)器學(xué)習(xí)、看到滿(mǎn)屏術(shù)語(yǔ)就頭疼的人或者之前零零散散看過(guò)一些課程、但始終沒(méi)有獨(dú)立跑通過(guò)一個(gè)正經(jīng)模型的人這篇文章應(yīng)該對(duì)你有用。它覆蓋三個(gè)層面的內(nèi)容認(rèn)知層數(shù)據(jù)挖掘和機(jī)器學(xué)習(xí)到底什么關(guān)系、數(shù)學(xué)要補(bǔ)到什么程度、該按什么順序?qū)W工具層Python、NumPy、Pandas、Matplotlib、scikit-learn 這些必備工具到底怎么搭配使用實(shí)戰(zhàn)層我會(huì)帶你在一個(gè)經(jīng)典小數(shù)據(jù)集上從數(shù)據(jù)探索到建模評(píng)估完整跑一遍分類(lèi)任務(wù)并附上我在實(shí)踐里踩過(guò)的幾個(gè)經(jīng)典坑。看完之后你可以照著這個(gè)路徑復(fù)現(xiàn)一遍把自己第一個(gè)機(jī)器學(xué)習(xí)項(xiàng)目真正跑起來(lái)。1. 先別急著寫(xiě)代碼入門(mén)前的3個(gè)認(rèn)知準(zhǔn)備1.1 數(shù)據(jù)挖掘和機(jī)器學(xué)習(xí)到底是不是一回事在很多學(xué)習(xí)筆記里數(shù)據(jù)挖掘和機(jī)器學(xué)習(xí)經(jīng)常被并列提出來(lái)。它們像兄弟但不是雙胞胎。數(shù)據(jù)挖掘的源頭是“從數(shù)據(jù)中發(fā)現(xiàn)有價(jià)值的知識(shí)”它的關(guān)注點(diǎn)更寬數(shù)據(jù)清洗、數(shù)據(jù)理解、特征工程、模式發(fā)現(xiàn)、異常檢測(cè)、可視化探索都在這個(gè)范疇里。它不要求一定用機(jī)器學(xué)習(xí)模型傳統(tǒng)的統(tǒng)計(jì)方法、簡(jiǎn)單的規(guī)則同樣可以是數(shù)據(jù)挖掘手段。我習(xí)慣把它理解成“在一個(gè)礦山里篩金子”——得先搞清楚哪個(gè)區(qū)域可能埋著東西、用什么工具篩、篩出來(lái)的東西怎么評(píng)估這些環(huán)節(jié)都在數(shù)據(jù)挖掘內(nèi)部。機(jī)器學(xué)習(xí)相比之下更聚焦在“構(gòu)建一個(gè)能從數(shù)據(jù)中學(xué)習(xí)并做出預(yù)測(cè)或決策的系統(tǒng)”。它關(guān)心的是數(shù)據(jù)里有沒(méi)有可學(xué)習(xí)的模式以及如何用算法把這個(gè)模式學(xué)出來(lái)然后對(duì)未知樣本做出判斷。你可以把它理解成“訓(xùn)練一只導(dǎo)盲犬”給它大量帶提示的樣例讓它學(xué)會(huì)看到某個(gè)輸入就做出正確的動(dòng)作。不過(guò)在真實(shí)項(xiàng)目里兩者高度交疊數(shù)據(jù)挖掘項(xiàng)目大概率會(huì)用到機(jī)器學(xué)習(xí)模型機(jī)器學(xué)習(xí)項(xiàng)目也一定繞不開(kāi)數(shù)據(jù)清洗和特征處理。入門(mén)階段你不需要糾結(jié)學(xué)科邊界只要記住一句話(huà)數(shù)據(jù)挖掘偏“找知識(shí)”機(jī)器學(xué)習(xí)偏“學(xué)映射”。后文聊到的所有實(shí)操本質(zhì)上都是把一堆原始數(shù)據(jù)變成有價(jià)值輸出的完整鏈條。1.2 學(xué)習(xí)路徑怎么安排才不會(huì)被勸退我見(jiàn)過(guò)太多人雄心勃勃地翻開(kāi)一本大部頭教材從第一章的數(shù)學(xué)推導(dǎo)開(kāi)始啃兩周后心態(tài)直接崩了。不是深挖理論不對(duì)而是入門(mén)階段你還沒(méi)有足夠的“模型直覺(jué)”來(lái)支撐理論理解。沒(méi)有直覺(jué)托底公式讀起來(lái)就只是一堆符號(hào)在跳動(dòng)。我建議的路線(xiàn)是先跑通一個(gè)極簡(jiǎn)項(xiàng)目再逐步擴(kuò)大知識(shí)面。拆開(kāi)來(lái)看就五步把 Python 基礎(chǔ)語(yǔ)法過(guò)一遍能寫(xiě)循環(huán)、能處理列表字典就夠了不需要學(xué)得很深。學(xué) NumPy、Pandas、Matplotlib 的常用操作用兩個(gè)小數(shù)據(jù)集把加載、清洗、畫(huà)圖做熟?;ㄒ恢芨愣畽C(jī)器學(xué)習(xí)最核心的幾個(gè)概念訓(xùn)練集/測(cè)試集、特征/標(biāo)簽、監(jiān)督/無(wú)監(jiān)督、過(guò)擬合。用 scikit-learn 跑通第一個(gè)分類(lèi)和回歸任務(wù)不管效果多粗糙先看到模型能跑起來(lái)?;氐浇滩陌葱柩a(bǔ)數(shù)學(xué)、補(bǔ)算法細(xì)節(jié)。這個(gè)路徑最大的好處是每一步都有正反饋。學(xué)完一個(gè)東西馬上能看到效果比如畫(huà)出一張清晰的分布圖或者跑出一個(gè)有基本準(zhǔn)頭的模型。這種反饋是支撐你繼續(xù)走下去最重要的燃料。我還想強(qiáng)調(diào)一點(diǎn)不要試圖把數(shù)據(jù)挖掘和機(jī)器學(xué)習(xí)拆成兩條平行的學(xué)習(xí)線(xiàn)。它們本來(lái)就是一套工作流上的環(huán)節(jié)現(xiàn)實(shí)中也是綁定在一起的。你拿到一份數(shù)據(jù)先做探索分析和清洗再做特征工程接著建模評(píng)估最后嘗試解釋結(jié)果。一套完整流程跑下來(lái)兩個(gè)領(lǐng)域的知識(shí)就一起覆蓋了。1.3 數(shù)學(xué)基礎(chǔ)要補(bǔ)到什么程度才夠用這是新手最焦慮的問(wèn)題我數(shù)學(xué)不好能不能學(xué)機(jī)器學(xué)習(xí)我的答案很明確能。入門(mén)階段你只需要把三門(mén)數(shù)學(xué)課的核心內(nèi)容學(xué)到“會(huì)用”的程度。線(xiàn)性代數(shù)要理解向量、矩陣、矩陣乘法、轉(zhuǎn)置、特征值和特征向量。原因是數(shù)據(jù)在代碼里就是二維數(shù)組PCA 降維本質(zhì)上是在找特征方向神經(jīng)網(wǎng)絡(luò)的每一層也就是一次矩陣運(yùn)算。概率統(tǒng)計(jì)要掌握期望、方差、條件概率、貝葉斯公式、常見(jiàn)分布和最大似然的基本思想。真實(shí)世界的標(biāo)簽往往帶噪聲“不確定性”這個(gè)概念會(huì)貫穿整個(gè)機(jī)器學(xué)習(xí)。微積分里重點(diǎn)是導(dǎo)數(shù)和梯度。梯度下降是大多數(shù)優(yōu)化算法的引擎把“沿著梯度反方向走一小步目標(biāo)函數(shù)會(huì)下降”這一句話(huà)想明白就夠用了。入門(mén)階段不需要證明公式也不需要手推 SVM 的對(duì)偶問(wèn)題。學(xué)機(jī)器學(xué)習(xí)有點(diǎn)像學(xué)開(kāi)車(chē)數(shù)學(xué)是發(fā)動(dòng)機(jī)原理你可以先會(huì)開(kāi)車(chē)再逐步理解發(fā)動(dòng)機(jī)為什么好開(kāi)。等你遇到具體場(chǎng)景比如為什么 L2 正則化能讓權(quán)重變小、為什么邏輯回歸要用極大似然估計(jì)再回頭補(bǔ)數(shù)學(xué)效率會(huì)高很多。2. 工具鏈與學(xué)習(xí)路線(xiàn)Python生態(tài)怎么搭2.1 為什么首選Python而不是Excel/R/SPSS我早期做過(guò)一段時(shí)間的報(bào)表和數(shù)據(jù)分析Excel 用得非常多數(shù)據(jù)透視表、VLOOKUP、條件格式都玩得熟練。但 Excel 有其明顯天花板一旦面對(duì)幾十萬(wàn)行、上百個(gè)字段的數(shù)據(jù)操作就會(huì)變得很卡而且很難承載“訓(xùn)練一個(gè)模型并反復(fù)調(diào)參”這類(lèi)任務(wù)。R 在統(tǒng)計(jì)分析和繪圖上有獨(dú)到優(yōu)勢(shì)尤其適合統(tǒng)計(jì)檢驗(yàn)、學(xué)術(shù)圖表這類(lèi)的場(chǎng)景。但它在工程化、深度學(xué)習(xí)生態(tài)和通用編程能力上不如 Python 均衡很多工程團(tuán)隊(duì)也不太用它來(lái)上線(xiàn)模型。至于 SPSS、SAS 這類(lèi)商業(yè)統(tǒng)計(jì)工具更偏傳統(tǒng)統(tǒng)計(jì)流程閉源、昂貴而且很難和現(xiàn)代數(shù)據(jù)處理鏈路集成。Python 能成為數(shù)據(jù)挖掘和機(jī)器學(xué)習(xí)的事實(shí)標(biāo)準(zhǔn)根本原因是生態(tài)。scikit-learn 把所有經(jīng)典算法封裝成統(tǒng)一接口Pandas 提供類(lèi)似 SQL 的表格操作能力Matplotlib/Seaborn 解決可視化NumPy 負(fù)責(zé)底層高效數(shù)值計(jì)算。更關(guān)鍵的是社區(qū)龐大你遇到的問(wèn)題幾乎都能搜到對(duì)應(yīng)解決方案。對(duì)新手來(lái)說(shuō)搜索問(wèn)題效率高本身就是巨大的優(yōu)勢(shì)。我自己學(xué)習(xí)時(shí)遵循一個(gè)原則能在命令行里用代碼解決的問(wèn)題絕不用鼠標(biāo)在圖形界面里點(diǎn)來(lái)點(diǎn)去。代碼可復(fù)制、可復(fù)現(xiàn)、可版本化這比任何“記憶操作步驟”都可靠。這也是數(shù)據(jù)工作最基本的素養(yǎng)之一。2.2 數(shù)據(jù)三件套NumPy、Pandas、Matplotlib怎么學(xué)所謂三件套就是 NumPy、Pandas 和 Matplotlib/Seaborn。它們各解決什么問(wèn)題我用一個(gè)場(chǎng)景說(shuō)明。假設(shè)你拿到一張訂單表幾萬(wàn)行數(shù)據(jù)包含訂單號(hào)、城市、商品類(lèi)別、金額、下單時(shí)間等字段。你想知道“每個(gè)城市每類(lèi)商品的銷(xiāo)售額排名”。用 Excel 要做透視表用 Pandas 只需要一個(gè)方法鏈按城市和類(lèi)別分組、對(duì)金額求和、排序輸出一個(gè)新表。這個(gè)處理過(guò)程本質(zhì)上就是數(shù)據(jù)挖掘里的“數(shù)據(jù)準(zhǔn)備與聚合”。NumPy 的職責(zé)是底層數(shù)值計(jì)算。Pandas 底層大量依賴(lài) NumPy你不需要把 NumPy 的 API 全背下來(lái)但一定要理解它與 Python 內(nèi)置列表的關(guān)鍵區(qū)別向量化運(yùn)算。比如把一整個(gè)數(shù)組的每個(gè)元素乘 2用純 Python for 循環(huán)可能慢得明顯用 NumPy 的廣播機(jī)制幾乎是瞬間完成。大規(guī)模數(shù)據(jù)操作必須依靠向量化這是性能的核心。Matplotlib 是基礎(chǔ)繪圖庫(kù)Seaborn 在它之上封裝出更美觀(guān)的統(tǒng)計(jì)圖形。入門(mén)階段掌握四類(lèi)圖就夠散點(diǎn)圖、直方圖、箱線(xiàn)圖、熱力圖。每次拿到新數(shù)據(jù)集先畫(huà)分布和相關(guān)性這是發(fā)現(xiàn)異常值和理解特征關(guān)系最快的方法。學(xué)習(xí)三件套時(shí)我強(qiáng)烈建議直接拿真實(shí)數(shù)據(jù)集練手而不是去刷語(yǔ)法手冊(cè)。比如找一份公開(kāi)的銷(xiāo)售記錄連續(xù)做幾個(gè)小任務(wù)篩選某月數(shù)據(jù)、計(jì)算客單價(jià)、按城市分組統(tǒng)計(jì)、畫(huà)出金額分布。這些小練習(xí)做完你的掌握程度會(huì)遠(yuǎn)超那些只跟著教程敲過(guò)例子的人。2.3 先學(xué)scikit-learn還是先學(xué)深度學(xué)習(xí)框架幾乎每個(gè)初學(xué)者都問(wèn)過(guò)這個(gè)問(wèn)題。深度學(xué)習(xí)框架熱度太高容易讓人誤以為入門(mén)就要從 PyTorch 或 TensorFlow 開(kāi)始。我的建議非常明確入門(mén)階段先老老實(shí)實(shí)學(xué) scikit-learn。理由有三條。第一scikit-learn 算法覆蓋率高線(xiàn)性回歸、邏輯回歸、決策樹(shù)、隨機(jī)森林、SVM、KNN、聚類(lèi)、降維、特征工程工具全都有而且 API 極度統(tǒng)一核心就是 fit 和 predict 兩個(gè)方法。學(xué)會(huì)一個(gè)模型其他模型很快就能舉一反三。第二它對(duì)新手很友好默認(rèn)參數(shù)在常見(jiàn)規(guī)模的數(shù)據(jù)上通常表現(xiàn)不錯(cuò)不需要你理解太多底層細(xì)節(jié)就能跑出可接受的結(jié)果。第三它和深度學(xué)習(xí)框架不是對(duì)立關(guān)系而是前后銜接的關(guān)系——兩者共享同一套機(jī)器學(xué)習(xí)思維比如數(shù)據(jù)預(yù)處理、訓(xùn)練測(cè)試劃分、評(píng)估指標(biāo)、過(guò)擬合與正則化。那什么時(shí)候可以轉(zhuǎn)向深度學(xué)習(xí)框架我的判斷標(biāo)準(zhǔn)很實(shí)際當(dāng)你手里的數(shù)據(jù)是圖像、長(zhǎng)文本、語(yǔ)音這類(lèi)非結(jié)構(gòu)化數(shù)據(jù)或者發(fā)現(xiàn)傳統(tǒng)模型已經(jīng)明顯遇到瓶頸再或者你需要自定義靈活的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)時(shí)就可以切入 PyTorch 了。到那個(gè)階段你已經(jīng)有模型直覺(jué)和數(shù)據(jù)處理經(jīng)驗(yàn)再學(xué)張量、自動(dòng)求導(dǎo)、GPU 加速這些概念會(huì)順很多。學(xué)習(xí)順序上先用 scikit-learn 把經(jīng)典算法全部過(guò)一遍再用 PyTorch 重寫(xiě)其中幾個(gè)簡(jiǎn)單模型比如線(xiàn)性回歸和邏輯回歸。這一步做完你既理解了兩代工具的差異也能把基礎(chǔ)概念串起來(lái)。3. 核心概念掃盲從模型到完整流程3.1 監(jiān)督學(xué)習(xí)的兩大基本盤(pán)分類(lèi)與回歸監(jiān)督學(xué)習(xí)的核心是有一批已經(jīng)標(biāo)注好的樣本模型從這些樣本里學(xué)規(guī)律然后去預(yù)測(cè)新樣本的標(biāo)簽。用“開(kāi)卷復(fù)習(xí)之后閉卷考試”來(lái)理解就對(duì)了——訓(xùn)練集是你復(fù)習(xí)時(shí)翻看的標(biāo)準(zhǔn)答案測(cè)試集是考場(chǎng)上的新題目模型在測(cè)試集上的表現(xiàn)才算真本事。監(jiān)督學(xué)習(xí)下面最常用的是兩類(lèi)任務(wù)分類(lèi)任務(wù)預(yù)測(cè)的標(biāo)簽是離散類(lèi)別。例如銀行判斷一筆交易是否屬于欺詐、郵件服務(wù)判斷一封郵件是否垃圾郵件、公司根據(jù)用戶(hù)畫(huà)像預(yù)測(cè)用戶(hù)是否會(huì)流失?;貧w任務(wù)預(yù)測(cè)的標(biāo)簽是連續(xù)數(shù)值。例如預(yù)測(cè)房?jī)r(jià)、預(yù)測(cè)明天最高氣溫、預(yù)測(cè)某個(gè)商品未來(lái)一個(gè)月的銷(xiāo)量。項(xiàng)目里反復(fù)出現(xiàn)的概念不外乎這么幾個(gè)特征也就是樣本的屬性比如年齡、消費(fèi)金額、訪(fǎng)問(wèn)次數(shù)標(biāo)簽也就是你真正想預(yù)測(cè)的值比如“是否流失”訓(xùn)練集用來(lái)學(xué)習(xí)規(guī)律的樣本測(cè)試集負(fù)責(zé)考試的樣本。新手最容易犯的錯(cuò)誤之一是把訓(xùn)練集上的表現(xiàn)直接當(dāng)成模型最終水平。訓(xùn)練集上的高分說(shuō)明模型“背得熟”測(cè)試集上的分?jǐn)?shù)才說(shuō)明模型“學(xué)得會(huì)”。這兩者之間的差距大小本質(zhì)上就是過(guò)擬合的程度。用一個(gè)例子串起來(lái)你要預(yù)測(cè)某用戶(hù)是否會(huì)在未來(lái)三個(gè)月內(nèi)購(gòu)買(mǎi)某商品特征可能有瀏覽時(shí)長(zhǎng)、歷史購(gòu)買(mǎi)次數(shù)、最近一次訪(fǎng)問(wèn)間隔。你用一個(gè)月的歷史數(shù)據(jù)構(gòu)造訓(xùn)練集再用后面一周的數(shù)據(jù)做測(cè)試集訓(xùn)練一個(gè)分類(lèi)模型。整個(gè)過(guò)程聽(tīng)起來(lái)不難但真上手之后你會(huì)發(fā)現(xiàn)數(shù)據(jù)清洗和特征篩選才是真正花時(shí)間的地方訓(xùn)練模型反而只是其中一環(huán)。3.2 無(wú)監(jiān)督學(xué)習(xí)聚類(lèi)和降維是干什么用的和監(jiān)督學(xué)習(xí)不同無(wú)監(jiān)督學(xué)習(xí)面對(duì)的數(shù)據(jù)沒(méi)有標(biāo)簽?zāi)P鸵约簭臄?shù)據(jù)結(jié)構(gòu)中發(fā)現(xiàn)模式。這個(gè)概念一開(kāi)始有點(diǎn)抽象我用最常見(jiàn)的兩個(gè)任務(wù)來(lái)講。聚類(lèi)目標(biāo)是把相似的樣本聚成一組。舉個(gè)例子電商平臺(tái)并沒(méi)有給用戶(hù)打上“高價(jià)值/低價(jià)值”的標(biāo)簽但你希望做客戶(hù)分群。于是你用消費(fèi)頻次、客單價(jià)、瀏覽深度這些特征讓算法自動(dòng)把用戶(hù)分成幾簇。分完以后每簇用戶(hù)可能呈現(xiàn)出不同的行為畫(huà)像運(yùn)營(yíng)策略就能因人而異。K-Means 是最常用的聚類(lèi)算法核心其實(shí)就是圓心 K 的取值你想聚成幾類(lèi)。選 K 的方式可以看手肘法則也可以結(jié)合業(yè)務(wù)經(jīng)驗(yàn)。降維目標(biāo)是壓縮特征維度。假設(shè)原始特征有 100 個(gè)里面大量冗余、彼此高度相關(guān)PCA 通過(guò)尋找數(shù)據(jù)方差最大的方向把 100 個(gè)特征壓成 5 個(gè)同時(shí)盡量保留原有信息。降維還有一個(gè)很實(shí)用的場(chǎng)景是可視化——把高維數(shù)據(jù)投影到二維平面人眼才能看到它的分布和簇結(jié)構(gòu)。無(wú)監(jiān)督學(xué)習(xí)有時(shí)被認(rèn)為是更貼近“數(shù)據(jù)挖掘”本意的技術(shù)。確實(shí)數(shù)據(jù)挖掘的起點(diǎn)往往就是沒(méi)有標(biāo)簽的數(shù)據(jù)你得先有探索性的理解才可能設(shè)計(jì)出更合理的特征和方案。入門(mén)階段至少要跑通一次 K-Means 和一次 PCA不是為了看效果有多好而是為了建立“從數(shù)據(jù)自身結(jié)構(gòu)里找規(guī)律”的感覺(jué)。3.3 一個(gè)完整數(shù)據(jù)挖掘項(xiàng)目的六個(gè)階段很多新手學(xué)到建模就停了以為拿到高準(zhǔn)確率就是整個(gè)項(xiàng)目的終點(diǎn)。真正讓數(shù)據(jù)挖掘產(chǎn)生業(yè)務(wù)價(jià)值行業(yè)里最經(jīng)典的流程框架叫 CRISP-DM中文常譯作“跨行業(yè)數(shù)據(jù)挖掘標(biāo)準(zhǔn)流程”它把項(xiàng)目切成了六個(gè)階段業(yè)務(wù)理解搞清楚要解決什么問(wèn)題、價(jià)值在哪里。數(shù)據(jù)理解收集數(shù)據(jù)、初步探查、驗(yàn)證數(shù)據(jù)質(zhì)量。數(shù)據(jù)準(zhǔn)備清洗、合并、構(gòu)造特征、處理缺失值。建模在干凈數(shù)據(jù)上訓(xùn)練多個(gè)候選模型。評(píng)估回到業(yè)務(wù)目標(biāo)判斷模型是否真的解決問(wèn)題。部署把模型接入實(shí)際系統(tǒng)持續(xù)監(jiān)控效果。我用一個(gè)生活中的類(lèi)比幫助記憶你在城市里找地方開(kāi)咖啡店。業(yè)務(wù)理解是“確定該開(kāi)在哪、服務(wù)誰(shuí)”數(shù)據(jù)理解是“調(diào)查周邊人流、消費(fèi)水平”數(shù)據(jù)準(zhǔn)備是“把各路信息整理成一張干凈的表”建模是“用不同策略評(píng)估候選位置”評(píng)估是“模擬利潤(rùn)并實(shí)地復(fù)核”部署是“真的把店開(kāi)起來(lái)并持續(xù)觀(guān)察”。在這個(gè)階段里新手最容易忽略的是“評(píng)估”和“部署”但這恰恰是項(xiàng)目能否落地的分水嶺。作為入門(mén)筆記我建議你在做任何練習(xí)項(xiàng)目時(shí)都按照這個(gè)框架寫(xiě)一份簡(jiǎn)短文檔把每個(gè)階段做了什么寫(xiě)下來(lái)。哪怕只是給自己看它也能幫你建立完整的數(shù)據(jù)項(xiàng)目思維。4. 手把手實(shí)操跑通一個(gè)完整的分類(lèi)項(xiàng)目4.1 環(huán)境準(zhǔn)備與數(shù)據(jù)集選擇實(shí)操前先把環(huán)境準(zhǔn)備好。我用的是 conda因?yàn)樗芎芊奖愕貏?chuàng)建隔離環(huán)境避免不同項(xiàng)目之間的依賴(lài)沖突。打開(kāi)終端執(zhí)行conda create -n ml_learning python3.10 conda activate ml_learning pip install notebook scikit-learn pandas matplotlib seaborn如果 conda 在某些網(wǎng)絡(luò)環(huán)境下安裝較慢你也可以換成 venv 配合 pip管理思路是一樣的只是命令略有差別。環(huán)境搞定之后在終端輸入 jupyter notebook 啟動(dòng)交互環(huán)境就可以開(kāi)始寫(xiě)代碼了。這次使用的數(shù)據(jù)集是鳶尾花數(shù)據(jù)集 Iris。這是一個(gè)非常經(jīng)典的入門(mén)數(shù)據(jù)集三種鳶尾花各有若干樣本每個(gè)樣本有四個(gè)特征——花萼長(zhǎng)度、花萼寬度、花瓣長(zhǎng)度、花瓣寬度。目標(biāo)是根據(jù)這四個(gè)連續(xù)特征預(yù)測(cè)當(dāng)前樣本屬于哪一個(gè)品種。為什么選它來(lái)做第一個(gè)項(xiàng)目第一數(shù)據(jù)干凈、無(wú)缺失值不需要做復(fù)雜的清洗第二四維特征少而清晰畫(huà)圖就能直觀(guān)看到分布第三三個(gè)類(lèi)別樣本數(shù)量均衡評(píng)估結(jié)果不容易被誤導(dǎo)第四scikit-learn 內(nèi)置了這個(gè)數(shù)據(jù)的讀取接口一行代碼就能加載省去下載和解析的麻煩。等你把這套流程跑熟了再切換到真實(shí)世界那些又臟又大的數(shù)據(jù)難度逐級(jí)提升才不會(huì)一開(kāi)始就被勸退。4.2 數(shù)據(jù)探索先別建模好好看看數(shù)據(jù)很多人拿到數(shù)據(jù)就急著跑模型這是大忌。先花幾分鐘探查數(shù)據(jù)既能發(fā)現(xiàn)異常也能建立對(duì)問(wèn)題的直覺(jué)。加載數(shù)據(jù)并轉(zhuǎn)成 DataFramefrom sklearn.datasets import load_iris import pandas as pd iris load_iris() df pd.DataFrame(iris.data, columnsiris.feature_names) df[species] iris.target_names[iris.target] print(df.head()) print(df.info()) print(df.describe())head() 讓你看到前五行知道數(shù)據(jù)長(zhǎng)什么樣info() 顯示有沒(méi)有空值、每列的類(lèi)型describe() 給出每列的均值、標(biāo)準(zhǔn)差、最小值、最大值等統(tǒng)計(jì)量。跑完之后你會(huì)發(fā)現(xiàn)花瓣長(zhǎng)度和花瓣寬度的取值范圍明顯比花萼特征大最大值能到 6.9而花萼寬度的最小值是 2.0。這個(gè)觀(guān)察是一個(gè)信號(hào)暗示后面建模時(shí)要注意特征縮放。接著畫(huà)一張成對(duì)分布圖把四個(gè)特征兩兩組合不同品種用不同顏色標(biāo)出import seaborn as sns import matplotlib.pyplot as plt sns.pairplot(df, huespecies) plt.show()從這張圖里你能直觀(guān)看到山鳶尾和另外兩種花是混在一起還是分得很開(kāi)。以我的經(jīng)驗(yàn)Iris 的成對(duì)分布圖會(huì)呈現(xiàn)出一個(gè)很明顯的結(jié)論花瓣長(zhǎng)度和花瓣寬度這兩個(gè)特征對(duì)區(qū)分品種貢獻(xiàn)最大而花萼寬度單獨(dú)使用時(shí)區(qū)分度很弱。這種直覺(jué)會(huì)直接影響你后續(xù)建模時(shí)的特征選擇也會(huì)讓你對(duì)模型能達(dá)到的準(zhǔn)確率有一個(gè)合理預(yù)期。4.3 建模與評(píng)估用KNN跑第一個(gè)模型數(shù)據(jù)探查結(jié)束可以建模了。我的第一個(gè)模型選 K 最近鄰也就是 KNN。理由不是它最強(qiáng)而是它直覺(jué)最好理解一個(gè)新樣本來(lái)了看看離它最近的 K 個(gè)已知樣本分別屬于哪一類(lèi)哪個(gè)類(lèi)別多新樣本就屬于哪個(gè)類(lèi)。這個(gè)算法沒(méi)有復(fù)雜的訓(xùn)練過(guò)程非常適合用來(lái)理解“模型是怎么做預(yù)測(cè)”的。完整代碼如下from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.neighbors import KNeighborsClassifier X df.iloc[:, :-1].values y iris.target X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, random_state42 ) scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) model KNeighborsClassifier(n_neighbors3) model.fit(X_train_scaled, y_train) acc model.score(X_test_scaled, y_test) print(f準(zhǔn)確率: {acc:.4f})有幾處細(xì)節(jié)需要特別說(shuō)明。第一為什么劃分訓(xùn)練集和測(cè)試集test_size0.3 意味著 30% 的數(shù)據(jù)留作測(cè)試70% 參與訓(xùn)練。random_state 固定成 42是讓每次實(shí)驗(yàn)的劃分結(jié)果一致方便復(fù)現(xiàn)。你看別人的學(xué)習(xí)筆記時(shí)如果對(duì)方不固定隨機(jī)種子你很難跑出完全一樣的結(jié)果。第二StandardScaler 的作用是讓每個(gè)特征變成均值 0、方差 1。KNN 依賴(lài)距離歐氏距離會(huì)被取值范圍大的特征主導(dǎo)不縮放的話(huà)花瓣特征的影響就被花萼長(zhǎng)度蓋過(guò)去了。第三scaler 只在訓(xùn)練集上 fit測(cè)試集只做 transform。這個(gè)順序非常重要我在下一章會(huì)專(zhuān)門(mén)展開(kāi)講為什么。正確執(zhí)行的情況下你在 Iris 上通常能得到 0.93 以上的準(zhǔn)確率。這三個(gè)類(lèi)別在特征空間里本身區(qū)分度就高所以模型表現(xiàn)好并不意外。關(guān)鍵在于理解這個(gè)數(shù)字的含義它是模型在從未見(jiàn)過(guò)的測(cè)試樣本上的表現(xiàn)而不是在訓(xùn)練集上的自吹自擂。跑完分類(lèi)你還可以順手把數(shù)據(jù)集切出一份做 K-Means 聚類(lèi)或者用線(xiàn)性回歸預(yù)測(cè)一個(gè)連續(xù)變量練練手。不過(guò)第一步先把分類(lèi)流程跑順貪多嚼不爛。5. 新手最容易踩的坑實(shí)操問(wèn)題排查實(shí)錄5.1 數(shù)據(jù)泄漏一個(gè)偷看答案的習(xí)慣數(shù)據(jù)泄漏是新手最容易犯、也最不容易察覺(jué)的錯(cuò)誤。最典型的表現(xiàn)是在劃分訓(xùn)練集和測(cè)試集之前就用全量數(shù)據(jù)做標(biāo)準(zhǔn)化、缺失值填充或者算了某些統(tǒng)計(jì)指標(biāo)。這樣一來(lái)測(cè)試集的信息在訓(xùn)練階段就泄露給了模型。相當(dāng)于考前老師把考卷答案也當(dāng)成例題講了考出來(lái)的分?jǐn)?shù)自然反映不了真實(shí)水平。正確做法永遠(yuǎn)是先劃分訓(xùn)練集和測(cè)試集再在訓(xùn)練集上 fit 預(yù)處理器最后應(yīng)用到測(cè)試集。對(duì)應(yīng)到代碼就是scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test)注意這里的差別fit_transform 只出現(xiàn)在訓(xùn)練集上測(cè)試集只用 transform。如果先對(duì)全量數(shù)據(jù) fit_transform 再拆分你得到的高分是虛高的。在真實(shí)項(xiàng)目上這種虛高帶來(lái)的后果更嚴(yán)重模型部署到線(xiàn)上后面對(duì)全新的數(shù)據(jù)表現(xiàn)會(huì)遠(yuǎn)遠(yuǎn)低于你在驗(yàn)證時(shí)看到的指標(biāo)。養(yǎng)成“一切統(tǒng)計(jì)和擬合操作只基于訓(xùn)練集”的習(xí)慣是從新手走向合格工程師的重要一步。5.2 忘記特征縮放距離類(lèi)模型的隱形殺手第二個(gè)坑和數(shù)據(jù)處理相關(guān)但沒(méi)那么容易察覺(jué)。KNN、SVM 這類(lèi)基于距離的模型對(duì)特征尺度極其敏感。我見(jiàn)過(guò)不少同學(xué)跑 KNN 時(shí)不做標(biāo)準(zhǔn)化結(jié)果在 Iris 上的準(zhǔn)確率明顯下降。原因很好理解計(jì)算距離時(shí)取值范圍大的特征天然獲得更大權(quán)重模型幾乎被那一兩個(gè)特征牽著走。你可能會(huì)問(wèn)那樹(shù)模型和線(xiàn)性回歸也需要縮放嗎決策樹(shù)和隨機(jī)森林不需要因?yàn)樗鼈儼刺卣鞣至巡灰蕾?lài)距離線(xiàn)性回歸在解釋系數(shù)時(shí)一般建議縮放否則系數(shù)之間不可比神經(jīng)網(wǎng)絡(luò)、KNN、SVM、PCA 則強(qiáng)烈依賴(lài)同一量綱。這是算法選型時(shí)必須記住的細(xì)節(jié)。怎么判斷一個(gè)模型是否需要特征縮放問(wèn)自己一個(gè)問(wèn)題這個(gè)模型的計(jì)算過(guò)程里有沒(méi)有用到距離、梯度、方差用到就得認(rèn)真考慮。最簡(jiǎn)單省心的習(xí)慣是數(shù)值型特征先 StandardScaler再喂給模型除非你有明確理由不這樣做。5.3 只看準(zhǔn)確率類(lèi)別不平衡下的評(píng)估誤區(qū)初學(xué)階段很多人習(xí)慣拿準(zhǔn)確率當(dāng)唯一指標(biāo)。準(zhǔn)確率確實(shí)直觀(guān)但在類(lèi)別不均衡的場(chǎng)景下會(huì)極度誤導(dǎo)。舉一個(gè)極端例子假設(shè)欺詐交易只占全部交易的 1%你寫(xiě)一個(gè)“永遠(yuǎn)預(yù)測(cè)正?!钡纳倒夏P蜏?zhǔn)確率照樣是 99%但它完全沒(méi)用因?yàn)檎鎸?shí)欺詐一筆都沒(méi)抓到。這時(shí)候要用到一組更細(xì)的指標(biāo)精確率、召回率、F1 分?jǐn)?shù)。精確率回答的是“模型判定為欺詐的交易里有多少是真的欺詐”召回率回答的是“所有真實(shí)欺詐交易里模型抓到了多少”F1 是兩者的調(diào)和平均兼顧兩邊的表現(xiàn)。實(shí)際業(yè)務(wù)往往需要在兩率之間做權(quán)衡抓漏的代價(jià)高還是誤傷的代價(jià)高這個(gè)答案只有業(yè)務(wù)方知道模型自身不會(huì)告訴你。入門(mén)階段不要求你立刻精通全部評(píng)估指標(biāo)但至少要有這個(gè)意識(shí)準(zhǔn)確率不是萬(wàn)能的要結(jié)合數(shù)據(jù)分布和業(yè)務(wù)目標(biāo)選擇合適的評(píng)估方式。另外還有一個(gè)高頻翻車(chē)點(diǎn)訓(xùn)練集表現(xiàn)很好測(cè)試集突然拉胯。這種時(shí)候多數(shù)是以下四種原因之一數(shù)據(jù)劃分泄漏、沒(méi)有做特征縮放、訓(xùn)練樣本太少、模型太復(fù)雜導(dǎo)致過(guò)擬合。照著這個(gè)清單逐條排查大多數(shù)“神奇翻車(chē)”都能定位到。6. 入門(mén)之后這條路還能往哪些方向走6.1 常用算法清單先認(rèn)識(shí)全貌再逐個(gè)擊破當(dāng)你跑通 KNN 之后可以按順序掃掉一批經(jīng)典算法。我整理了一張快速認(rèn)識(shí)的對(duì)照表算法任務(wù)類(lèi)型一句話(huà)理解入門(mén)探索建議線(xiàn)性回歸回歸用一條超平面擬合數(shù)據(jù)先理解最小二乘損失邏輯回歸分類(lèi)在回歸基礎(chǔ)上加 sigmoid 壓縮出概率理解輸出為什么在 0 到 1 之間決策樹(shù)分類(lèi)/回歸按特征做一層層 if-then 判斷畫(huà)棵樹(shù)看每個(gè)節(jié)點(diǎn)怎么選特征隨機(jī)森林分類(lèi)/回歸多棵決策樹(shù)投票或平均降低過(guò)擬合理解 Bagging 思想SVM分類(lèi)找最大化間隔的分隔超平面先用線(xiàn)性核再感受核技巧K-Means聚類(lèi)按距離把樣本分簇嘗試不同 K看分簇效果PCA降維找方差最大的若干方向投影結(jié)合可視化理解特征方向每一條都值得單獨(dú)花時(shí)間寫(xiě)代碼跑一遍。我的經(jīng)驗(yàn)是每學(xué)一個(gè)新算法就把它放到同一份數(shù)據(jù)集上跟舊模型對(duì)比看看差異在哪里。這樣你對(duì)算法的理解會(huì)比死背公式深刻得多。這個(gè)階段不追求調(diào)出最完美的模型而是建立“看到數(shù)據(jù)時(shí)能聯(lián)想到多種算法工具”的直覺(jué)。6.2 特征工程與模型調(diào)參真正拉開(kāi)差距的地方不少入門(mén)者以為機(jī)器學(xué)習(xí)做到“調(diào)模型”就結(jié)束了事實(shí)恰恰相反真實(shí)項(xiàng)目里最耗時(shí)間的往往是特征工程而不是調(diào)參。特征工程是指從原始數(shù)據(jù)里構(gòu)造出更能刻畫(huà)業(yè)務(wù)規(guī)律的新特征。比如從時(shí)間戳里拆出“星期幾”從用戶(hù)行為序列里統(tǒng)計(jì)“最近 7 天購(gòu)買(mǎi)次數(shù)”或者把類(lèi)別型變量編碼成模型能處理的數(shù)值。同樣的算法特征工程做得好不好最終效果可能相差一個(gè)量級(jí)。這個(gè)環(huán)節(jié)考驗(yàn)的主要是兩點(diǎn)一是對(duì)業(yè)務(wù)的理解二是對(duì)數(shù)據(jù)變換工具的熟練程度。入門(mén)時(shí)不要怕花時(shí)間把缺失值處理、類(lèi)別編碼、數(shù)值分桶、時(shí)間特征拆解這四類(lèi)操作練熟。調(diào)參方面入門(mén)階段建議直接用網(wǎng)格搜索系統(tǒng)性地找參數(shù)而不是靠感覺(jué)一個(gè)個(gè)試。例如在 KNN 上嘗試不同的 k 值和距離權(quán)重from sklearn.model_selection import GridSearchCV param_grid { n_neighbors: [3, 5, 7, 9], weights: [uniform, distance] } grid GridSearchCV(KNeighborsClassifier(), param_grid, cv5) grid.fit(X_train_scaled, y_train) print(grid.best_params_)GridSearchCV 會(huì)把參數(shù)組合全部試一遍并用交叉驗(yàn)證選出一組最優(yōu)參數(shù)。這里的 cv5 表示把訓(xùn)練數(shù)據(jù)切成 5 份輪流用 4 份訓(xùn)練、1 份驗(yàn)證。它的意義在于你選參數(shù)時(shí)不依賴(lài)某一次特定的數(shù)據(jù)劃分評(píng)估結(jié)果更穩(wěn)定。等你掌握了網(wǎng)格搜索再去理解隨機(jī)搜索、貝葉斯調(diào)參本質(zhì)上也只是搜索策略的優(yōu)化。核心思想始終是模型選擇要有評(píng)價(jià)依據(jù)不能拍腦袋。6.3 從結(jié)構(gòu)化數(shù)據(jù)走向深度學(xué)習(xí)傳統(tǒng)機(jī)器學(xué)習(xí)中的經(jīng)典算法最擅長(zhǎng)處理的場(chǎng)景是結(jié)構(gòu)化表格數(shù)據(jù)。但當(dāng)數(shù)據(jù)切換成圖片、視頻、語(yǔ)音、長(zhǎng)文本之后特征高度非結(jié)構(gòu)化手動(dòng)設(shè)計(jì)特征的成本急劇上升這時(shí)神經(jīng)網(wǎng)絡(luò)這類(lèi)能自動(dòng)學(xué)習(xí)特征表達(dá)的模型就開(kāi)始接管戰(zhàn)場(chǎng)。深度學(xué)習(xí)的進(jìn)階路徑建議從多層感知機(jī) MLP 起步。先理解神經(jīng)網(wǎng)絡(luò)如何通過(guò)一層層線(xiàn)性變換加非線(xiàn)性激活函數(shù)來(lái)逼近復(fù)雜函數(shù)然后過(guò)渡到卷積神經(jīng)網(wǎng)絡(luò) CNN處理圖像再到適合文本序列的 Transformer 結(jié)構(gòu)。這不是一篇入門(mén)筆記能展開(kāi)的內(nèi)容但方向可以先立起來(lái)。對(duì)打算走數(shù)據(jù)挖掘路線(xiàn)的人我的建議是不用盲目追深度學(xué)習(xí)每一條最新進(jìn)展先把經(jīng)典模型和數(shù)據(jù)處理能力練扎實(shí)。深度學(xué)習(xí)是工具經(jīng)典機(jī)器學(xué)習(xí)是地基。地基穩(wěn)了上層的新工具你學(xué)習(xí)起來(lái)會(huì)非??斓鼗焕闻茉俣嘈履P鸵仓皇窃趧e人的代碼上拼拼湊湊。整套筆記寫(xiě)下來(lái)我最深的體會(huì)不是某個(gè)模型跑得有多準(zhǔn)而是“先跑通、再深入”這套學(xué)習(xí)方法真的對(duì)新手最友好。我后來(lái)再看自己這篇第一篇筆記仍然能回憶起當(dāng)年踩坑時(shí)的抓狂但現(xiàn)在回看那些坑恰恰是理解模型評(píng)估和數(shù)據(jù)處理的入口。如果你也在學(xué)機(jī)器學(xué)習(xí)我建議你不妨也把學(xué)過(guò)的內(nèi)容寫(xiě)成文字。寫(xiě)出來(lái)是一個(gè)很強(qiáng)的信號(hào)代表你不僅有“我懂了”的錯(cuò)覺(jué)還能把它講清楚讓一個(gè)完全沒(méi)接觸過(guò)的人照著做也能跑出結(jié)果。這種能力比單獨(dú)記住某個(gè)算法的公式值錢(qián)得多。