KNN學習筆記

    k近鄰(k-nearest nrighbor,k-NN)是一種基本分類與迴歸的方法。實現簡單,直觀:給定一個訓練數據集,對新的輸入實例,在訓練數據集中找到與該實例最鄰近的K個實例,這K個實例的多數屬於某個類,就把該輸入實例分爲到這個類裏。
    k近鄰算法使用的模型實際上有三個基本要素,分別是距離度量,k值的選擇和分類決策規則。下面分別簡述三要素。
    1、距離度量
    空間中兩個實例點的距離反應兩個實例點的相似程度。k近鄰算法的特徵空間一般是n維向量空間,使用的是距離度量方式爲歐氏距離,歐氏距離我們高中就學過。當然也可以使用其他距離度量方式。
    2、k值的選擇
    k值的選擇會對結果有很大的影響。如果選擇較小的k值,相當於用較小的鄰域中訓練實例進行預測,近似誤差會變小,只有與輸入實例較近的訓練實例纔會對預測結果起作用。k值較小意味着整體模型算法變得複雜了,容易發生過擬合。如果k值過大的話,相當於模型算法變得簡單,可能會到欠擬合。在實際使用中,k值一般取一個較小的數組,然後通過交叉驗證的方法選擇最優的k值。
    3、分類決策規則
    k-nn中的分類決策規則往往是多數表決,即輸入實例的k個近鄰的訓練實例中的多數類決定輸入實例的類。

下面通過一個簡單實例來看下這個k-nn得使用。
# -*- coding:utf-8 -*-
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

#讀取數據
df = pd.read_csv('data.csv')
# print(df.head())
# print(df.info())
# print(df.describe())

"""
使用one-hot編碼,將離散特徵的取值擴展到了歐式空間,離散特徵的某個取值就對應歐式空間的某個點。將離散型特徵使用one-hot編碼,會讓特徵之間的距離計算更加合理。離散特徵進行one-hot編碼後,編碼後的特徵,其實每一維度的特徵都可以看做是連續的特徵。就可以跟對連續型特徵的歸一化方法一樣,對每一維特徵進行歸一化。比如歸一化到[-1,1]或歸一化到均值爲0,方差爲1。
"""
#清洗數據
#顏色進行one-hot編碼,顏色有多種並且是str類型的,one-hot將顏色變成連續數,便於距離計算。
df_color = df['Color'].str.get_dummies().add_prefix('Color: ')
#type進行one-hot
df_type = df['Type'].apply(str).str.get_dummies().add_prefix('Type: ')
# 添加獨熱編碼數據列
df = pd.concat([df,df_color,df_type],axis=1)
# 去除獨熱編碼對應的原始列
df = df.drop(['Color','Type','Brand'],axis=1)
# print(df)

#數據轉換
#corr()相關係數矩陣,即給出任意兩個特徵之間的相關係數
matrix = df.corr()
fig = plt.figure(figsize=(10,6))
sns.heatmap(matrix,square=True)
plt.title('Car Price Variables')
# plt.show()

from sklearn.neighbors import KNeighborsClassifier
from sklearn.neighbors import KNeighborsRegressor
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
from sklearn.preprocessing import StandardScaler
X = df[['Construction Year', 'Days Until MOT', 'Odometer']]
y = df['Ask Price'].values.reshape(-1,1)
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=41)

X_norm = StandardScaler()
X_train = X_norm.fit_transform(X_train)
X_test = X_norm.transform(X_test)

y_norm = StandardScaler()
y_train = y_norm.fit_transform(y_train)
y_test = y_norm.transform(y_test)

knn = KNeighborsRegressor(n_neighbors=2)
knn.fit(X_train,y_train)

#Now we can predict prices:
y_pred = knn.predict(X_test)
y_pred_reval = y_norm.inverse_transform(y_pred)
y_test_reval = y_norm.inverse_transform(y_test)

fig2 = plt.figure(figsize=(10,8))
plt.scatter(y_pred_reval,y_test_reval)
plt.xlabel('Prediction')
plt.ylabel('Real value')

# Now add the perfect prediction line
fig1 = plt.figure(figsize=(10,8))
diagonal = np.linspace(500, 1500, 100)
plt.scatter(y_pred_reval,y_test_reval)
plt.plot(diagonal, diagonal, '-r')
plt.xlabel('Predicted ask price')
plt.ylabel('Ask price')
plt.show()

# print(y_pred_reval)
"""
[[1199.]
 [1199.]
 [ 700.]
 [ 899.]]
"""
KNeighborsRegressor(algorithm='auto',leaf_size=30,metric='minkowski',metric_params=None,n_jobs=None,n_neighbors=2,p=2,weights='uniform')
pred = knn.predict(X_test)
print(pred)

"""
[[ 1.36676513]
 [ 1.36676513]
 [-0.68269804]
 [ 0.13462294]]

"""

from sklearn.metrics import  mean_absolute_error
p = mean_absolute_error(y_pred_reval,y_test_reval)
from sklearn.metrics import mean_squared_error
p1 = mean_squared_error(y_pred_reval,y_test_reval)
print(p)  #175.5
print(p1) #56525.5
print(y_pred_reval)
print(y_test_reval)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章