日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

k近邻回归算法python_经典算法之K近邻(回归部分)

發(fā)布時(shí)間:2025/3/15 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 k近邻回归算法python_经典算法之K近邻(回归部分) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.算法原理

1.分類和回歸

分類模型和回歸模型本質(zhì)一樣,分類模型是將回歸模型的輸出離散化。

一般來說,回歸問題通常是用來預(yù)測(cè)一個(gè)值,如預(yù)測(cè)房價(jià)、未來的天氣情況等等,例如一個(gè)產(chǎn)品的實(shí)際價(jià)格為500元,通過回歸分析預(yù)測(cè)值為499元,我們認(rèn)為這是一個(gè)比較好的回歸分析。回歸是對(duì)真實(shí)值的一種逼近預(yù)測(cè)。

分類問題是用于將事物打上一個(gè)標(biāo)簽,通常結(jié)果為離散值。例如判斷一幅圖片上的動(dòng)物是一只貓還是一只狗。分類并沒有逼近的概念,最終正確結(jié)果只有一個(gè),錯(cuò)誤的就是錯(cuò)誤的,不會(huì)有相近的概念。

簡言之:

定量輸出稱為回歸,或者說是連續(xù)變量預(yù)測(cè),預(yù)測(cè)明天的氣溫是多少度,這是一個(gè)回歸任務(wù)

定性輸出稱為分類,或者說是離散變量預(yù)測(cè),預(yù)測(cè)明天是陰、晴還是雨,就是一個(gè)分類任務(wù)

2.KNN回歸

KNN算法不僅可以用于分類,還可以用于回歸。通過找出一個(gè)樣本的k個(gè)最近鄰居,將這些鄰居的某個(gè)(些)屬性的平均值賦給該樣本,就可以得到該樣本對(duì)應(yīng)屬性的值。

3.原理

問題引入

我有個(gè)3個(gè)臥室的房子,租多少錢呢?

不知道的話,就去看看別人3個(gè)臥室的房子都租多少錢吧!

其中,K代表我們的候選對(duì)象個(gè)數(shù),也就是找和我房間數(shù)量最相近的K個(gè)房子的價(jià)格,做一定的處理后(例如平均),作為我們房子的出租價(jià)格。

那么,如何衡量和我的房子最相近呢?如何評(píng)估我們得到的出租價(jià)格的好壞呢?

K近鄰原理

假設(shè)我們的數(shù)據(jù)源中只有5條信息,現(xiàn)在我想針對(duì)我的房子(只有一個(gè)房間)來定一個(gè)價(jià)格。

在這里假設(shè)我們選擇的K=3,也就是選3個(gè)跟我最相近的房源。

再綜合考慮這三個(gè)只有房子的價(jià)格,就得到了我的房子大概能值多錢啦!

如何才能知道哪些數(shù)據(jù)樣本跟我最相近呢?

歐氏距離公式:

其中p1到pn是一條數(shù)據(jù)的所有特征信息,q1到qn是另一條數(shù)據(jù)的所有特征信息。

4.舉例說明

假設(shè)我們的房子有3個(gè)房間

單變量下的距離定義簡化為:

讀取數(shù)據(jù):

importpandas as pd

features= ['accommodates','bedrooms','bathrooms','beds','price','minimum_nights','maximum_nights','number_of_reviews']

dc_listings= pd.read_csv('listings.csv')

dc_listings=dc_listings[features]print(dc_listings.shape)

dc_listings.head()

僅取以單個(gè)指標(biāo)accommodates的個(gè)數(shù)來計(jì)算每個(gè)樣本到我們的距離:

代碼實(shí)現(xiàn)如下:

importnumpy as np#定義我們的accomodates個(gè)數(shù)為3

our_acc_value = 3

#新增一列distance,記錄每個(gè)樣本到3的距離#np.abs函數(shù)用于計(jì)算絕對(duì)值#通過dc_listings.accommodates取出accommodates列的所有數(shù)據(jù)#可通過dc_listings.accommodates取值#也可通過字典的形式取值,dc_listings['accommodates']或dc_listings.get('accommodates')

dc_listings['distance'] = np.abs(dc_listings.accommodates -our_acc_value)#取出結(jié)果列distance#value_counts()統(tǒng)計(jì)個(gè)數(shù)#sort_index()按照索引distance排序

dc_listings.distance.value_counts().sort_index()

輸出結(jié)果:

0 461

1 2294

2 503

3 279

4 35

5 73

6 17

7 22

8 7

9 12

10 2

11 4

12 6

13 8Name: distance, dtype: int64

從結(jié)果中可以看出,以房間個(gè)數(shù)來衡量的話,同樣有3個(gè)房間的樣本一共461個(gè)

假設(shè)K=5,即取距離我們最近的五個(gè)樣本的價(jià)格取平均值,作為我們的出租價(jià)格。

#使用sample函數(shù),進(jìn)行洗牌操作,將數(shù)據(jù)隨機(jī)打亂#farc = 1 表示選擇100%的數(shù)據(jù)#random_stare-0 表示設(shè)置隨機(jī)種子

dc_listings = dc_listings.sample(frac=1, random_state=0)#以instance為索引,進(jìn)行升序排序

dc_listings = dc_listings.sort_values('distance')#取出價(jià)格列

price =dc_listings.price#對(duì)價(jià)格進(jìn)行一定的處理,去掉$和,兩個(gè)符號(hào),并轉(zhuǎn)化為float類型dc_listings['price'] = price.str.replace(r'\$|,', '').astype(float)

#取K=5時(shí),預(yù)測(cè)的出租價(jià)格

pre_price = dc_listings.price.iloc[:5].mean()print(pre_price)

得到了平均價(jià)格,也就是我們的房子大致的價(jià)格了。這個(gè)就是KNN回歸預(yù)測(cè)的整個(gè)過程。這里僅做一個(gè)例子,旨在說明KNN回歸的過程。

實(shí)際情況下,我們有很多個(gè)樣本,而且每個(gè)樣本不僅僅只有一個(gè)accomodate屬性。

2.基于單變量預(yù)測(cè)價(jià)格

實(shí)際情況下,一般將樣本劃分為兩部分,一部分用作訓(xùn)練(稱之為訓(xùn)練集)用于訓(xùn)練模型;一部分用作測(cè)試(稱之為測(cè)試集)對(duì)訓(xùn)練出的模型進(jìn)行評(píng)估。

繼續(xù)上面的數(shù)據(jù)進(jìn)行演示,此時(shí)的數(shù)據(jù)長這個(gè)樣子:

輸入以下代碼,構(gòu)造訓(xùn)練集和測(cè)試集。

#刪除distance列, axis=1表示按列刪除

dc_listings.drop('distance', axis=1)#訓(xùn)練集,取前2792行作為訓(xùn)練集

df_train = dc_listings.copy().iloc[:2792]#測(cè)試集,剩下的作為測(cè)試集

df_test = dc_listings.copy().iloc[2792:]

僅考慮accommodates一個(gè)衡量指標(biāo)下,對(duì)測(cè)試集中的所有樣本的價(jià)格進(jìn)行預(yù)測(cè),并與真實(shí)值進(jìn)行對(duì)比。

defpredict_price(new_listing_value, fea_col):"""對(duì)房子出租價(jià)格進(jìn)行預(yù)測(cè),K取值5

new_listing_value :

fea_col: 特征列,參考的特征"""df_temp= df_train #導(dǎo)入訓(xùn)練集數(shù)據(jù)

#在df_temp中添加一列,用于記錄距離

df_temp['distance'] = np.abs(df_train[fea_col] -new_listing_value)#按照distance索引進(jìn)行升序排序

df_temp = df_temp.sort_values('distance')#取距離最近的前5行數(shù)據(jù)

KNN_5 = df_temp.price.iloc[:5]#取平均值作為預(yù)測(cè)值

predict_price =KNN_5.mean()return predict_price

例如,上文中的預(yù)測(cè)accomodates為3的價(jià)格,那么fea_col = 'accomodates', new_listing_value=3;

那么,對(duì)于測(cè)試集中的樣本,accomodates屬性值(即new_listing_value)是不同的,使用apply函數(shù),循環(huán)調(diào)用預(yù)測(cè)函數(shù),并得到測(cè)試樣本中每個(gè)樣本的預(yù)測(cè)值。

#取測(cè)試集中,每個(gè)樣本的accomodates值#應(yīng)用predice_price函數(shù),得到預(yù)測(cè)值#并新增一列predict_price記錄預(yù)測(cè)值

df_test['predict_price'] = df_test.accommodates.apply(predict_price, fea_col='accommodates')#取出預(yù)測(cè)值與真實(shí)值這兩列,對(duì)比

df_test[['predict_price', 'price']]

部分輸出結(jié)果:

那么,如何評(píng)判預(yù)測(cè)結(jié)果的好壞呢?

3.誤差評(píng)估

一般采用均方根誤差(root mean squared error,RMSE)作為誤差評(píng)估指標(biāo),誤差越大,說明預(yù)測(cè)效果越差。

因此,基于上文內(nèi)容,計(jì)算測(cè)試集總的均方根誤差:

#求出預(yù)測(cè)值與真實(shí)值差值的平方

df_test['squared_error'] = (df_test.predict_price - df_test.price)**2

#求差值均值

mse =df_test.squared_error.mean()#求均方差誤差

rmse = mse ** (1/2)print(rmse)

如此,就得到了對(duì)于一個(gè)變量的模型評(píng)估分。

結(jié)果輸出:

顯然,此誤差值較大,可見僅僅用一個(gè)指標(biāo),結(jié)果不一定靠譜。

那么,如何能降低這個(gè)預(yù)測(cè)的誤差呢?顯然需要利用多個(gè)指標(biāo)對(duì)房子的價(jià)格進(jìn)行評(píng)估。但是不同指標(biāo)的單位不同,且相差較大。

因此,考慮將數(shù)據(jù)進(jìn)行一定的處理,將所有數(shù)據(jù)都處理成不受單位影響的指標(biāo)。

4.數(shù)據(jù)標(biāo)準(zhǔn)化與歸一化

一般將數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化或歸一化處理,使其不受單位影響。

z-score標(biāo)準(zhǔn)化

z-score標(biāo)準(zhǔn)化是將數(shù)據(jù)按比例縮放,使之落入一個(gè)特定區(qū)間。 要求:均值 μ = 0 ,σ = 1

標(biāo)準(zhǔn)差公式:

z-score標(biāo)準(zhǔn)化轉(zhuǎn)換公式:

歸一化

歸一化:把數(shù)變?yōu)?0,1)之間的小數(shù)

歸一化公式:

這里利用sklearn的MinMaxScaler和StandardScaler兩個(gè)類,對(duì)所有數(shù)據(jù)進(jìn)行歸一化處理。

importpandas as pdfrom sklearn importpreprocessingfrom sklearn.preprocessing importMinMaxScalerfrom sklearn.preprocessing importStandardScaler#讀取數(shù)據(jù)

features = ['accommodates','bedrooms','bathrooms','beds','price','minimum_nights','maximum_nights','number_of_reviews']

dc_listings= pd.read_csv(r'D:\codes_jupyter\數(shù)據(jù)分析_learning\課件\05_K近鄰\listings.csv', engine='python')

dc_listings=dc_listings[features]#對(duì)price列進(jìn)行一定的處理,使其變成float型

dc_listings['price'] = dc_listings.price.str.replace(r'\$|,', '').astype(float)#對(duì)缺失值進(jìn)行處理,刪除有缺失值的數(shù)據(jù)

dc_listings =dc_listings.dropna()#歸一化

dc_listings[features] =MinMaxScaler().fit_transform(dc_listings)#標(biāo)準(zhǔn)化#dc_listings[features] = StandardScaler().fit_transform(dc_listings)

print(dc_listings.shape)

dc_listings.head()

輸出結(jié)果如下:

得到標(biāo)準(zhǔn)化的數(shù)據(jù)后,就可以利用多個(gè)指標(biāo)對(duì)房租價(jià)格進(jìn)行預(yù)測(cè)了。

例如,增加一個(gè)Bathrooms指標(biāo),對(duì)房租價(jià)格進(jìn)行預(yù)測(cè)。

兩個(gè)指標(biāo)計(jì)算距離,相當(dāng)于計(jì)算平面上兩個(gè)點(diǎn)的距離:

也可以利用scipy中的已有工具對(duì)距離進(jìn)行計(jì)算。

from scipy.spatial importdistance

first_listing= dc_listings.iloc[0][['accommodates', 'bathrooms']]

second_listing= dc_listings.iloc[20][['accommodates', 'bathrooms']]#利用euclidean函數(shù)計(jì)算兩個(gè)點(diǎn)間的距離#點(diǎn)可以是n維,但只能計(jì)算兩個(gè)點(diǎn)的距離#結(jié)果返回一個(gè)數(shù)值

distance =distance.euclidean(first_listing, second_listing)

distance

結(jié)果輸出:

5.多變量的KNN模型

這里選取所有特征進(jìn)行預(yù)測(cè),并對(duì)預(yù)測(cè)結(jié)果進(jìn)行評(píng)估。

importpandas as pdfrom sklearn importpreprocessingfrom sklearn.preprocessing importMinMaxScalerfrom scipy.spatial importdistance#數(shù)據(jù)讀取

features = ['accommodates','bedrooms','bathrooms','beds','price','minimum_nights','maximum_nights','number_of_reviews']

dc_listings= pd.read_csv(r'D:\codes_jupyter\數(shù)據(jù)分析_learning\課件\05_K近鄰\listings.csv', engine='python')

dc_listings=dc_listings[features]#數(shù)據(jù)預(yù)處理

dc_listings['price'] = dc_listings.price.str.replace(r'\$|,', '').astype(float) #對(duì)price列進(jìn)行一定的處理,使其變成float型

origin_listings = dc_listings.dropna() #對(duì)缺失值進(jìn)行處理,刪除有缺失值的數(shù)據(jù)norm_dc_listings=origin_listings.copy()

norm_dc_listings[features]= MinMaxScaler().fit_transform(norm_dc_listings) #歸一化

#構(gòu)造訓(xùn)練集和測(cè)試集

train_set = norm_dc_listings[:2792]

test_set= norm_dc_listings[2792:]#價(jià)格預(yù)測(cè)函數(shù)

defpredict_price_multivariate(new_listing_value, features_cols):

temp=train_set#distance.cdist是計(jì)算兩個(gè)集合的距離

#[new_listing_value[features]是使其滿足array結(jié)構(gòu)

temp['distance'] =distance.cdist(temp[features], [new_listing_value[features_cols]])#以distance以索引,從小到大排序

temp = temp.sort_values('distance')#取價(jià)格的前5行

KNN_5 = temp.price.iloc[:5]#取平均值進(jìn)行預(yù)測(cè)

predict_price =KNN_5.mean()returnpredict_price#利用測(cè)試集進(jìn)行預(yù)測(cè)

test_set['predict_price'] = test_set[features].apply(predict_price_multivariate, features_cols=features, axis=1)#數(shù)據(jù)結(jié)果預(yù)處理,化簡為標(biāo)準(zhǔn)化數(shù)據(jù),因此預(yù)測(cè)出來的值也是標(biāo)準(zhǔn)化后的值#因此,需要將預(yù)測(cè)值進(jìn)行反歸一化處理,轉(zhuǎn)化為真實(shí)值#反歸一化處理

scaler =MinMaxScaler()

norm_price= scaler.fit_transform(origin_listings['price'].values.reshape(-1, 1))

orig_price= scaler.inverse_transform(test_set['predict_price'].values.reshape(-1, 1))#對(duì)預(yù)測(cè)結(jié)果進(jìn)行評(píng)估

test_set['square_error'] = (orig_price.ravel() - origin_listings['price'][2792:]) ** 2mse= test_set['square_error'].mean()

rmse= mse ** (1/2)print(rmse)

結(jié)果輸出如下:

6.KNN模型的sklearn實(shí)現(xiàn)

importpandas as pdfrom sklearn importpreprocessingfrom sklearn.preprocessing importMinMaxScalerfrom sklearn.neighbors importKNeighborsRegressorfrom sklearn.metrics importmean_squared_error#數(shù)據(jù)讀取

features = ['accommodates','bedrooms','bathrooms','beds','price','minimum_nights','maximum_nights','number_of_reviews']

dc_listings= pd.read_csv(r'D:\codes_jupyter\數(shù)據(jù)分析_learning\課件\05_K近鄰\listings.csv', engine='python')

dc_listings=dc_listings[features]#數(shù)據(jù)預(yù)處理

dc_listings['price'] = dc_listings.price.str.replace(r'\$|,', '').astype(float) #對(duì)price列進(jìn)行一定的處理,使其變成float型

origin_listings = dc_listings.dropna() #對(duì)缺失值進(jìn)行處理,刪除有缺失值的數(shù)據(jù)

norm_dc_listings =origin_listings.copy()

norm_dc_listings[features]= MinMaxScaler().fit_transform(norm_dc_listings) #歸一化

#構(gòu)造訓(xùn)練集和測(cè)試集

train_set = norm_dc_listings[:2792]

test_set= norm_dc_listings[2792:]#實(shí)例化一個(gè)KNN回歸模型并制定K為14

KNN = KNeighborsRegressor(n_neighbors = 14) #默認(rèn)的K為15

KNN.fit(train_set[features], train_set['price'])#預(yù)測(cè)

prediction =KNN.predict(test_set[features])#評(píng)估

mean_squared_error(test_set['price'], prediction) ** 0.5

輸出結(jié)果如下:

這里利用數(shù)據(jù)歸一化,求出的rmse為上述值。將MinMaxScaler()改為StandardScaler(),利用標(biāo)準(zhǔn)化后的數(shù)據(jù)求解得到的rmse為:

總結(jié)

以上是生活随笔為你收集整理的k近邻回归算法python_经典算法之K近邻(回归部分)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。