机器学习经典算法笔记——KNN

K近邻算法

这里面涉及到一些算法实现的包,比如得到的每个点,求距离后怎么处理的问题。

# 前面求欧氏距离就不赘述了,这里主要是补充一点求出结果后怎么处理的问题
nearest = np.argsort(distances)  # 这里对每个距离进行排列,得出index
# 假设K=6的话
topX = [y_train[i] for i in nearest[:k]]  # y_train[i] 是标签,得到的是一个类别列表

# 下一步是求出类别列表中哪种类别是最多的
from collections import Counter
votes = Counter(topX)  # 这里Counter函数返回的是一个字典类型,每个类别对应的数量字典
votes.most_common(1)[0][0]  # 字典中最多的一类是  most_common返回的是元组列表,参数1是最多的一类

下面是用sklearn库来调用实现KNN算法

from sklearn.neighbors import KNeighborsClassifier
Knn_classfier = KNeighborsClassifier(n_neighbors=6)  # 这里的6即是K值
Knn_classfier.fit(X_train,y_train)  # 第一个参数是训练数据集,第二个参数是标签向量
Knn_classfier.predict(x)   # 这里x是输入的待预测的值,这是个向量

判断机器学习算法的性能

shuffle_indexes = np.random.permutation(len(X))  # 随机生成len(X)个索引
test_ratio = 0.2  # 测试数据集比例
test_size = int(len(X) * test_ratio) 
test_indexes = shuffle_indexes[:test_size] 
train_indexes = shuffle_indexes[test_size:]
X_train = X[train_indexes] # 训练数据集
y_train = y[train_indexes]

X_test = X[test_indexes] # 测试数据集
y_test = y[test_indexes]

"""
首先是训练训练数据集中的样本
然后对测试数据集进行预测
最后比对预测数据集中的label中一样的比例,来预测准确率
"""
y_predict = Knn_classfier.predict(X_test)
sum(y_predict == y_test)/len(y_test)  # 计算准确率

我们也可以使用sklearn中自带的训练数据集和测试数据集分离器

from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2)
# 接下来的步骤同上

接下来是一个例子,手写数字数据集

import matplotlib.pyplot as plt
from sklearn import datasets

digits = datasets.load_digits()
X = digits.data
y = digits.target
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2) # 分离测试数据集和训练数据集
# 接下来就是同上了,没有什么好说的

# 求准确度的有个可以调用的函数
from sklearn.metrics import accuracy_score
accuracy_score(y_test,y_predict)

下面引入超参数

这里的超参数,打个比方,K=3的情况,三个点,其中两个同类型的点距离测试值比较远,而另一个类型的点比较近,这种情况下,只是单一的考虑数量来决定该点是哪种类型,明显是不太妥当的,应该是适当的考虑一下权值,比如说把距离的倒数作为权值考虑进去,距离越大的权值越小

Knn_classfier = KNeighborsClassifier(n_neighbors=6, weights = )  # 这里可以选择uniform/distance
""" 这里还有一点需要提出来的是,距离问题,之前我们提到的距离都是指欧拉距离,但是这是不严谨的,
准确的来说应该用明可夫斯基距离,当p=2时,明式距离才等于欧拉距离
"""
Knn_classfier = KNeighborsClassifier(n_neighbors=6, weights = "distance", p = ?)
# p可以不断取值来确定最大的准确度,这里要强调的是,只有weights = "distance",才能有p参数

网格搜索(Grid Search)

param_grid = [
	{
		"weight":["uniform"],
		"n_neighbors":[i for i in range(1,11)]
	},
	{
		"weight":["distance"],
		"n_neighbors":[i for i in range(1,11)],
		"p":[i for i in range(1,6)]
	}
]
from sklearn.model_selection import GridSearchCV
knn_clf = KNeighborsClassifier()  # 定义一个空的分类器
grid_search = GridSearchCV(knn_clf, param_grid)
grid_search.fit(X_train, y_train)
grid_search.best_params_    # 最佳参数以字典的形式返回给你
grid_search.best_score_   # 最佳参数对应的准确度

# 下面是怎么用这个分类器
knn_clf = grid_search.best_estimator_   # 这里返回的是最佳的分类器
knn_clf.predict(X_test)
knn_clf.score(X_test, y_test) # 返回准确率

# 其实这里网格搜索可以选择并行处理来加快处理速度
grid_search = GridSearchCV(knn_clf, param_grid, n_jobs=m)  # 这里的m是采用的m核处理,当m=-1时,是计算机所有的核都在处理这个问题

数据归一化处理

对于一些数据,相差太大的话,在求距离的时候会有很多不便之处,比如坐标为(0.1,1000)和(0.5,1633)这样求距离的话,显然是不太合适的,所以需要对数据进行处理,这里一般的处理方式是 Xscale = (x-xmin)/(xmax-xmin) 把所有的距离映射到0-1之间,适合于分布有明显的边界,比如说考试分数多是在0-100,无明显边界,比如说年薪有的人10000,有的人100000000,根本无法映射到一块,这时候我们需要均值方差归一化 Xscale = (x-xmean)/s 其中xmean是均值,s 为方差

from sklearn.preprocessing import StandardScaler
standarscaler = StandardScaler()
standarscaler.fit(X_train)
X_train = standarscaler.transform(X_train) # 对矩阵进行归一化之后产生的结果,返回X_train
X_test_standard = standarscaler.transform(X_test) # 对矩阵进行归一化之后产生的结果,返回X_test

KNN算法到此结束了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值