K-近邻算法(2019/07/17学习总结)

K-近邻算法

优点:精度高,对异常值不敏感,无数据输入假定(不理解)
缺点:计算复杂度高(需要计算新的数据点与样本集中每个数据的“距离”,以判断是否是前k个邻居),空间复杂度高(巨大的矩阵)。
使用数据范围:数值型和标称型
算法原理:距离公式(欧氏距离)
一般流程:
1.收集数据,可以使用任何方法
2.准备数据,计算距离所需要的数值,最好是结构化的数据格式
3.分析数据,可以使用任何方法
4.训练算法,此步骤不适用于k-近邻算法(存疑)
5.测试算法,计算错误率
6.使用算法。首先需要输入样本数据和结构化的输出结果,然后运行k-近邻算大判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续的处理。

注意:需提前查看数据的内容,看是否需要处理(归一化正则化或者标准化)
标准化:(X - mean)/ std,减去均值之后除以标准差,可以通过使用sklearn.preprocessing.scale()函数将给定数据进行标准化,或者使用sklearn.preprocessing.StandardScaler类,使用该类的好处在于可以保存训练集中的参数(均值、方差)直接使用其对象转换测试集数据。
归一化:将属性缩放到一个指定范围(比如0-1) ,另一种常用的方法是将属性缩放到一个指定的最大值和最小值之间,这可以通过preprocessing.MinMaxScaler类实现。
正则化:将每个样本缩放到单位范数(每个样本的范数为1),这个还没看懂。正则化就是说给需要训练的目标函数加上一些规则(限制),让他们不要自我膨胀。

以下是代码,未对数据进行预处理以及算法的存储(工具:jupyter):

from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
%matplotlib inline
from sklearn.neighbors import KNeighborsClassifier,KNeighborsRegressor
from sklearn.model_selection import train_test_split
data = pd.read_csv('./datingTestSet2.txt',header = None,sep ='\t')
dataArray = np.array(data)
X = dataArray[:,0:3]
y = dataArray[:,3]
def begin(X,y):
    X_train,X_test,y_train,y_test = train_test_split(X,y)
    score = 0
    k = 0 
    for i in range(1,22):
        knn = KNeighborsClassifier(n_neighbors=i)
        knn.fit(X_train,y_train)
        ks = knn.score(X_test,y_test)
        if ks > score:
            score = ks
            k = i
sc = 0
l = []
for i in range(0,1000):
    begin(X,y)
    sc+=score
    l.append(k)
print('平均正确率为:',sc/1000)
print('最佳k值为',max(l, key=l.count))

遗留问题:无论对数据进行何种预处理,正确率一直固定在0.8280000000000016,最佳k值一直为19。
标准化:

from sklearn import preprocessing
X_scaled = preprocessing.scale(X)
sc = 0
l = []
for i in range(0,100):
    begin(X_scaled,y)
    sc+=score
    l.append(k)
print('平均正确率为:',sc/100)
print('最佳k值为',max(l, key=l.count))

归一化:

min_max_scaler = preprocessing.MinMaxScaler()
X_minmax = min_max_scaler.fit_transform(X)
sc = 0
l = []
for i in range(0,100):
    begin(X_minmax,y)
    sc+=score
    l.append(k)
print('平均正确率为:',sc/100)
print('最佳k值为',max(l, key=l.count))

正则化:

X_normalized = preprocessing.normalize(X, norm='l2')
sc = 0
l = []
for i in range(0,100):
    begin(X_normalized,y)
    sc+=score
    l.append(k)
print('平均正确率为:',sc/100)
print('最佳k值为',max(l, key=l.count))

问题分析:怀疑问题出在begin()函数的参数命名上,不应该用X,y

但在同一次切分的情况下,归一化后的准确率比未进行任何处理的准确率高出0.132。

import numpy as np
import pandas as pd 
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
data = pd.read_csv('./datingTestSet2.txt',sep = '\t',header = None)
dataArray = np.array(data)
X = dataArray[:,0:3]
y = dataArray[:,3]
X_train,X_test,y_train,y_test = train_test_split(X,y)
min_max_scaler = preprocessing.MinMaxScaler()
X_train_minmax = min_max_scaler.fit_transform(X_train)
X_test_minmax = min_max_scaler.fit_transform(X_test)
knn = KNeighborsClassifier(n_neighbors=19)
knn.fit(X_train,y_train)
knn.score(X_test,y_test)
#未进行处理的数据准确率为0.8
knn = KNeighborsClassifier(n_neighbors=19)
knn.fit(X_train_minmax,y_train)
knn.score(X_test_minmax,y_test)
#归一化的数据准确率为0.932
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值