
作者 | Japson
來源 | 木東居士
0x00 前言
天下苦數學久矣!
對于很多想要入門機器學習的工程師來說,數學是通往AI道路上的第一支攔路虎。一些已經工作的同學不得不撿起早已還給老師的數學知識,勉強拿起《統計學習方法》、《西瓜書》等入門書籍鉆研?;虮灰粋€個復雜的機公式勸退,或記下一堆公式定理之后卻不知道和代碼有什么關系,茫然不知所措。
其實對于工程師來說,最直接的入門方法就是coding。
本系列從最簡單的機器學習算法“K-近鄰算法”開始,通過代碼走進機器學習的大門,搞定傳統機器學習算法。
首先會介紹算法的基本原理,然后依據原理手動實現算法,最后使用sklearn中提供的機器學習庫完成一些小demo。不用擔心,相關的機器學習概念以及算法原理也會穿插其中,幫助你以“代碼->原理->代碼”這種迭代的方式完成學習。
需要:
掌握Python語言,能夠使用Numpy、Pandas等工具庫。
安裝Anaconda
不要求對機器學習算法以及相關概念有很深刻的了解,因為在文章中會對首次出現的概念進行介紹。
子曰:“先行其言而后從之”。行動永遠是引發改變的第一步,話不多說,先讓我們碼起來吧!
0x01 初探kNN算法
為什么選擇kNN
首先KNN算法思想簡單樸素,容易理解,幾乎不需要任何數學知識。這一點使得KNN算法非常適合入門。
其次,KNN算法也很好用,理論成熟,簡單粗暴,既可以用來做分類(天然支持多分類),也可以用來做回歸。并且與樸素貝葉斯之類的算法相比,由于其對數據沒有假設,因此準確度高,對異常點不敏感。
最后,kNN算法簡單,但是可以解釋機器學習算法過程中的很多細節問題,能夠完整的刻畫機器學習應用的流程。
當然KNN算法也有缺點,我們會在最后進行總結。
kNN思想簡介
魯迅曾經說過:“想要了解一個人,就去看看他的朋友”。因此,KNN算法是魯迅發明的。
kNN(k-NearestNeighbor),也就是k最近鄰算法。顧名思義,所謂K最近鄰,就是k個最近的鄰居的意思。也就是在數據集中,認為每個樣本可以用離他最距離近的k個鄰居來代表。
貼出一張從百度百科上找的一張圖,我們可以直觀地感受到這樸素的思想:我們要判斷Xu 是什么顏色的,找到與其距離最近的5個點,有4個是紅色的,有1個是綠色的。因此我們認為Xu是屬于紅色的集合
因此我們說:
在一個給定的類別已知的訓練樣本集中,已知樣本集中每一個數據與所屬分類的對應關系(標簽)。在輸入不含有標簽的新樣本后,將新的數據的每個特征與樣本集中數據對應的特征進行比較,然后算法提取樣本最相似的k個數據(最近鄰)的分類標簽。通過多數表決等方式進行預測。即選擇k個最相似數據中出現次數最多的分類,作為新數據的分類。
K近鄰法不具有顯式的學習過程,而是利用訓練數據集對特征向量空間進行劃分,并作為其分類的“模型”。
kNN算法流程
通過理解算法思想,可以將其簡化為“找鄰居+投票”。K近鄰法使用的模型,實際上是特征空間的劃分。模型由三個基本要素決定:
其中兩個實例點之間的距離反映了相似程度。一般來說使用歐氏距離來計算。
梳理kNN算法流程如下:
0x02 算法實現
kNN算法自實現
打開Jupyter Notebook,創建Python3文件。
準備數據
首先我們準備一組數據:
import numpy as npimport matplotlib.pyplot as plt# raw_data_x是特征,raw_data_y是標簽,0為良性,1為惡性raw_data_X = [[3.393533211, 2.331273381], [3.110073483, 1.781539638], [1.343853454, 3.368312451], [3.582294121, 4.679917921], [2.280362211, 2.866990212], [7.423436752, 4.685324231], [5.745231231, 3.532131321], [9.172112222, 2.511113104], [7.927841231, 3.421455345], [7.939831414, 0.791631213] ] raw_data_y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]# 設置訓練組X_train = np.array(raw_data_X) y_train = np.array(raw_data_y)# 將數據可視化plt.scatter(X_train[y_train==0,0],X_train[y_train==0,1], color='g', label = 'Tumor Size') plt.scatter(X_train[y_train==1,0],X_train[y_train==1,1], color='r', label = 'Time') plt.xlabel('Tumor Size') plt.ylabel('Time') plt.axis([0,10,0,5]) plt.show()
數據可視化后生成的圖片如下圖所示。其中橫軸是腫塊大小,縱軸是發現時間。每個病人的腫塊大小和發病時間構成了二維平面特征中的一個點。對于每個點,我們通過label明確是惡性腫瘤(綠色)、良性腫瘤(紅色)。
那么現在給出一個腫瘤患者的數據(樣本點)x:[8.90933607318, 3.365731514],是良性腫瘤還是惡性腫瘤
求距離
我們要做的是:求點x到數據集中每個點的距離,首先計算距離,使用歐氏距離
下面寫代碼:
from math import sqrt distances = [] # 用來記錄x到樣本數據集中每個點的距離for x_train in X_train: d = sqrt(np.sum((x_train - x) ** 2)) distances.append(d)# 使用列表生成器,一行就能搞定,對于X_train中的每一個元素x_train都進行前面的運算,把結果生成一個列表distances = [sqrt(np.sum((x_train - x) ** 2)) for x_train in X_train] distances 輸出:[5.611968000921151, 6.011747706769277, 7.565483059418645, 5.486753308891268, 6.647709180746875, 1.9872648870854204, 3.168477291709152, 0.8941051007010301, 0.9830754144862234, 2.7506238644678445]
在求出距離列表之后,我們要找到最小的距離,需要進行一次排序操作。其實不是簡單的排序,因為我們把只將距離排大小是沒有意義的,我們要知道距離最小的k個點是在樣本集中的位置。
這里我們使用函數:np.argsort(array) 對一個數組進行排序,返回的是相應的排序后結果的索引
nearest = np.argsort(distances) nearest 輸出:array([7, 8, 5, 9, 6, 3, 0, 1, 4, 2]) 結果的含義是:距離最小的點在distances數組中的索引是7,第二小的點索引是8... 近到遠是哪些點
選k值
然后我們選擇k值,這里暫定為6,那就找出最近的6個點(top 6),并記錄他們的標簽值(y)
k = 6topK_y = [y_train[i] for i in nearest[:k]] topK_y 輸出:[1, 1, 1, 1, 1, 0]
決策規則
下面進入投票環節。找到與測試樣本點最近的6個訓練樣本點的標簽y是什么??梢圆椴煌悇e的點有多少個。
將數組中的元素和元素出現的頻次進行統計
from collections import Counter votes = Counter(topK_y) votes 輸出:一個字典,原數組中值為0的個數為1,值為1的個數有為5Counter({0:1, 1:5}) # Counter.most_common(n) 找出票數最多的n個元素,返回的是一個列表,列表中的每個元素是一個元組,元組中第一個元素是對應的元素是誰,第二個元素是頻次votes.most_common(1) 輸出:[(1,5)] predict_y = votes.most_common(1)[0][0] predict_y 輸出:1
得到預測的y值是1
自實現完整工程代碼
我們已經在jupyter notebook中寫好了kNN算法,下面我們在外部進行封裝。
相關代碼可以在 https://github.com/japsonzbz/ML_Algorithms 中看到
import numpy as npimport math as sqrtfrom collections import Counterclass kNNClassifier: def __init__(self, k): """初始化分類器""" assert k >= 1, "k must be valid" self.k = k self._X_train = None self._y_train = None def fit(self, X_train, y_train): """根據訓練數據集X_train和y_train訓練kNN分類器""" assert X_train.shape[0] == y_train.shape[0], \ "the size of X_train must be equal to the size of y_train" assert self.k <= X_train.shape[0], \ "the size of X_train must be at least k" self._X_train = X_train self._y_train = y_train return self def predict(self,X_predict): """給定待預測數據集X_predict,返回表示X_predict結果的向量""" assert self._X_train is not None and self._y_train is not None, \ "must fit before predict!" assert X_predict.shape[1] == self._X_train.shape[1], \ "the feature number of X_predict must be equal to X_train" y_predict = [self._predict(x) for x in X_predict] return np.array(y_predict) def _predict(self, x): distances = [sqrt(np.sum((x_train - x) ** 2)) for x_train in self._X_train] nearest = np.argsort(distances) topK_y = [self._y_train[i] for i in nearest] votes = Counter(topK_y) return votes.most_common(1)[0][0] def __repr__(self): return "kNN(k=%d)" % self.k
當我們寫完定義好自己的kNN代碼之后,可以在jupyter notebook中使用魔法命令進行調用:
%run myAlgorithm/kNN.py knn_clf = kNNClassifier(k=6) knn_clf.fit(X_train, y_train) X_predict = x.reshape(1,-1) y_predict = knn_clf.predict(X_predict) y_predict 輸出:array([1])
現在我們就完成了一個sklearn風格的kNN算法,但是實際上,sklearn封裝的算法比我們實現的要復雜得多。
sklearn中的kNN
代碼
對于機器學習來說,其流程是:訓練數據集 -> 機器學習算法 -fit-> 模型 輸入樣例 -> 模型 -predict-> 輸出結果
我們之前說過,kNN算法沒有模型,模型其實就是訓練數據集,predict的過程就是求k近鄰的過程。
我們使用sklearn中已經封裝好的kNN庫。你可以看到使用有多么簡單。
from sklearn.neighbors import KNeighborsClassifier# 創建kNN_classifier實例kNN_classifier = KNeighborsClassifier(n_neighbors=6)# kNN_classifier做一遍fit(擬合)的過程,沒有返回值,模型就存儲在kNN_classifier實例中kNN_classifier.fit(X_train, y_train)# kNN進行預測predict,需要傳入一個矩陣,而不能是一個數組。reshape()成一個二維數組,第一個參數是1表示只有一個數據,第二個參數-1,numpy自動決定第二維度有多少y_predict = kNN_classifier.predict(x.reshape(1,-1)) y_predict 輸出:array([1])
在kNN_classifier.fit(X_train, y_train)這行代碼后其實會有一個輸出:
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski', metric_params=None, n_jobs=1, n_neighbors=6, p=2, weights='uniform')
參數
class sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, weights=’uniform’, algorithm=’auto’, leaf_size=30, p=2, metric=’minkowski’, metric_params=None, n_jobs=None, **kwargs)
我們研究一下參數:
方法
對于KNeighborsClassifier的方法:
方法名含義fit(X, y)使用X作為訓練數據,y作為目標值(類似于標簽)來擬合模型。get_params([deep])獲取估值器的參數。neighbors([X, n_neighbors, return_distance])查找一個或幾個點的K個鄰居。kneighbors_graph([X, n_neighbors, mode])計算在X數組中每個點的k鄰居的(權重)圖。predict(X)給提供的數據預測對應的標簽。predict_proba(X)返回測試數據X的概率估值。score(X, y[, sample_weight])返回給定測試數據和標簽的平均準確值。set_params(**params)設置估值器的參數。
0xFF 總結
在本文中我們了解了第一個ML算法kNN,kNN憑借著自己樸素成熟的特點成為機器學習的敲門磚。
然后我們學習了kNN算法的流程,并且在jupyter notebook上手動實現了代碼,并且在外部也進行了封裝。最后我們學習了sklearn中的kNN算法。
雖然我們自己實現了一個機器學習算法,但是它的效果怎樣樣?預測準確率高不高?我們在機器學習過程中還有哪些需要注意的問題呢?
且聽下回分解。
數據分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
解碼數據基因:從數字敏感度到邏輯思維 每當看到超市貨架上商品的排列變化,你是否會聯想到背后的銷售數據波動?三年前在零售行 ...
2025-05-23在本文中,我們將探討 AI 為何能夠加速數據分析、如何在每個步驟中實現數據分析自動化以及使用哪些工具。 數據分析中的AI是什么 ...
2025-05-20當數據遇見人生:我的第一個分析項目 記得三年前接手第一個數據分析項目時,我面對Excel里密密麻麻的銷售數據手足無措。那些跳動 ...
2025-05-20在數字化運營的時代,企業每天都在產生海量數據:用戶點擊行為、商品銷售記錄、廣告投放反饋…… 這些數據就像散落的拼圖,而相 ...
2025-05-19在當今數字化營銷時代,小紅書作為國內領先的社交電商平臺,其銷售數據蘊含著巨大的商業價值。通過對小紅書銷售數據的深入分析, ...
2025-05-16Excel作為最常用的數據分析工具,有沒有什么工具可以幫助我們快速地使用excel表格,只要輕松幾步甚至輸入幾項指令就能搞定呢? ...
2025-05-15數據,如同無形的燃料,驅動著現代社會的運轉。從全球互聯網用戶每天產生的2.5億TB數據,到制造業的傳感器、金融交易 ...
2025-05-15大數據是什么_數據分析師培訓 其實,現在的大數據指的并不僅僅是海量數據,更準確而言是對大數據分析的方法。傳統的數 ...
2025-05-14CDA持證人簡介: 萬木,CDA L1持證人,某電商中廠BI工程師 ,5年數據經驗1年BI內訓師,高級數據分析師,擁有豐富的行業經驗。 ...
2025-05-13CDA持證人簡介: 王明月 ,CDA 數據分析師二級持證人,2年數據產品工作經驗,管理學博士在讀。 學習入口:https://edu.cda.cn/g ...
2025-05-12CDA持證人簡介: 楊貞璽 ,CDA一級持證人,鄭州大學情報學碩士研究生,某上市公司數據分析師。 學習入口:https://edu.cda.cn/g ...
2025-05-09CDA持證人簡介 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度、美團、阿里等 ...
2025-05-07相信很多做數據分析的小伙伴,都接到過一些高階的數據分析需求,實現的過程需要用到一些數據獲取,數據清洗轉換,建模方法等,這 ...
2025-05-06以下的文章內容來源于劉靜老師的專欄,如果您想閱讀專欄《10大業務分析模型突破業務瓶頸》,點擊下方鏈接 https://edu.cda.cn/g ...
2025-04-30CDA持證人簡介: 邱立峰 CDA 數據分析師二級持證人,數字化轉型專家,數據治理專家,高級數據分析師,擁有豐富的行業經驗。 ...
2025-04-29CDA持證人簡介: 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度,美團,阿里等 ...
2025-04-28CDA持證人簡介: 居瑜 ,CDA一級持證人國企財務經理,13年財務管理運營經驗,在數據分析就業和實踐經驗方面有著豐富的積累和經 ...
2025-04-27數據分析在當今信息時代發揮著重要作用。單因素方差分析(One-Way ANOVA)是一種關鍵的統計方法,用于比較三個或更多獨立樣本組 ...
2025-04-25CDA持證人簡介: 居瑜 ,CDA一級持證人國企財務經理,13年財務管理運營經驗,在數據分析就業和實踐經驗方面有著豐富的積累和經 ...
2025-04-25在當今數字化時代,數據分析師的重要性與日俱增。但許多人在踏上這條職業道路時,往往充滿疑惑: 如何成為一名數據分析師?成為 ...
2025-04-24