【机器学习入门】(1) K近邻算法:原理、实例应用(红酒分类预测)附python完整代码及数据集
各位同學(xué)好,今天我向大家介紹一下python機(jī)器學(xué)習(xí)中的K近鄰算法。內(nèi)容有:K近鄰算法的原理解析;實(shí)戰(zhàn)案例--紅酒分類預(yù)測(cè)。紅酒數(shù)據(jù)集、完整代碼在文章最下面。
案例簡(jiǎn)介:有178個(gè)紅酒樣本,每一款紅酒含有13項(xiàng)特征參數(shù),如鎂、脯氨酸含量,紅酒根據(jù)這些特征參數(shù)被分成3類。要求是任意輸入一組紅酒的特征參數(shù),模型需預(yù)測(cè)出該紅酒屬于哪一類。
1. K近鄰算法介紹
1.1 算法原理
? ? ? ?原理:如果一個(gè)樣本在特征空間中的k個(gè)最相似(即特征空間中最鄰近)的樣本中的大多數(shù)屬于某一個(gè)類別,那么該樣本也屬于這個(gè)類別。簡(jiǎn)單來說就是,求兩點(diǎn)之間的距離,看距離誰是最近的,以此來區(qū)分我們要預(yù)測(cè)的這個(gè)數(shù)據(jù)是屬于哪個(gè)分類。
? ? ? ?我們看圖來理解一下。藍(lán)色點(diǎn)是屬于a類型的樣本點(diǎn),粉色點(diǎn)是屬于b類型的樣本點(diǎn)。此時(shí)新來了一個(gè)點(diǎn)(黃色點(diǎn)),怎么判斷是屬于它是a類型還是b類型呢。
? ? ? ? 方法是:新點(diǎn)找距離自身最近的k個(gè)點(diǎn)(k可變)。分別計(jì)算新點(diǎn)到其他各個(gè)點(diǎn)的距離,按距離從小到大排序,找出距離自身最近的k個(gè)點(diǎn)。統(tǒng)計(jì)在這k個(gè)點(diǎn)中,有多少點(diǎn)屬于a類,有多少點(diǎn)屬于b類。在這k個(gè)點(diǎn)中,如果屬于b類的點(diǎn)更多,那么這個(gè)新點(diǎn)也屬于b分類。距離計(jì)算公式也是我們熟悉的勾股定理。?
?
1.2 算法優(yōu)缺點(diǎn)
算法優(yōu)點(diǎn):簡(jiǎn)單易理解、無需估計(jì)參數(shù)、無需訓(xùn)練。適用于幾千-幾萬的數(shù)據(jù)量。
算法缺點(diǎn):對(duì)測(cè)試樣本計(jì)算時(shí)的計(jì)算量大,內(nèi)存開銷大,k值要不斷地調(diào)整來達(dá)到最優(yōu)效果。k值取太小容易受到異常點(diǎn)的影響,k值取太多產(chǎn)生過擬合,影響準(zhǔn)確性。
2. 紅酒數(shù)據(jù)集
2.1 數(shù)據(jù)集獲取方式
? ? ? ?紅酒數(shù)據(jù)集是Scikit-learn庫(kù)中自帶的數(shù)據(jù)集,我們只需要直接調(diào)用它,然后打亂它的順序來進(jìn)行我們自己的分類預(yù)測(cè)。首先我們導(dǎo)入Scikit-learn庫(kù),如果大家使用的是anaconda的話,這個(gè)庫(kù)中的數(shù)據(jù)集都是提前安裝好了的,我們只需要調(diào)用它即可。
找不到這個(gè)數(shù)據(jù)集的,我把紅酒數(shù)據(jù)集連接放在文末了,有需要的自取。
Scikit-learn數(shù)據(jù)集獲取方法:
(1)用于獲取小規(guī)模數(shù)據(jù)集,數(shù)據(jù)集已在系統(tǒng)中安裝好了的
sklearn.datasets.load_數(shù)據(jù)名() ?
from sklearn import datasets
#系統(tǒng)中已有的波士頓房?jī)r(jià)數(shù)據(jù)集
boston = datasets.load_boston()
(2)遠(yuǎn)程獲取大規(guī)模數(shù)據(jù)集安裝到本地,data_home默認(rèn)是位置是/scikit_learn_data/
sklearn.datasets.fetch_數(shù)據(jù)名(data_home = 數(shù)據(jù)集下載目錄) ?
# 20年的新聞數(shù)據(jù)下載到
datasets.fetch_20newsgroups(data_home = './newsgroups.csv') #指定文件位置
這兩種方法返回的數(shù)據(jù)是?.Bunch類型,它有如下屬性:
data:特征數(shù)據(jù)二維數(shù)組;相當(dāng)于x變量
target:標(biāo)簽數(shù)組;相當(dāng)于y變量
DESCR:數(shù)據(jù)描述
feature_names:特征名。新聞數(shù)據(jù)、手寫數(shù)據(jù)、回歸數(shù)據(jù)沒有
target_name:標(biāo)簽名。回歸數(shù)據(jù)沒有
想知道還能獲取哪些數(shù)據(jù)集的同學(xué),可去下面這個(gè)網(wǎng)址查看具體操作:
https://sklearn.apachecn.org/#/docs/master/47
2.2 獲取紅酒數(shù)據(jù)
? ? ? ?首先導(dǎo)入sklearn的本地?cái)?shù)據(jù)集庫(kù),變量wine獲取紅酒數(shù)據(jù),由于wine接收的返回值是.Bunch類型的數(shù)據(jù),因此我用win_data接收所有特征值數(shù)據(jù),它是178行13列的數(shù)組,每一列代表一種特征。win_target用來接收所有的目標(biāo)值,本數(shù)據(jù)集中的目標(biāo)值為0、1、2三類紅酒。如果大家想更仔細(xì)的觀察這個(gè)數(shù)據(jù)集,可以通過wine.DESCR來看這個(gè)數(shù)據(jù)集的具體描述。
? ? ? ? 然后把我們需要的數(shù)據(jù)轉(zhuǎn)換成DataFrame類型的數(shù)據(jù)。為了使預(yù)測(cè)更具有一般性,我們把這個(gè)數(shù)據(jù)集打亂。操作如下:
from sklearn import datasets
wine = datasets.load_wine() # 獲取葡萄酒數(shù)據(jù)
wine_data = wine.data #獲取葡萄酒的索引data數(shù)據(jù),178行13列
wine_target = wine.target #獲取分類目標(biāo)值# 將數(shù)據(jù)轉(zhuǎn)換成DataFrame類型
wine_data = pd.DataFrame(data = wine_data)
wine_target = pd.DataFrame(data = wine_target)# 將wine_target插入到第一列,并給這一列的列索引取名為'class'
wine_data.insert(0,'class',wine_target)# ==1== 變量.sample(frac=1) 表示洗牌,重新排序
# ==2== 變量.reset_index(drop=True) 使index從0開始排序wine = wine_data.sample(frac=1).reset_index(drop=True) #把DataFrame的行順序打亂
?
? ? ? 我們取出最后10行數(shù)據(jù)用作后續(xù)的驗(yàn)證預(yù)測(cè)結(jié)果是否正確,這10組數(shù)據(jù)分出特征值(相當(dāng)于x)和目標(biāo)值(相當(dāng)于y)。剩下的數(shù)據(jù)也分出特征值features和目標(biāo)值targets,用于模型訓(xùn)練。剩下的數(shù)據(jù)中還要?jiǎng)澐殖鲇?xùn)練集和測(cè)試集,下面再詳述。到此,數(shù)據(jù)處理這塊完成。
#取后10行,用作最后的預(yù)測(cè)結(jié)果檢驗(yàn)。并且讓index從0開始,也可以不寫.reset_index(drop=True)
wine_predict = wine[-10:].reset_index(drop=True)
# 讓特征值等于去除'class'后的數(shù)據(jù)
wine_predict_feature = wine_predict.drop('class',axis=1)
# 讓目標(biāo)值等于'class'這一列
wine_predict_target = wine_predict['class']wine = wine[:-10] #去除后10行
features = wine.drop(columns=['class'],axis=1) #刪除class這一列,產(chǎn)生返回值
targets = wine['class'] #class這一列就是目標(biāo)值
3. 紅酒分類預(yù)測(cè)
3.1 劃分測(cè)試集和訓(xùn)練集
一般采用75%的數(shù)據(jù)用于訓(xùn)練,25%用于測(cè)試,因此在數(shù)據(jù)進(jìn)行預(yù)測(cè)之前,先要對(duì)數(shù)據(jù)劃分。
劃分方式:
使用sklearn.model_selection.train_test_split 模塊進(jìn)行數(shù)據(jù)分割。
x_train,x_test,y_train,y_test = train_test_split(x, y, test_size=數(shù)據(jù)占比)
train_test_split() 括號(hào)內(nèi)的參數(shù):
x:數(shù)據(jù)集特征值(features)
y:數(shù)據(jù)集目標(biāo)值(targets)
test_size: 測(cè)試數(shù)據(jù)占比,用小數(shù)表示,如0.25表示,75%訓(xùn)練train,25%測(cè)試test。
train_test_split() 的返回值:
x_train:訓(xùn)練部分特征值
x_test:? ? 測(cè)試部分特征值
y_train:訓(xùn)練部分目標(biāo)值
y_test:? ? 測(cè)試部分目標(biāo)值
# 劃分測(cè)試集和訓(xùn)練集
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(features,targets,test_size=0.25)
3.2 數(shù)據(jù)標(biāo)準(zhǔn)化
? ? ? ?由于不同數(shù)據(jù)的單位不同,數(shù)據(jù)間的跨度較大,對(duì)結(jié)果影響較大,因此需要進(jìn)行數(shù)據(jù)縮放,例如歸一化和標(biāo)準(zhǔn)化。考慮到歸一化的缺點(diǎn):如果異常值較多,最大值和最小值間的差值較大,會(huì)造成很大影響。我采用數(shù)據(jù)標(biāo)準(zhǔn)化的方法,采用方差標(biāo)準(zhǔn)差,使標(biāo)準(zhǔn)化后的數(shù)據(jù)均值為0,標(biāo)準(zhǔn)差為1,使數(shù)據(jù)滿足標(biāo)準(zhǔn)正態(tài)分布。
# 先標(biāo)準(zhǔn)化再預(yù)測(cè)
from sklearn.preprocessing import StandardScaler #導(dǎo)入標(biāo)準(zhǔn)化縮放方法
scaler = StandardScaler() #變量scaler接收標(biāo)準(zhǔn)化方法
# 傳入特征值進(jìn)行標(biāo)準(zhǔn)化
# 對(duì)訓(xùn)練的特征值標(biāo)準(zhǔn)化
x_train = scaler.fit_transform(x_train)
# 對(duì)測(cè)試的特征值標(biāo)準(zhǔn)化
x_test = scaler.fit_transform(x_test)
# 對(duì)驗(yàn)證結(jié)果的特征值標(biāo)準(zhǔn)化
wine_predict_feature = scaler.fit_transform(wine_predict_feature)
?3.3 K近鄰預(yù)測(cè)分類
使用sklearn實(shí)現(xiàn)k近鄰算法
from sklearn.neighbors import KNeighborsClassifier?
KNeighborsClassifier(n_neighbors = 鄰居數(shù),algorithm = '計(jì)算最近鄰居算法')
.fit(x_train,y_train)
KNeighborsClassifier()?括號(hào)內(nèi)的參數(shù):
n_neighbors:int類型,默認(rèn)是5,可以自己更改。(找出離自身最近的k個(gè)點(diǎn))
algorithm:用于計(jì)算最近鄰居的算法。有:'ball_tree'、'kd_tree'、'auto'。默認(rèn)是'auto',根據(jù)傳遞給fit()方法的值來決定最合適的算法,自動(dòng)選擇前兩個(gè)方法中的一個(gè)。
from sklearn.neighbors import KNeighborsClassifier #導(dǎo)入k近鄰算法庫(kù)
# k近鄰函數(shù)
knn = KNeighborsClassifier(n_neighbors=5,algorithm='auto')
# 把訓(xùn)練的特征值和訓(xùn)練的目標(biāo)值傳進(jìn)去
knn.fit(x_train,y_train)
? ? ? ? 將訓(xùn)練所需的特征值和目標(biāo)值傳入.fit()方法之后,即可開始預(yù)測(cè)。首先利用.score()評(píng)分法輸入用于測(cè)試的特征值和目標(biāo)值,來看一下這個(gè)模型的準(zhǔn)確率是多少,是否是滿足要求,再使用.predict()方法預(yù)測(cè)所需要的目標(biāo)值。
評(píng)分法:根據(jù)x_test預(yù)測(cè)結(jié)果,把結(jié)果和真實(shí)的y_test比較,計(jì)算準(zhǔn)確率
.score(x_test, y_test)
預(yù)測(cè)方法:
.predict(用于預(yù)測(cè)的特征值)
# 評(píng)分法計(jì)算準(zhǔn)確率
accuracy = knn.score(x_test,y_test)
# 預(yù)測(cè),輸入預(yù)測(cè)用的x值
result = knn.predict(wine_predict_feature)
? ? ? ?accuracy存放準(zhǔn)確率,result存放預(yù)測(cè)結(jié)果,最終準(zhǔn)確率為0.952,最終的分類結(jié)果和wine_predict_target存放的實(shí)際分類結(jié)果有微小偏差。
紅酒數(shù)據(jù)集免費(fèi)獲取:
python實(shí)戰(zhàn)K近鄰算法,紅酒分類預(yù)測(cè)數(shù)據(jù)集.xls-Python文檔類資源-CSDN下載
完整代碼如下:
python機(jī)器學(xué)習(xí)K近鄰算法--紅酒分類預(yù)測(cè).py-Python文檔類資源-CSDN下載
import pandas as pd
from sklearn import datasetswine = datasets.load_wine() # 獲取葡萄酒數(shù)據(jù)
wine_data = wine.data #獲取葡萄酒的索引data數(shù)據(jù),178行13列
wine_target = wine.target #獲取分類目標(biāo)值wine_data = pd.DataFrame(data = wine_data) #轉(zhuǎn)換成DataFrame類型數(shù)據(jù)
wine_target = pd.DataFrame(data = wine_target)
# 將target插入到第一列
wine_data.insert(0,'class',wine_target)# ==1== 變量.sample(frac=1) 表示洗牌,重新排序
# ==2== 變量.reset_index(drop=True) 使index從0開始排序,可以省略這一步
wine = wine_data.sample(frac=1).reset_index(drop=True)# 拿10行出來作驗(yàn)證
wine_predict = wine[-10:].reset_index(drop=True)
wine_predict_feature = wine_predict.drop('class',axis=1) #用于驗(yàn)證的特征值,輸入到predict()函數(shù)中
wine_predict_target = wine_predict['class'] #目標(biāo)值,用于和最終預(yù)測(cè)結(jié)果比較wine = wine[:-10] #刪除后10行
features = wine.drop(columns=['class'],axis=1) #刪除class這一列,產(chǎn)生返回值,這個(gè)是特征值
targets = wine['class'] #class這一列就是目標(biāo)值
# 相當(dāng)于13個(gè)特征值對(duì)應(yīng)1個(gè)目標(biāo)# 劃分測(cè)試集和訓(xùn)練集
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(features,targets,test_size=0.25)# 先標(biāo)準(zhǔn)化再預(yù)測(cè)
from sklearn.preprocessing import StandardScaler #導(dǎo)入標(biāo)準(zhǔn)化縮放方法
scaler = StandardScaler() #變量scaler接收標(biāo)準(zhǔn)化方法# 傳入特征值進(jìn)行標(biāo)準(zhǔn)化
x_train = scaler.fit_transform(x_train) #對(duì)訓(xùn)練的特征值標(biāo)準(zhǔn)化
x_test = scaler.fit_transform(x_test) #對(duì)測(cè)試的特征值標(biāo)準(zhǔn)化
wine_predict_feature = scaler.fit_transform(wine_predict_feature)# 使用K近鄰算法分類
from sklearn.neighbors import KNeighborsClassifier #導(dǎo)入k近鄰算法庫(kù)
# k近鄰函數(shù)
knn = KNeighborsClassifier(n_neighbors=5,algorithm='auto')# 訓(xùn)練,把訓(xùn)練的特征值和訓(xùn)練的目標(biāo)值傳進(jìn)去
knn.fit(x_train,y_train)
# 檢測(cè)模型正確率--傳入測(cè)試的特征值和目標(biāo)值
# 評(píng)分法,根據(jù)x_test預(yù)測(cè)結(jié)果,把結(jié)果和真實(shí)的y_test比較,計(jì)算準(zhǔn)確率
accuracy = knn.score(x_test,y_test)
# 預(yù)測(cè),輸入預(yù)測(cè)用的x值
result = knn.predict(wine_predict_feature)
總結(jié)
以上是生活随笔為你收集整理的【机器学习入门】(1) K近邻算法:原理、实例应用(红酒分类预测)附python完整代码及数据集的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Pandas库】(5) 索引操作--增
- 下一篇: 【机器学习入门】(2) 朴素贝叶斯算法: