sklearn实现K-近邻算法、鸢尾花分类、facebook签到位置预测

1 K-近邻算法(KNN)概念

KNN算法流程

sklearn 的KNN的算法实现

API :   sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm='auto')

参数说明

  • n_neighbors:
    • int,可选(默认= 5),k_neighbors查询默认使用的邻居数
  • algorithm 字符串类型、可选如下参数‘auto’,‘ball_tree’,‘kd_tree’,‘brute’。其中:
    • 默认参数为auto,可以理解为算法自己决定合适的搜索算法。除此之外,用户也可以自己指定搜索算法ball_tree、kd_tree、brute方法进行搜索,
    • brute是蛮力搜索,也就是线性扫描,当训练集很大时,计算非常耗时。
    • kd_tree,构造kd树存储数据以便对其进行快速检索的树形数据结构,kd树也就是数据结构中的二叉树。以中值切分构造的树,每个结点是一个超矩形,在维数小于20时效率高。
    • ball tree是为了克服kd树高维失效而发明的,其构造过程是以质心C和半径r分割样本空间,每个节点是一个超球体。
from sklearn.neighbors import KNeighborsClassifier
import pickle


# 训练集 x是特征值,y是标签
x = [[0], [1], [2], [10], [15], [11]]
y = [0, 0, 0, 1, 1, 1]

# 实例化一个knn对象,k=3
estimator = KNeighborsClassifier(n_neighbors=3, algorithm='auto')
# 训练
estimator.fit(x,y)

# 预测 
estimator.predict([[22]])

# 模型保存
with open('./KNN.pkl','wb') as f:
    pickle.dump(estimator, f)

模型加载

import pickle


# 模型加载
with open('./KNN.pkl', 'rb') as ff:
    model = pickle.load(ff)

# 模型预测
model.predict([[15]])

2 基于KNN的鸢尾花分类

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier


# 数据集加载
iris= load_iris()

# 数据集划分
x_train,x_test, y_train,y_test = train_test_split(iris.data, iris.target, test_size=0.2)

#特征工程
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)

# 机器学习
estimator = KNeighborsClassifier(n_neighbors=11, algorithm='auto')
estimator.fit(x_train, y_train)

# 预测
y_predict = estimator.predict(x_test)
print("测试集预测结果:\n", y_predict)
print()
print(y_predict == y_test)

# 计算模型得分
score = estimator.score(x_test,y_test)
print("模型得分为:", score)

3 facebook签到位置预测

import pandas as pd
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
import numpy as np


# 1、获取数据集
facebook = pd.read_csv("./train.csv")

# 2.基本数据处理
# 2.1 缩小数据范围
facebook_data = facebook.query("x>2.0 & x<2.5 & y>2.0 & y<2.5")
# 2.2 选择时间特征
time = pd.to_datetime(facebook_data["time"], unit="s")
time = pd.DatetimeIndex(time)
facebook_data["day"] = time.day
facebook_data["hour"] = time.hour
facebook_data["weekday"] = time.weekday
# 2.3 去掉签到较少的地方
place_count = facebook_data.groupby("place_id").count()
place_count = place_count[place_count["row_id"]>3]
facebook_data = facebook_data[facebook_data["place_id"].isin(place_count.index)]
# 2.4 确定特征值和目标值
x = facebook_data[["x", "y", "accuracy", "day", "hour", "weekday"]]
y = facebook_data["place_id"]
# 2.5 分割数据集
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)

# 3.特征工程--特征预处理(标准化)
# 3.1 实例化一个转换器
transfer = StandardScaler()
# 3.2 调用fit_transform
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)

# 4.机器学习--knn+cv
# 4.1 实例化一个估计器
estimator = KNeighborsClassifier()
# 4.2 调用gridsearchCV
param_grid = {"n_neighbors": [1, 3, 5, 7, 9]}
estimator = GridSearchCV(estimator, param_grid=param_grid, cv=5)
# 4.3 模型训练
estimator.fit(x_train, y_train)

# 5.模型评估
# 5.1 基本评估方式
score = estimator.score(x_test, y_test)
print("最后预测的准确率为:\n", score)

y_predict = estimator.predict(x_test)
print("最后的预测值为:\n", y_predict)
print("预测值和真实值的对比情况:\n", y_predict == y_test)

# 5.2 使用交叉验证后的评估方式
print("在交叉验证中验证的最好结果:\n", estimator.best_score_)
print("最好的参数模型:\n", estimator.best_estimator_)
print("每次交叉验证后的验证集准确率结果和训练集准确率结果:\n",estimator.cv_results_)

训练数据集有点大,放入网盘链接:https://pan.baidu.com/s/1IqeYKknJnxeTa9wieSTh7w 提取码:1111 

KNN算法总结

  • 优点:

    • 简单有效
    • 重新训练的代价低
    • 适合类域交叉样本
      • KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。
    • 适合大样本自动分类
      • 该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分

  • 缺点:

    • 惰性学习

      • KNN算法是懒散学习方法(lazy learning,基本上不学习),一些积极学习的算法要快很多
    • 类别评分不是规格化

      • 不像一些通过概率评分的分类
    • 输出可解释性不强
      • 例如决策树的输出可解释性就较强
    • 对不均衡的样本不擅长
      • 当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。该算法只计算“最近的”邻居样本,某一类的样本数量很大,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。无论怎样,数量并不能影响运行结果。可以采用权值的方法(和该样本距离小的邻居权值大)来改进。
    • 计算量较大
      • 目前常用的解决方法是事先对已知样本点进行剪辑,事先去除对分类作用不大的样本。

猜你喜欢

转载自blog.csdn.net/qq_39197555/article/details/114992113