机器学习-基础分类算法-KNN详解

KNN-k近邻算法

k-Nearest Neighbors

  • 思想极度简单
  • 应用数学只是少
  • 效果好
  • 可以解释机器学习算法使用过程中的很多细节问题
  • 更完整的刻画机器学习应用的流程

image.png
image.png
image.png
创建简单测试用例

import numpy as np
import matplotlib.pyplot as plt
raw_data_X = [[3.393533211, 2.331273381],[3.110073483, 1.781539638],[1.343808831, 3.368360954],[3.582294042, 4.679179110],[2.280362439, 2.866990263],[7.423436942, 4.696522875],[5.745051997, 3.533989803],[9.172168622, 2.511101045],[7.792783481, 3.424088941],[7.939820817, 0.791637231]]
raw_data_y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
X_train = np.array(raw_data_X)
y_train = np.array(raw_data_y)
plt.scatter(X_train[y_train==0,0], X_train[y_train==0,1], color='g')
plt.scatter(X_train[y_train==1,0], X_train[y_train==1,1], color='r')
plt.show()

无标题.png
预测

x = np.array([8.093607318, 3.365731514])plt.scatter(X_train[y_train==0,0], X_train[y_train==0,1], color='g')
plt.scatter(X_train[y_train==1,0], X_train[y_train==1,1], color='r')
plt.scatter(x[0], x[1], color='b')
plt.show()

无标题.png
KNN过程

from math import sqrt
distances = []
for x_train in X_train:d = sqrt(np.sum((x_train - x)**2))distances.append(d)

image.png
image.png

distances = [sqrt(np.sum((x_train - x)**2))for x_train in X_train]

数组排序返回索引

np.argsort(distances)
nearest = np.argsort(distances)

最近k个点相近的y坐标

k = 6
topK_y = [y_train[neighbor] for neighbor in nearest[:k]]
topK_y

image.png
统计

from collections import Counter
votes = Counter(topK_y)
votes.most_common(1)
predict_y = votes.most_common(1)[0][0]

image.png

封装

import numpy as np
from math import sqrt
from collections import Counterdef kNN_classify(k, X_train, y_train, x):assert 1 <= k <= X_train.shape[0], "k must be valid"assert X_train.shape[0] == y_train.shape[0], \"the size of X_train must equal to the size of y_train"assert X_train.shape[1] == x.shape[0], \"the feature number of x must be equal to X_train"distances = [sqrt(np.sum((x_train - x)**2)) for x_train in X_train]nearest = np.argsort(distances)topK_y = [y_train[i] for i in nearest[:k]]votes = Counter(topK_y)return votes.most_common(1)[0][0]
  • k近邻算法是非常特殊的,可以被认为是没有模型的算法
  • 为了和其他算法统一,可以认为训练数据集就是模型本身

使用scikit-learn中的kNN

raw_data_X = [[3.393533211, 2.331273381],[3.110073483, 1.781539638],[1.343808831, 3.368360954],[3.582294042, 4.679179110],[2.280362439, 2.866990263],[7.423436942, 4.696522875],[5.745051997, 3.533989803],[9.172168622, 2.511101045],[7.792783481, 3.424088941],[7.939820817, 0.791637231]]
raw_data_y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]X_train = np.array(raw_data_X)
y_train = np.array(raw_data_y)x = np.array([8.093607318, 3.365731514])
from sklearn.neighbors import KNeighborsClassifier
kNN_classifier = KNeighborsClassifier(n_neighbors=6)
kNN_classifier.fit(X_train, y_train)
#预测
kNN_classifier.predict(x)
#转化为矩阵
X_predict = x.reshape(1, -1)
kNN_classifier.predict(X_predict)
y_predict = kNN_classifier.predict(X_predict)

image.png
优化封装的KNN

import numpy as np
from math import sqrt
from collections import Counterclass KNNClassifier:def __init__(self, k):"""初始化kNN分类器"""assert k >= 1, "k must be valid"self.k = kself._X_train = Noneself._y_train = Nonedef fit(self, X_train, y_train):"""根据训练数据集X_train和y_train训练kNN分类器"""assert X_train.shape[0] == y_train.shape[0], \"the size of X_train must be equal to the size of y_train"assert self.k <= X_train.shape[0], \"the size of X_train must be at least k."self._X_train = X_trainself._y_train = y_trainreturn selfdef predict(self, X_predict):"""给定待预测数据集X_predict,返回表示X_predict的结果向量"""assert self._X_train is not None and self._y_train is not None, \"must fit before predict!"assert X_predict.shape[1] == self._X_train.shape[1], \"the feature number of X_predict must be equal to X_train"y_predict = [self._predict(x) for x in X_predict]return np.array(y_predict)def _predict(self, x):"""给定单个待预测数据x,返回x的预测结果值"""assert x.shape[0] == self._X_train.shape[1], \"the feature number of x must be equal to X_train"distances = [sqrt(np.sum((x_train - x) ** 2))for x_train in self._X_train]nearest = np.argsort(distances)topK_y = [self._y_train[i] for i in nearest[:self.k]]votes = Counter(topK_y)return votes.most_common(1)[0][0]def __repr__(self):return "KNN(k=%d)" % self.k

image.png

判断机器学习算法的性能-训练数据分割测试数据

image.png
分一部分数据设置为测试数据
image.png
train test split
加载数据

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets 
iris = datasets.load_iris()
iris.keys()
X = iris.data
y = iris.target
X.shape
y.shape

image.png
**分离出一部分数据做训练,另外一部分数据做测试 **
将索引随机排列

shuffled_indexes = np.random.permutation(len(X))
shuffled_indexes

设置测试数据百分比
获取测试数据

test_ratio = 0.2
test_size = int(len(X) * test_ratio)
test_indexes = shuffled_indexes[:test_size]
train_indexes = shuffled_indexes[test_size:]
X_train = X[train_indexes]
y_train = y[train_indexes]
X_test = X[test_indexes]
y_test = y[test_indexes]

image.png
封装算法

import numpy as np
def train_test_split(X, y, test_ratio=0.2, seed=None):"""将数据 X 和 y 按照test_ratio分割成X_train, X_test, y_train, y_test"""assert X.shape[0] == y.shape[0], \"the size of X must be equal to the size of y"assert 0.0 <= test_ratio <= 1.0, \"test_ration must be valid"if seed:np.random.seed(seed)shuffled_indexes = np.random.permutation(len(X))test_size = int(len(X) * test_ratio)test_indexes = shuffled_indexes[:test_size]train_indexes = shuffled_indexes[test_size:]X_train = X[train_indexes]y_train = y[train_indexes]X_test = X[test_indexes]y_test = y[test_indexes]return X_train, X_test, y_train, y_test

image.png
sklearn中的train_test_split
image.png

分类准确度

加载手写数字数据

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
digits = datasets.load_digits()
digits.keys()
X = digits.data
X.shape
y = digits.target
y.shape

image.png
查看数据

some_digit = X[666]
some_digit_image = some_digit.reshape(8, 8)
import matplotlib
import matplotlib.pyplot as plt
plt.imshow(some_digit_image, cmap = matplotlib.cm.binary)
plt.show()

image.png
预测准确率

from playML.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, test_ratio=0.2)
from playML.kNN import KNNClassifiermy_knn_clf = KNNClassifier(k=3)
my_knn_clf.fit(X_train, y_train)
y_predict = my_knn_clf.predict(X_test)
sum(y_predict == y_test) / len(y_test)

image.png
封装自己的accuracy_score

import numpy as npdef accuracy_score(y_true, y_predict):'''计算y_true和y_predict之间的准确率'''assert y_true.shape[0] == y_predict.shape[0], \"the size of y_true must be equal to the size of y_predict"return sum(y_true == y_predict) / len(y_true)

image.png
scikit-learn中的accuracy_score

from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=666)
from sklearn.neighbors import KNeighborsClassifierknn_clf = KNeighborsClassifier(n_neighbors=3)
knn_clf.fit(X_train, y_train)
y_predict = knn_clf.predict(X_test)
from sklearn.metrics import accuracy_score
accuracy_score(y_test, y_predict)

超参数和模型参数

  • 超参数:在算法运行前需要决定的参数
  • 模型参数:算法过程中学习的参数

KNN算法没有模型参数
KNN算法中的K是典型的超参数
寻找好的超参数

  • 领域知识
  • 经验数值
  • 实验搜索

加载手写数字数据集

import numpy as np
from sklearn import datasets
digits = datasets.load_digits()
X = digits.data
y = digits.target
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, random_state=666)
from sklearn.neighbors import KNeighborsClassifier
knn_clf = KNeighborsClassifier(n_neighbors=3)
knn_clf.fit(X_train, y_train)
knn_clf.score(X_test, y_test)

寻找最好的k、

best_score = 0.0
best_k = -1
for k in range(1, 11):knn_clf = KNeighborsClassifier(n_neighbors=k)knn_clf.fit(X_train, y_train)score = knn_clf.score(X_test, y_test)if score > best_score:best_k = kbest_score = scoreprint("best_k =", best_k)
print("best_score =", best_score)

image.png
image.png
image.png
加入是否考虑距离

best_score = 0.0
best_k = -1
best_method = ""
for method in ["uniform", "distance"]:for k in range(1, 11):knn_clf = KNeighborsClassifier(n_neighbors=k, weights=method)knn_clf.fit(X_train, y_train)score = knn_clf.score(X_test, y_test)if score > best_score:best_k = kbest_score = scorebest_method = methodprint("best_method =", best_method)
print("best_k =", best_k)
print("best_score =", best_score)

明可夫斯基距离
image.png

best_score = 0.0
best_k = -1
best_p = -1for k in range(1, 11):for p in range(1, 6):knn_clf = KNeighborsClassifier(n_neighbors=k, weights="distance", p=p)knn_clf.fit(X_train, y_train)score = knn_clf.score(X_test, y_test)if score > best_score:best_k = kbest_p = pbest_score = scoreprint("best_k =", best_k)
print("best_p =", best_p)
print("best_score =", best_score)

网格搜索 Grid Search

定义搜索参数

param_grid = [{'weights': ['uniform'], 'n_neighbors': [i for i in range(1, 11)]},{'weights': ['distance'],'n_neighbors': [i for i in range(1, 11)], 'p': [i for i in range(1, 6)]}
]
knn_clf = KNeighborsClassifier()
from sklearn.model_selection import GridSearchCVgrid_search = GridSearchCV(knn_clf, param_grid)
grid_search.fit(X_train, y_train)

查看最佳分类器参数和准确度

grid_search.best_estimator_
grid_search.best_score_

image.png

更多的距离定义

  • 向量空间余弦相似度 Cosine Similarity
  • 调整余弦相似度 Adjusted Cosine Similarity
  • 皮尔森相关系数 Pearson Correlation Coefficient
  • Jaccard相似吸收 Jaccard Coeffcient

数据归一化 Feature Scaling

将所有的数据映射到同一尺度
最值归一化 normalization:把所有数据映射到0-1之间
image.png
适用于分布有明显边界的情况;受outlier影响较大

x = np.random.randint(0, 100, 100) 
(x - np.min(x)) / (np.max(x) - np.min(x))

image.png

X = np.random.randint(0, 100, (50, 2))
X = np.array(X, dtype=float)
X[:,0] = (X[:,0] - np.min(X[:,0])) / (np.max(X[:,0]) - np.min(X[:,0]))
X[:,1] = (X[:,1] - np.min(X[:,1])) / (np.max(X[:,1]) - np.min(X[:,1]))
X[:10,:]

image.png
均值方差归一化 standardization
数据分布没有明显的边界,有可能存在极端数据值
均值方差归一化:把所有数据归一到均值为0方差为1的分布中
image.png

X2 = np.random.randint(0, 100, (50, 2))
X2 = np.array(X2, dtype=float)
X2[:,0] = (X2[:,0] - np.mean(X2[:,0])) / np.std(X2[:,0])
X2[:,1] = (X2[:,1] - np.mean(X2[:,1])) / np.std(X2[:,1])

image.png

测试数据集的归一化

测试数据说模拟真实环境

  • 真实环境很有可能无法得到所有测试数据的均值和方差
  • 对数据的归一化也是算法的一部分

(x_test-mean_train)/std_train

scikit-learn中的Scaler

image.png
加载数据

import numpy as np
from sklearn import datasets
iris = datasets.load_iris()
X = iris.data
y = iris.target

数据分割

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=666)

数据归一化

from sklearn.preprocessing import StandardScaler 
standardScalar = StandardScaler() 
standardScalar.fit(X_train)
standardScalar.transform(X_train)#归一化

image.png
归一化结果赋值

X_train = standardScalar.transform(X_train)
X_test_standard = standardScalar.transform(X_test) 

使用归一化后的数据进行knn分类

from sklearn.neighbors import KNeighborsClassifier
knn_clf = KNeighborsClassifier(n_neighbors=3)
knn_clf.fit(X_train, y_train)
knn_clf.score(X_test_standard, y_test)

实现自己的standardScaler

import numpy as npclass StandardScaler:def __init__(self):self.mean_ = Noneself.scale_ = Nonedef fit(self, X):"""根据训练数据集X获得数据的均值和方差"""assert X.ndim == 2, "The dimension of X must be 2"self.mean_ = np.array([np.mean(X[:,i]) for i in range(X.shape[1])])self.scale_ = np.array([np.std(X[:,i]) for i in range(X.shape[1])])return selfdef transform(self, X):"""将X根据这个StandardScaler进行均值方差归一化处理"""assert X.ndim == 2, "The dimension of X must be 2"assert self.mean_ is not None and self.scale_ is not None, \"must fit before transform!"assert X.shape[1] == len(self.mean_), \"the feature number of X must be equal to mean_ and std_"resX = np.empty(shape=X.shape, dtype=float)for col in range(X.shape[1]):resX[:,col] = (X[:,col] - self.mean_[col]) / self.scale_[col]return resX

有关k近邻算法

解决分类问题
天然可以解决多分类问题
思想简单,效果强大
最大缺点:效率低下
如果训练集有m个样本,n个特征,则预测每一个新的数据,需要O(m*n)
优化 使用树结构:KD-Tree,Ball-Tree
缺点2:高度数据相关
缺点3:预测结果不具有可解释性
维数灾难
随着维度的增加,“看似相近”的两个点之间的距离越来越大
解决方法:降维、

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/664773.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu20.04安装sumo

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 有问题&#xff0c;请大家指出&#xff0c;争取使方法更完善。这只是ubuntu安装sumo的一种方法。一、注意事项1、首先明确你的ubuntu的用户名是什么 二、sumo安装1.…

基于springboot篮球论坛系统源码和论文

首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了系统的需求基础上需要进一步地设计系统,主要包罗软件架构模式、整体功能模块、数据库设计。本项…

国家博物馆逆向抢票协议

逆向工程的具体步骤可以因项目和目标系统的不同而有所变化。然而&#xff0c;以下是一般逆向工程的一般步骤&#xff1a; 1. 分析目标系统&#xff1a;对待逆向的系统进行调研和了解&#xff0c;包括其架构、功能、使用的技术等方面的信息。 2. 反汇编或反编译&#xff1a;使…

保姆级CDN使用教程,解决可能出现的各种问题

如果你还没有注册雨云&#xff08;rainyun&#xff09;&#xff0c;可以通过该链接进行注册雨云 - 新一代云服务提供商 通过该链接注册是可以白嫖到优惠券的&#xff0c;可以白嫖CDN。 比直接注册划算。 雨云的cdn在国内表现是非常不错的&#xff0c;而且不需要域名进行备案 在…

如何创建长期有效的文件二维码?支持多文件批量生成单独二维码

现在很多人为了避免文件通过文件有时效的问题&#xff0c;会将文件生成二维码之后来使用&#xff0c;将文件存入二维码中通过扫码调取云端的储存的数据来实现文件的预览或者下载。那么对于想要学习文件二维码制作的小伙伴&#xff0c;可以学习下面的方法来制作&#xff0c;利用…

flask基于django大数据的证券股票分析系统python可视化大屏

证券分析系统采用B/S架构&#xff0c;数据库是MySQL。网站的搭建与开发采用了先进的Python进行编写&#xff0c;使用了Django框架。该系统从两个对象&#xff1a;由管理员和用户来对系统进行设计构建。主要功能包括&#xff1a;个人信息修改&#xff0c;对股票信息、股票买入、…

XML传参方式

export function groupLoginAPI(xmlData) {return http.post(/tis/group/1.0/login, xmlData, {headers: {Content-Type: application/xml,X-Requested-With: AAServer/4.0,}}) }import {groupLoginAPI} from "../api/user"; function (e) { //xml格式传参let groupX…

网络安全全栈培训笔记(60-服务攻防-中间件安全CVE复现WeblogicJenkinsGlassFish)

第60天 服务攻防-中间件安全&CVE复现&Weblogic&Jenkins&GlassFish 知识点: 中间件及框架列表: lIS,Apache,Nginx,Tomcat,Docker,Weblogic,JBoos,WebSphere,Jenkins, GlassFish,Jira,Struts2,Laravel,Solr,Shiro,Thinkphp,Sprng,Flask,jQuery 1、中间件-Web…

【C/C++ 10】扫雷小游戏

一、题目 写一个扫雷小游戏&#xff0c;每次输入一个坐标&#xff0c;若该处是地雷&#xff0c;则游戏失败&#xff0c;若该处不是地雷&#xff0c;则显示周围地雷数量&#xff0c;若扫除全部非地雷区域&#xff0c;则扫雷成功。 二、算法 设置两张地图&#xff08;二维数组&…

chisel decoupled

Decoupled 即为接口包装一层valid 和 ready &#xff0c;decoupled 默认方向为输出&#xff0c;如果需要输入&#xff0c;可以加.flip, Decoupled 可以直接调用Bundle或者Bits&#xff0c;Bundle 内的端口也应该用bits定义 注意: ready和valid不能组合耦合&#xff0c;否则可能…

C# SSH.NET 长命令及时返回

在SSH中执行长时间的命令&#xff0c;SSH.NET及时在文本框中返回连续显示结果。 c# - Execute long time command in SSH.NET and display the results continuously in TextBox - Stack Overflow 博主管理了一个服务器集群&#xff0c;准备上自动巡检工具&#xff0c;测试在…

Linux Rootkit实验|01 基于修改系统调用表的Hook

Linux Rootkit实验&#xff5c;01 基于修改系统调用表的Hook 文章目录 Linux Rootkit实验&#xff5c;01 基于修改系统调用表的Hook实验说明实验环境实验过程一 基于修改sys_call_table的系统调用挂钩1 寻找sys_call_table内存地址2 关掉写保护3 修改sys_call_table 二 基于系统…

AI新工具(20240203) 文心一言APP数字分身;HuggingChat Assistants等

文心一言APP数字分身-一键生成专属数字分身 文心一言数字分身是一项新功能&#xff0c;用户只需一张照片和录制三句语音&#xff0c;就能创建一个专属的数字分身。这个数字分身还支持个性化定义名称、声音、MBTI性格等&#xff0c;用户可以选择是否公开自己的数字分身。这个功…

概率论中的全概率公式、贝叶斯公式解析

全概率公式 定义 全概率公式是用来计算一个事件的概率&#xff0c;这个事件可以通过几个互斥事件的并集来表示。这几个互斥事件称为“完备事件系”。实质是由原因推结果。 公式 用途 全概率公式通常用于计算一个事件的总概率&#xff0c;特别是当这个事件与几个不同的因素相关…

C++进阶--C++11 lambda表达式

C进阶--C11 lambda表达式 一、lambda表达式的概念二、lambda表达式的语法2.1 lambda表达式语法格式2.2 lambda表达式捕获列表说明 三、lambda表达式交换两个数3.1 标准写法3.2 利用捕捉列表进行捕捉3.3 利用捕捉列表进行捕捉 四、lambda表达式的底层原理4.1 底层原理4.2 lambda…

qt中使用mysql 数据库

QT 版本介绍 虽然版本是这个&#xff0c;但是工作目录确是&#xff1a; 下面陈述安装步骤 第一步&#xff1a; 就是安装MYSQL 数据库&#xff0c;在此不再赘述了&#xff0c;很多博主已经上传了。 第二步&#xff1a; 就是拷贝QT 对应mysql 的版本驱动到 QT 的编译器文件中…

【gulp+jq+html】添加环境变量,并在js中使用(判断环境,更改api接口域名)+ 附gulpfile.js代码

参考博文&#xff1a; gulp分离环境 gulp中如何配置环境变量 gulp环境变量配置 1、安装cross-env插件 npm install cross-env -d2、package.json更改scripts "scripts": {"clean": "gulp clean","serve:test": "cross-env NODE…

IDEA JDBC配置

一、在pom中添加依赖 <dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency></dependencies> 然后同步一下 二、编写代码…

C++项目-- 高并发内存池(一)

C项目-- 高并发内存池&#xff08;一&#xff09; 文章目录 C项目-- 高并发内存池&#xff08;一&#xff09;一、项目介绍1.项目来源2.内存池介绍1.池化技术2.内存池3.内存池主要解决的问题4.malloc 二、定长内存池1.定长内存池的设计2.代码实现3.性能测试4.直接在堆上申请空间…

【考研408】算法与数据结构笔记

文章目录 绪论数据结构的基本概念算法和算法评价 线性表线性表的定义和基本操作线性表的顺序表示线性表的链式表示 栈和队列栈基本操作栈的顺序存储结构栈的链式存储 队列队列常见的基本操作队列的顺序存储结构队列的链式存储结构双端队列 栈和队列的应用栈在括号匹配中的应用栈…