KNN核心思想:
你的"邻居"来推断出你的类别
如果取的最近的电影数量不一样?会是什么结果?
k 值取得过小,容易受到异常点的影响
k 值取得过大,样本不均衡的影响
优点:简单,易于理解,易于实现,无需训练
缺点:
1)必须指定K值,K值选择不当则分类精度不能保证
2)懒惰算法,对测试样本分类时的计算量大,内存开销大
使用场景:小数据场景,几千~几万样本,具体场景具体业务去测试
API
sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm='auto')
n_neighbors:k值
algorithm:{'auto', 'ball_tree', 'kd_tree', 'brute'},
可选用于计算最近邻居的算法:
'ball_tree':将会使用BallTree
'kd_tree':将会使用KDTree
'auto':将尝试根据传递给fit方法的值来决定最合适的算法。
(不同实现方式影响效率)
用KNN算法对鸢尾花数据集进行分类预测
from sklearn.datasets import load_iris
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
"""
用KNN算法对鸢尾花进行分类
:return:
"""
# 1)获取数据
iris = load_iris()
# 2)划分数据集
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22)
# 3)特征工程:标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
'''
#注意这里
训练集需要标准化,同样的测试集也需要进行标准化,
对于训练集,需要fit(), transform()两个步骤进行标准化
经过fit()之后得出平均值和标准差
对于测试集,如果使用fit(),则会得到一组新的平均值和标准差。
但是我们进行测试时,需要与训练集的保持一致(类似于直接调用训练集产生的模型)
因此不需要再fit(),只需要进行transform()
'''
# 4)KNN算法预估器
estimator = KNeighborsClassifier(n_neighbors=3)
estimator.fit(x_train, y_train)
# 5)模型评估
# 方法1:直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:n", y_predict)
print("直接比对真实值和预测值:n", y_test == y_predict)
# 方法2:计算准确率
score = estimator.score(x_test, y_test)
print("准确率为:n", score)
交叉验证与网格搜索
交叉验证:
将拿到的训练数据,分为训练集和验证集。
以下图为例:将数据分为4份,其中1份作为验证集。然后经过4次(组)的测试,每次都更换不同的验证集。即得到4组模型的结果,取平均值作为最终结果。又称4折交叉验证。
目的:为了让被评估的模型更加准确可信
分析:
我们之前知道,数据分为训练集和测试集。但是为了让从训练得到模型结果更加准确。做以下处理:
训练集:训练集+验证集
测试集:测试集
最终的预测结果求平均值,即:
(80%+78%+75%+82%)/ 4 = 78.75%
网格搜索
超参数搜索-网格搜索(Grid Search)
通常情况下,有很多参数时需要手动指定的(如KNN算法中的K值),这种叫超参数。但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。
API(同时添加交叉验证与网格搜索)
sklearn.model_selection.GridSearchCV(estimator,param_grid=None,cv=None)
对评估器的指定参数值进行详尽搜索
estimator:估计器对象
param_grid:估计器参数(dict){"n_neighbors":[1,3,5]}
cv:指定几折交叉验证
fit():输入训练数据
score():准确率
结果分析:
最佳参数: best_params_
最佳结果: best_score_
最佳估计器: best_estimator_
交叉验证结果: cv_results_
实例一:用KNN算法对鸢尾花进行分类,添加网格搜索和交叉验证
from sklearn.datasets import load_iris
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
"""
用KNN算法对鸢尾花进行分类,添加网格搜索和交叉验证
:return:
"""
# 1)获取数据
iris = load_iris()
# 2)划分数据集
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22)
# 3)特征工程:标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4)KNN算法预估器
estimator = KNeighborsClassifier()
# 加入网格搜索与交叉验证
# 参数准备
param_dict = {"n_neighbors": [1, 3, 5, 7, 9, 11]}
estimator = GridSearchCV(estimator, param_grid=param_dict, cv=10)
estimator.fit(x_train, y_train)
# 5)模型评估
# 方法1:直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:n", y_predict)
print("直接比对真实值和预测值:n", y_test == y_predict)
# 方法2:计算准确率
score = estimator.score(x_test, y_test)
print("准确率为:n", score)
# 最佳参数:best_params_
print("最佳参数:n", estimator.best_params_)
# 最佳结果:best_score_
print("最佳结果:n", estimator.best_score_)
# 最佳估计器:best_estimator_
print("最佳估计器:n", estimator.best_estimator_)
# 交叉验证结果:cv_results_
print("交叉验证结果:n", estimator.cv_results_)



