同步更新在個(gè)人網(wǎng)站:http://www.wangpengcufe.com/machinelearning/pythonml-pythonml2/
一、什么是K近鄰算法训裆?
定義:
如果一個(gè)樣本在特征空間中的k個(gè)最相似(即特征空間中最鄰近)的樣本中的大多數(shù)屬于某一個(gè)類別,則該樣本也屬于這個(gè)類別。
來源:
KNN算法最早是由Cover和Hart提出的一種分類算法.
計(jì)算距離公式:
兩個(gè)樣本的距離可以通過如下公式計(jì)算酪刀,又叫歐式距離。
比如說钮孵,a(a1,a2,a3),b(b1,b2,b3)
二骂倘、K近鄰算法的實(shí)現(xiàn)
sk-learn近鄰算法API
sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm='auto')
n_neighbors:int,可選(默認(rèn)= 5),k_neighbors查詢默認(rèn)使用的鄰居數(shù)
algorithm:{‘a(chǎn)uto’巴席,‘ball_tree’历涝,‘kd_tree’,‘brute’}漾唉,可選用于計(jì)算最近鄰居的算法:‘ball_tree’將會使用 BallTree荧库,‘kd_tree’將使用 KDTree≌孕蹋‘a(chǎn)uto’將嘗試根據(jù)傳遞給fit方法的值來決定最合適的算法分衫。 (不同實(shí)現(xiàn)方式影響效率)
近鄰算法實(shí)例
案例背景:(kaggle地址:https://www.kaggle.com/c/facebook-v-predicting-check-ins/overview)
數(shù)據(jù)下載地址:train.csv
數(shù)據(jù)格式:
row_id x y accuracy time place_id
0 0 0.7941 9.0809 54 470702 8523065625
1 1 5.9567 4.7968 13 186555 1757726713
2 2 8.3078 7.0407 74 322648 1137537235
3 3 7.3665 2.5165 65 704587 6567393236
4 4 4.0961 1.1307 31 472130 7440663949
... ... ... ... ... ... ...
29118016 29118016 6.5133 1.1435 67 399740 8671361106
29118017 29118017 5.9186 4.4134 67 125480 9077887898
29118018 29118018 2.9993 6.3680 67 737758 2838334300
29118019 29118019 4.0637 8.0061 70 764975 1007355847
29118020 29118020 7.4523 2.0871 17 102842 7028698129
[29118021 rows x 6 columns]
實(shí)現(xiàn)思路:
1、數(shù)據(jù)集的處理(縮小數(shù)據(jù)集范圍般此,處理日期數(shù)據(jù)蚪战,增加分割的日期數(shù)據(jù)牵现,刪除沒用的日期數(shù)據(jù),將簽到位置少于n個(gè)用戶的刪除)
2邀桑、分割數(shù)據(jù)集
3施籍、對數(shù)據(jù)集進(jìn)行標(biāo)準(zhǔn)化
4、estimator流程進(jìn)行分類預(yù)測
具體代碼如下:
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
# 讀取數(shù)據(jù)
data = pd.read_csv("./data/FBlocation/train.csv")
# 處理數(shù)據(jù)
# 1概漱、縮小數(shù)據(jù),查詢數(shù)據(jù)集范圍
data = data.query("x > 1.0 & x < 1.25 & y > 2.5 & y < 2.75")
# 處理時(shí)間的數(shù)據(jù)
time_value = pd.to_datetime(data['time'], unit='s')
# 把日期格式轉(zhuǎn)換成 字典格式
time_value = pd.DatetimeIndex(time_value)
# 構(gòu)造一些特征
data['day'] = time_value.day
data['hour'] = time_value.hour
data['weekday'] = time_value.weekday
# 把時(shí)間戳特征刪除
data = data.drop(['time'], axis=1)
# 把簽到數(shù)量少于n個(gè)目標(biāo)位置刪除
place_count = data.groupby('place_id').count()
tf = place_count[place_count.row_id > 3].reset_index()
data = data[data['place_id'].isin(tf.place_id)]
# 取出數(shù)據(jù)當(dāng)中的特征值和目標(biāo)值
y = data['place_id']
x = data.drop(['place_id'], axis=1)
# 進(jìn)行數(shù)據(jù)的分割訓(xùn)練集合測試集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)
# 特征工程(標(biāo)準(zhǔn)化)
std = StandardScaler()
# 對測試集和訓(xùn)練集的特征值進(jìn)行標(biāo)準(zhǔn)化
x_train = std.fit_transform(x_train)
x_test = std.transform(x_test)
# 進(jìn)行算法流程 # 超參數(shù)
knn = KNeighborsClassifier()
knn.fit(x_train, y_train)
y_predict = knn.predict(x_test)
print("預(yù)測的目標(biāo)簽到位置為:", y_predict)
print("預(yù)測的準(zhǔn)確率:", knn.score(x_test, y_test))
運(yùn)行結(jié)果:
預(yù)測的目標(biāo)簽到位置為: [8258328058 2355236719 6683426742 ... 5606572086 4932578245 9237487147]
預(yù)測的準(zhǔn)確率: 0.3959810874704492
思考問題
1丑慎、k值取多大?有什么影響瓤摧?
2竿裂、性能問題?
三照弥、K近鄰算法總結(jié)
K近鄰算法優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
簡單腻异,易于理解,易于實(shí)現(xiàn)这揣,無需估計(jì)參數(shù)悔常,無需訓(xùn)練
缺點(diǎn)
- 懶惰算法,對測試樣本分類時(shí)的計(jì)算量大给赞,內(nèi)存開銷大
- 必須指定K值机打,K值選擇不當(dāng)則分類精度不能保證
使用場景
小數(shù)據(jù)場景,幾千~幾萬樣本片迅,具體場景具體業(yè)務(wù)去測試
四残邀、分類模型的評估
評估方法
estimator.score()
一般最常見使用的是準(zhǔn)確率,即預(yù)測結(jié)果正確的百分比
混淆矩陣
在分類任務(wù)下柑蛇,預(yù)測結(jié)果(Predicted Condition)與正確標(biāo)記(True Condition)之間存在四種不同的組合芥挣,構(gòu)成混淆矩陣(適用于多分類)
精確率(Precision):預(yù)測結(jié)果為正例樣本中真實(shí)為正例的比例(查得準(zhǔn))
召回率(Recall):真實(shí)為正例的樣本中預(yù)測結(jié)果為正例的比例(查的全,對正樣本的區(qū)分能力)
其他分類標(biāo)準(zhǔn)耻台,F1-score空免,反映了模型的穩(wěn)健型
分類模型評估API
評估API :
sklearn.metrics.classification_report
用法:
sklearn.metrics.classification_report(y_true, y_pred, target_names=None)
y_true:真實(shí)目標(biāo)值
y_pred:估計(jì)器預(yù)測目標(biāo)值
target_names:目標(biāo)類別名稱
return:每個(gè)類別精確率與召回率