KNN算法原理及应用(二)

简介: 不能将所有数据集全部用于训练,为了能够评估模型的泛化能力,可以通过实验测试对学习器的泛化能力进行评估,进而做出选择。因此需要使用一个测试集来测试学习器对新样本的判别能力。

KNN算法原理及应用(一)+https://developer.aliyun.com/article/1544027?spm=a2c6h.13148508.setting.22.1fa24f0eRBJGs5


数据集划分


不能将所有数据集全部用于训练,为了能够评估模型的泛化能力,可以通过实验测试对学习器的泛化能力进行评估,进而做出选择。因此需要使用一个测试集来测试学习器对新样本的判别能力。


测试集要代表整个数据集、与训练集互斥、测试集与训练集建议比例: 2比8、3比7。


数据集划分的方法


1.将数据集划分成两个互斥的集合:训练集,测试集。


  • 训练集用于模型训练
  • 测试集用于模型验证


2.将数据集划分为训练集,验证集,测试集


  • 训练集用于模型训练
  • 验证集用于参数调整
  • 测试集用于模型验证


1:将数据集 D 划分为两个互斥的集合,其中一个集合作为训练集 S,另一个作为测试集 T。


from sklearn.model_selection import train_test_split
from sklearn.model_selection import StratifiedShuffleSplit
from sklearn.model_selection import ShuffleSplit
from collections import Counter
from sklearn.datasets import load_iris
 
 
def te1():
 
    # 1. 加载数据集
    x, y = load_iris(return_X_y=True)
    print('原始类别比例:', Counter(y))
 
        x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)
    print('随机类别分割:', Counter(y_train), Counter(y_test))
 
    
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, stratify=y)
    print('分层类别分割:', Counter(y_train), Counter(y_test))
 
 
def te2():
 
    # 1. 加载数据集
    x, y = load_iris(return_X_y=True)
    print('原始类别比例:', Counter(y))
    print('*' * 40)
 
    # 2. 多次划分
    spliter = ShuffleSplit(n_splits=5, test_size=0.2, random_state=0)
    for train, test in spliter.split(x, y):
        print('随机多次分割:', Counter(y[test]))
 
    spliter = StratifiedShuffleSplit(n_splits=5, test_size=0.2, random_state=0)
    for train, test in spliter.split(x, y):
        print('分层多次分割:', Counter(y[test]))
 
if __name__ == '__main__':
    te1()
    te2()
 
# 随机类别分割: Counter({0: 43, 2: 40, 1: 37}) Counter({1: 13, 2: 10, 0: 7})
# 分层类别分割: Counter({1: 40, 2: 40, 0: 40}) Counter({2: 10, 1: 10, 0: 10})
随机多次分割: Counter({1: 13, 0: 11, 2: 6})
随机多次分割: Counter({1: 12, 2: 10, 0: 8})
随机多次分割: Counter({1: 11, 0: 10, 2: 9})
随机多次分割: Counter({2: 14, 1: 9, 0: 7})
随机多次分割: Counter({2: 13, 0: 12, 1: 5})
 
分层多次分割: Counter({0: 10, 1: 10, 2: 10})
分层多次分割: Counter({2: 10, 0: 10, 1: 10})
分层多次分割: Counter({0: 10, 1: 10, 2: 10})
分层多次分割: Counter({1: 10, 2: 10, 0: 10})
分层多次分割: Counter({1: 10, 2: 10, 0: 10})



  • 第一次使用标号为0-8的共9份数据来做训练,而使用标号为9的这一份数据来进行测试,得到一个准确率
  • 第二次使用标记为1-9的共9份数据进行训练,而使用标号为0的这份数据进行测试,得到第二个准确率
  • 共进行10次训练,最后模型的准确率为10次准确率的平均值,避免了数据划分而造成的评估不准确。


from sklearn.model_selection import KFold
from sklearn.model_selection import StratifiedKFold
from collections import Counter
from sklearn.datasets import load_iris
 
def test():
 
    # 1. 加载数据集
    x, y = load_iris(return_X_y=True)
    print('原始类别比例:', Counter(y))
    print('*' * 30)
 
    # 2. 随机交叉验证
    spliter = KFold(n_splits=5, shuffle=True, random_state=0)
    for train, test in spliter.split(x, y):
        print('随机交叉验证:', Counter(y[test]))
 
    print('*' * 30)
 
    # 3. 分层交叉验证
    spliter = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
    for train, test in spliter.split(x, y):
        print('分层交叉验证:', Counter(y[test]))
 
test()



数据划分结果:


随机交叉验证: Counter({1: 13, 0: 11, 2: 6})
随机交叉验证: Counter({2: 15, 1: 10, 0: 5})
随机交叉验证: Counter({0: 10, 1: 10, 2: 10})
随机交叉验证: Counter({0: 14, 2: 10, 1: 6})
随机交叉验证: Counter({1: 11, 0: 10, 2: 9})
****************************************
分层交叉验证: Counter({0: 10, 1: 10, 2: 10})
分层交叉验证: Counter({0: 10, 1: 10, 2: 10})
分层交叉验证: Counter({0: 10, 1: 10, 2: 10})
分层交叉验证: Counter({0: 10, 1: 10, 2: 10})
分层交叉验证: Counter({0: 10, 1: 10, 2: 10})



留一法:每次抽取一个样本做为测试集。


from sklearn.model_selection import LeaveOneOut
from sklearn.model_selection import LeavePOut
from sklearn.datasets import load_iris
from collections import Counter
 
 
def test01():
 
    # 1. 加载数据集
    x, y = load_iris(return_X_y=True)
    print('原始类别比例:', Counter(y))
    print('*' * 40)
 
    
    spliter = LeaveOneOut()
    for train, test in spliter.split(x, y):
        print('训练集:', len(train), '测试集:', len(test), test)
 
test01()



分类算法的评估


  • 利用训练好的模型使用测试集的特征值进行预测


  • 将预测结果和测试集的目标值比较,计算预测正确的百分比


  • 百分比就是准确率, 准确率越高说明模型效果越好


确定合适的K值


K值过小:容易受到异常点的影响


k值过大:受到样本均衡的问题,K一般取一个较小的数值。


使用 scikit-learn 提供的 GridSearchCV 工具, 配合交叉验证法可以搜索参数组合


x, y = load_iris(return_X_y=True)
 
# 分割数据集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, stratify=y, random_state=0)
 
estimator = KNeighborsClassifier()
grid = {'n_neighbors': [1, 3, 5]}
estimator = GridSearchCV(estimator, param_grid=grid, cv=5)
estimator.fit(x_train, y_train)


K近邻算法的优缺点:


  • 优点:简单,易于理解,容易实现


  • 缺点:算法复杂度高,结果对K取值敏感,容易受数据分布影响


knn算法中我们最需要关注两个问题:k值的选择和距离的计算。


距离/相似度的计算:


样本之间的距离的计算,我们一般使用对于一般使用Lp距离进行计算。当p=1时候,称为曼哈顿距离,当p=2时候,称为欧氏距离,当p=∞时候,称为极大距离。一般采用欧式距离较多。

相关文章
|
2天前
|
存储 算法 C语言
二分查找算法的概念、原理、效率以及使用C语言循环和数组的简单实现
二分查找算法的概念、原理、效率以及使用C语言循环和数组的简单实现
|
3天前
|
存储 自然语言处理 算法
位运算入门及简单算法题的应用
位运算入门及简单算法题的应用
11 1
|
2天前
|
算法 程序员 数据处理
【数据结构与算法】使用单链表实现队列:原理、步骤与应用
【数据结构与算法】使用单链表实现队列:原理、步骤与应用
|
2天前
|
存储 算法 编译器
【数据结构与算法】使用数组实现栈:原理、步骤与应用
【数据结构与算法】使用数组实现栈:原理、步骤与应用
|
2天前
|
存储 算法
【数据结构和算法】---二叉树(2)--堆的实现和应用
【数据结构和算法】---二叉树(2)--堆的实现和应用
5 0
|
3天前
|
机器学习/深度学习 算法 搜索推荐
KNN算法(k近邻算法)原理及总结
KNN算法(k近邻算法)原理及总结
|
2天前
|
机器学习/深度学习 自然语言处理 算法
m基于深度学习的OFDM+QPSK链路信道估计和均衡算法误码率matlab仿真,对比LS,MMSE及LMMSE传统算法
**摘要:** 升级版MATLAB仿真对比了深度学习与LS、MMSE、LMMSE的OFDM信道估计算法,新增自动样本生成、复杂度分析及抗频偏性能评估。深度学习在无线通信中,尤其在OFDM的信道估计问题上展现潜力,解决了传统方法的局限。程序涉及信道估计器设计,深度学习模型通过学习导频信息估计信道响应,适应频域变化。核心代码展示了信号处理流程,包括编码、调制、信道模拟、降噪、信道估计和解调。
23 8
|
4天前
|
算法
基于GA遗传优化的混合发电系统优化配置算法matlab仿真
**摘要:** 该研究利用遗传算法(GA)对混合发电系统进行优化配置,旨在最小化风能、太阳能及电池储能的成本并提升系统性能。MATLAB 2022a用于实现这一算法。仿真结果展示了一系列图表,包括总成本随代数变化、最佳适应度随代数变化,以及不同数据的分布情况,如负荷、风速、太阳辐射、弃电、缺电和电池状态等。此外,代码示例展示了如何运用GA求解,并绘制了发电单元的功率输出和年变化。该系统原理基于GA的自然选择和遗传原理,通过染色体编码、初始种群生成、适应度函数、选择、交叉和变异操作来寻找最优容量配置,以平衡成本、效率和可靠性。
|
5天前
|
机器学习/深度学习 算法
基于鲸鱼优化的knn分类特征选择算法matlab仿真
**基于WOA的KNN特征选择算法摘要** 该研究提出了一种融合鲸鱼优化算法(WOA)与K近邻(KNN)分类器的特征选择方法,旨在提升KNN的分类精度。在MATLAB2022a中实现,WOA负责优化特征子集,通过模拟鲸鱼捕食行为的螺旋式和包围策略搜索最佳特征。KNN则用于评估特征子集的性能。算法流程包括WOA参数初始化、特征二进制编码、适应度函数定义(以分类准确率为基准)、WOA迭代搜索及最优解输出。该方法有效地结合了启发式搜索与机器学习,优化特征选择,提高分类性能。
|
5天前
|
机器学习/深度学习 算法 数据可视化
基于BP神经网络的64QAM解调算法matlab性能仿真
**算法预览图省略** MATLAB 2022A版中,运用BP神经网络进行64QAM解调。64QAM通过6比特映射至64复数符号,提高数据速率。BP网络作为非线性解调器,学习失真信号到比特的映射,对抗信道噪声和多径效应。网络在处理非线性失真和复杂情况时展现高适应性和鲁棒性。核心代码部分未显示。