k近邻算法

近朱者赤,近墨者黑
在这里插入图片描述
kNN中的k是指取几个近邻来预测分类规律
当k取1时,算法1-NN被称为最近邻分类器

最近邻分类器(1-NN)出错的概率

最近邻分类器出错的概率为
P ( e r r ) = 1 − ∑ c ∈ y P ( c ∣ x ) P ( c ∣ z ) P(err)=1-\sum_{c \in y}{P(c|x)P(c|z)} P(err)=1cyP(cx)P(cz)
为何是这个公式呢?
∑ c ∈ y P ( c ∣ x ) = P ( c ∣ z ) \sum_{c \in y}P(c|x)=P(c|z) cyP(cx)=P(cz)为分类器分类正确的概率,意思是分类的类型与最近邻的样本z分类的类型相同的概率,即分类正确的概率,这里的 y y y等同于总的分类类别,上述式子也等同于 ∑ c ∈ y P ( c ∣ x ) P ( c ∣ z ) \sum_{c \in y}P(c|x)P(c|z) cyP(cx)P(cz)
那么分类错误的概率很明显就是:1-分类正确的概率
P ( e r r ) = 1 − ∑ c ∈ y P ( c ∣ x ) P ( c ∣ z ) P(err)=1-\sum_{c \in y}P(c|x)P(c|z) P(err)=1cyP(cx)P(cz)

1-NN分类器的性能

我们可以用1-NN分类器和最理想的分类器进行对比,这里我们用贝叶斯最优分类器与1-NN分类器进行性能对比
贝叶斯最优分类器结果表示: c ∗ = a r g m a x c ∈ y P ( c ∣ x ) c^*=argmax_{c \in y}P(c|x) c=argmaxcyP(cx),大体意思就是说,分类出哪种类别的概率最高,那么分类结果就是哪种类别,这里最优的类别是 c ∗ c^* c,同时我们也能得到,贝叶斯最优分类器出错的概率为 1 − P ( c ∗ ∣ x ) 1-P(c^* | x) 1P(cx)
推导过程:
P ( e r r ) = 1 − ∑ c ∈ y P ( c ∣ x ) P ( c ∣ z ) 这里 x 与 z 充分接近的话 , 那么 P ( c ∣ x ) 充分接近 P ( c ∣ z ) 故 P ( e r r ) ≃ 1 − ∑ c ∈ y P 2 ( c ∣ x ) 有因为 P ( c ∣ x ) = P ( c 1 ∣ x ) + P ( c 2 ∣ x ) + ⋯ + P ( c y ∣ x ) 故 P ( c ∗ ∣ x ) ≤ P ( c ∣ x ) 故 P ( e r r ) ≤ 1 − P 2 ( c ∗ ∣ x ) 根据完全平方公式 P ( e r r ) ≤ ( 1 + P 2 ( c ∗ ∣ x ) ) ( 1 − P 2 ( c ∗ ∣ x ) ) 因为 P ( c ∗ ∣ x ) ≤ 1 故 P ( e r r ) ≤ 2 ( 1 − P 2 ( c ∗ ∣ x ) P(err)=1-\sum_{c \in y}P(c|x)P(c|z) \\ 这里x与z充分接近的话,那么P(c|x)充分接近P(c|z) \\ 故P(err) \simeq 1-\sum_{c \in y}P^2(c|x) \\ 有因为P(c|x)=P(c_1|x)+P(c_2|x)+\cdots+P(c_y|x) \\ 故P(c^*|x) \leq P(c|x) \\ 故P(err) \leq 1-P^2(c^*|x) \\ 根据完全平方公式 P(err) \leq (1+P^2(c^*|x))(1-P^2(c^*|x)) \\ 因为P(c^*|x) \leq 1 \\ 故P(err) \leq 2(1-P^2(c^*|x) P(err)=1cyP(cx)P(cz)这里xz充分接近的话,那么P(cx)充分接近P(cz)P(err)1cyP2(cx)有因为P(cx)=P(c1x)+P(c2x)++P(cyx)P(cx)P(cx)P(err)1P2(cx)根据完全平方公式P(err)(1+P2(cx))(1P2(cx))因为P(cx)1P(err)2(1P2(cx)
由上述可知贝叶斯最优分类器的出错概率为 1 − P ( c ∗ ∣ x ) 1-P(c^*|x) 1P(cx),由此可得,最近邻分类器虽然简单,但它的泛化错误率不超过贝叶斯最优分类器的错误率的两倍

通用步骤

①计算距离(常用欧几里得距离或马氏距离)
②升序排列
③取前k个
④加权平均

k的取值

k太大:导致分类模糊
k太小:受个例影响,波动较大

如何选取k

①经验
②均方根误差

import random
import csv

#读取
with open('Prostate_Cancer.csv','r') as file:
    reader=csv.DictReader(file)

    datas=[row for row in reader]

#分组
random.shuffle(datas)
n=len(datas)//3

test_set=datas[0:n]
train_set=datas[n:]

#KNN
#距离
def distance(d1,d2):
    res=0
    for key in ('radius','texture','perimeter','area','smoothness','compactness','symmetry','fractal_dimension'):
        res+=(float(d1[key])-float(d2[key]))**2

    return res**0.5

K=5
def knn(data):
    #求解所有的距离
    res=[
        {'result':train['diagnosis_result'],'distance':distance(data,train)}
        for train in train_set
    ]

    #排序——升序
    res=sorted(res,key=lambda item:item['distance'])

    #取前k个
    res2=res[0:K]

    #加权平均
    result={'B':0,'M':0}

    #总的距离
    sum=0
    for r in res2:
        sum+=r['distance']

    for r in res2:
        result[r['result']]+=1-r['distance']/sum

    if result['B']>result['M']:
        return 'B'
    else:
        return 'M'

#测试阶段
correct=0
for test in test_set:
    result=test['diagnosis_result']
    result2=knn(test)

    if result==result2:
        correct+=1

print("{:.2f}%".format(100*correct/len(test_set)))

癌症数据:
https://pan.baidu.com/s/1tAM4-PxIo1RBtNaBSgnnDQ?pwd=r5fi

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值