本文素材均来源于网络,参考黑马与网易教程

目录

一、什么是KNN算法

1.KNN

2.公式

3.小结

4.实现流程

二、KNN 与 SciKit-learn数据集

1.简单数据的KNN算法

2.SciKit-learn数据学习

3.重新封装自制KNN

1. 代码封装

2.测试

三、训练集与测试集的划分

1.查看鸢尾花数据集

2.训练集与测试集的分割

3.使用我们的算法

4.Sklearn 的train_test_spilt¶

四、分类准确度判断

1.手写数字模块

2.封装自制的accurac_score

3.SciKit-learn 中的 accuracy_score¶

五、超参数(Hyper-Parameters)

1. 超参数

2. 寻找最优K

3. 搜索明科夫斯基距离相应的P

3.1 闵可夫斯基距离(Minkowski Distance)

3.2 闵氏距离的缺点:

3.3 改变超参数P来判断具体公式效果

六、更多参数与网格搜索

1.网格搜索和更多的KNN超参数

2.Grid Search

3.CV参数

4.其他超参数

七、数据归一化(Feature Scaling)

1.最值归一化( Normalization)

2.均值方差归一化

八、Scaler-in-Scikit-Learn

1. playML包

2. Scikit-learn中的Scaler

2.1 首先对训练数据集进行处理scikit-learn中的StandardScaler

2.2 使用归一化后的数据进行knn分类 训练跟测试必须同时进行归一化处理

2.3 实现我们自己的standardScaler


一、什么是KNN算法

1.KNN

KNN是机器学习里面一个比较经典的算法,又被称之为K近邻算法(K Nearest Neighbor),同样也是一个非常容易理解的算法。

定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。

2.公式

正如两个样本之间的距离如下图公式所示:

本文中我们采用的数据集均放置于Scikit-learn中

3.小结

最近邻 (k-Nearest Neighbors,KNN) 算法是一种分类算法,

1968年由 Cover 和 Hart 提出,应用场景有字符识别、文本分类、图像识别等领域。

该算法的思想是:一个样本与数据集中的k个样本最相似,如果这k个样本中的大多数属于某一个类别.

4.实现流程

1)计算已知类别数据集中的点与当前点之间的距离

2)按距离递增次序排序

3)选取与当前点距离最小的k个点

4)统计前k个点所在的类别出现的频率

5)返回前k个点出现频率最高的类别作为当前点的预测分类

二、KNN 与 SciKit-learn数据集

1.简单数据的KNN算法

首先看看我们本地pycharm中的文件结构,KNN_funition里的knn是我们自己写的比较简单的函数,外面的KNN.py是比较复杂的KNN。

接下来我们在jupyter notebook中来实现一个简单的KNN函数

# jupyter中需要借助numpy 与matplotlib进行计算与图形化
# 对数据进行分类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]]
# 标签值y为
raw_data_y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]# 将X 与 y均导入到训练容器中
X_train = np.array(raw_data_X)
y_train = np.array(raw_data_y)x = np.array([8.093607318, 3.365731514])# 导入自己写的KNN_function中的简单KNN计算函数
%run KNN_function/KNN.py
# 封装一个自制函数
predict_y = kNN_classify(6, X_train, y_train, x)# 最终输出 predict_y = 1

封装的自制KNN函数如下

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"# 欧式距离   取最近距离索引 放入nearestdistances = [sqrt(np.sum((x_train - x)**2)) for x_train in X_train]nearest = np.argsort(distances)# 最接近的数据为 topK_y# 最终投票 votes topK_y = [y_train[i] for i in nearest[:k]]votes = Counter(topK_y)return votes.most_common(1)[0][0]

2.SciKit-learn数据学习

其实 KNN可以理解为 :几乎不需要训练( fit ),甚至可以被认为是没有模型的算法
让我们从底层来编写KNN算法

from sklearn.neighbors import KNeighborsClassifier# 创建实例 n_neighbors KNN的K值
# 假设我以6为邻居数进行判定
KNN_classifier = KNeighborsClassifier(n_neighbors=6)# fit 拟合过程
KNN_classifier.fit(X_train, y_train)
# out: KNeighborsClassifier(n_neighbors=6)# 调整x点 为矩阵
X_predict = x.reshape(1, -1)# 需要预测的矩阵为
# X_predict# 预测
y_predict = KNN_classifier.predict(X_predict)# 分类后输出为1
y_predict[0]

3.重新封装自制KNN

1. 代码封装

总结以上的代码,这里贴上一个比较完整的自制代码,并且进行测试。

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 = None # 私有值不可改变self._y_train = Nonedef fit(self, X_train, y_train):"""根据训练数据集X_train和y_train训练KNN分类器"""self._X_train = X_trainself._y_train = y_train # KNN简单写完了return 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_predict的预测结果"""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]

2.测试

本文90%代码在jupyter notebook中运行,少量需要pycharm结合jupyter。

#封装
%run KNN.py# 自制的函数6个排序 KNN_classifi
knn_clf = KNNClassifier(k=6)# 训练
knn_clf.fit(X_train, y_train)
y_predict = knn_clf.predict(X_predict)# 预测仍然是1
y_predict

三、训练集与测试集的划分

1.查看鸢尾花数据集

选择在iris数据集(鸢尾花数据集)上进行测试,代码简单如下示意:

鸢尾花数据集大约是由四种花的指标进行判断分类出是那种鸢尾花。

# 导包
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets# 装载数据
iris = datasets.load_iris()  # jupyter中可以输入名字进行查看# 载入鸢尾花数据以及分类值
X = iris.data
y = iris.target# 看看数据集有多少数据(鸢尾花数据集很小)
print(X.shape)   # (150, 4)
print(y.shape)   # (150, )

2.训练集与测试集的分割

(1).查看y数组的数值

可以看出被分为0,1,2,3 四种品种

(2).那么如何对数据进行划分

如何对数据进行划分
考虑划分问题需要进行乱序划分
为了一一对应 先合成矩阵


# 对149个数据的 索引进行乱序处理
shuffle_indexes = np.random.permutation(len(X)) # 乱序X个数据索引
shuffle_indexes # 索引随机排序

之后再对数据进行划分,按照2 8 法则进行,测试20%数据,训练占用80%数据

# 2 8分测试2 训练8
test_ratio = 0.2
test_size = int(len(X) * test_ratio)# 测试数据大小为print(test_size) # 输出 30 显示 # 得到对应索引 乱序
test_indexes = shuffle_indexes[:test_size] # 设置前30个为测试
train_indexes = shuffle_indexes[test_size:]# 设置第31个开始为训练# 传入训练数据
# 塞入索引得到数据
X_train = X[train_indexes]
y_train = y[train_indexes]X_test = X[test_indexes]
y_test = y[test_indexes]print(X_train.shape) #(120,4)
print(y_train.shape) # (120,)print(X_test.shape) # 矩阵
print(y_test.shape) # 向量# (30, 4)
# (30,)

3.使用我们的算法

准备一个playML工具箱,内部放置自己写的函数,大致结构如下所示

__init__.py 函数为空不用写

KNN.py代码如下所示

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))   # n 列数据进行欧式计算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

model_selection.py如下所示

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

开始使用我们自己写的算法

from playML.model_selection import train_test_split      # 封装成类
X_train, X_test, y_train, y_test = train_test_split(X, y)# 注意对齐数据print(X_train.shape)
print(y_train.shape)print(X_test.shape)
print(y_test.shape)"""
(120, 4)
(120,)
(30, 4)
(30,)
"""from playML.kNN import KNNClassifier
my_knn_clf = KNNClassifier(k=3)
# 预测结果
y_predict = my_knn_clf.predict(X_test)
# array([1, 2, 1, 1, 0, 0, 1, 2, 0, 0, 2, 0, 2, 0, 0, 0, 2, 1, 1, 1, 2, 2,
#       0, 2, 2, 0, 0, 1, 1, 0])# 要看预测率
sum(y_predict == y_test)
sum(y_predict == y_test) / len(y_test)  # 0.9666666

4.Sklearn 的train_test_spilt¶

采用现有的Sklearn中的api进行分割计算是非常简单的,完全不像上面一样需要自己造轮子


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) # 默认值一般为0.2# 注意对齐数据print(X_train.shape)
print(y_train.shape)print(X_test.shape)
print(y_test.shape)print(y_predict)

四、分类准确度判断

这时,我们的playML包又多了一个.py文件

import numpy as np# 准确度度量
# 真实值与预测值def 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)

1.手写数字模块

手写数字数据集与之前的鸢尾花数据集合相比起来,复杂度上升了不少。我们先载入该数据集,看看数据集的描述。

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets# 载入手写数字模块
digits = datasets.load_digits()
digits.keys()
# dict_keys(['data', 'target', 'frame', 'feature_names', 'target_names', 'images',
# 'DESCR'])# 数据集的描述
print(digits.DESCR)

译文:
* *数据集特征:* *
:实例数:1797
:属性个数:64
:属性信息:8 × 8的图像的整数像素范围0..16。
:缺少属性值:无
创作者:E. Alpaydin (Alpaydin '@' boun.edu.tr)
:日期:1998年七月

我们继续看代码

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets# 载入手写数字模块
digits = datasets.load_digits()
digits.keys()
# dict_keys(['data', 'target', 'frame', 'feature_names', 'target_names', 'images',
# 'DESCR'])# 数据集的描述
print(digits.DESCR)# 数据内容8*8矩阵图  (1797, 64)
X = digits.data
print(X.shape)y = digits.target
print(y.shape )

将一堆混乱的数据进行可视化,专门针对X[666]数字进行可视化

# 查看第666个数字的样式
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) #api自查
plt.show()

继续我们的训练学习,最终对数据进行分割,预测,评分得到实际数据0.986

# 同样也需要进行数据分割
# 用标准KNNapi分割
from playML.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_ratio=0.2)# 自己写的分类器进行预测
from playML.kNN import KNNClassifier
my_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)  # 0.9860724233983287

2.封装自制的accurac_score

我们将预测准确度的测评机制集成到playML包中

from playML.metrics import accuracy_scoreaccuracy_score(y_test, y_predict) # 0.9916666666666667my_knn_clf.score(X_test, y_test)  # 0.9944444444444445

3.SciKit-learn 中的 accuracy_score¶

最后还是来看看官方的代码预测的结果,之前自制的代码都是为了让自己的理解更加深刻。

# 封装准确度  加入随机种子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)# 调用score from sklearn.neighbors import KNeighborsClassifier
knn_clf = KNeighborsClassifier(n_neighbors=3)
knn_clf.fit(X_train, y_train)
y_predict = knn_clf.predict(X_test)# 不需要每次计算score 进行比较
from sklearn.metrics import accuracy_score
accuracy_score(y_test, y_predict) # 0.9916666666666667# emm 准确率略微提升?my_knn_clf.score(X_test, y_test) # 0.9944444444444445

五、超参数(Hyper-Parameters)

1. 超参数

机器学习和深度学习工作流中最困难的部分之一,就是为模型找到最好的超参数,机器学习和深度学习模型的性能与超参数直接相关。超参数调优的越好,得到的模型就越好。调优超参数可能是非常乏味和困难的,更像是一门艺术而不是科学。

如何寻找最好的超参数:1.领域知识  2.经验数值  3.实验搜索

# 寻找最好的超参数
# 领域知识 经验数值 实验搜索
# 仍然用数字来计算import numpy as np
from sklearn import datasets
digits = datasets.load_digits()
X = digits.data
y = digits.target# 加入随机种子666
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)# 导入KNN库
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)# 0.9916666666666667

2. 寻找最优K

# 初始化最好值为0
# 调参 如果是10 调为10以上
# 超参数 K
# 超参数 method 考虑距离权重   倒数写法 可以解决平票问题best_score = 0.0
best_k = -1
best_method = ""   # 考虑权重 先选空 不考虑for method in ["uniform", "distance"]:for k in range(1, 11):    # 就寻找KNN 1 -10 个K 判断哪个K最好knn_clf = KNeighborsClassifier(n_neighbors=k, weights=method)  # 传入循环kknn_clf.fit(X_train, y_train)              # 训练score = knn_clf.score(X_test, y_test)      #查分数if score > best_score:                     # 分数好 k 更新best_k = k       best_score = scorebest_method = methodprint("best_method =", best_method)
print("best_k =", best_k)                    # 分别打印出最好的数值
print("best_score =", best_score)

3. 搜索明科夫斯基距离相应的P

3.1 闵可夫斯基距离(Minkowski Distance)

闵氏距离不是一种距离,而是一组距离的定义,是对多个距离度量公式的概括性的表述。

两个n维变量a(x11,x12,…,x1n)与b(x21,x22,…,x2n)间的闵可夫斯基距离定义为:

其中p是一个变参数:

当p=1时,就是曼哈顿距离;

在曼哈顿街区要从一个十字路口开车到另一个十字路口,驾驶距离显然不是两点间的直线距离。这个实际驾驶距离就是“曼哈顿距离”。曼哈顿距离也称为“城市街区距离”(City Block distance)。

当p=2时,就是欧氏距离;

欧氏距离是最容易直观理解的距离度量方法,我们小学、初中和高中接触到的两个点在空间中的距离一般都是指欧氏距离。

当p→∞时,就是切比雪夫距离。

国际象棋中,国王可以直行、横行、斜行,所以国王走一步可以移动到相邻8个方格中的任意一个。国王从格子(x1,y1)走到格子(x2,y2)最少需要多少步?这个距离就叫切比雪夫距离。

根据p的不同,闵氏距离可以表示某一类/种的距离。

小结:

1 闵氏距离,包括曼哈顿距离、欧氏距离和切比雪夫距离都存在明显的缺点:

e.g. 二维样本(身高[单位:cm],体重[单位:kg]),现有三个样本:a(180,50),b(190,50),c(180,60)。

a与b的闵氏距离(无论是曼哈顿距离、欧氏距离或切比雪夫距离)等于a与c的闵氏距离。但实际上身高的10cm并不能和体重的10kg划等号。

3.2 闵氏距离的缺点:

​ (1)将各个分量的量纲(scale),也就是“单位”相同的看待了;

​ (2)未考虑各个分量的分布(期望,方差等)可能是不同的。

3.3 改变超参数P来判断具体公式效果

# 搜索时间较长  K*p 类似网格搜索 超参数之间还有互相依赖关系
%%time
best_score = 0.0
best_k = -1
best_p = -1  # 修改pfor k in range(1, 11):for p in range(1, 6):  # 双重循环 每次k都得查一次P公式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)

六、更多参数与网格搜索

1.网格搜索和更多的KNN超参数

# 仍然是数字签名
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
sk_knn_clf = KNeighborsClassifier(n_neighbors=4, weights="uniform")
sk_knn_clf.fit(X_train, y_train)
sk_knn_clf.score(X_test, y_test)

2.Grid Search

网格搜索

# 定义搜索的参数 字典 网格搜索
param_grid = [{'weights': ['uniform'],  # 键 对应uniform 搜索范围'n_neighbors': [i for i in range(1, 11)]},{'weights': ['distance'], # 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 GridSearchCV #交叉验证grid_search = GridSearchCV(knn_clf, param_grid) # 哪个分类器 参数是啥# 相对较慢 打点计时 # 返回最佳分类器的超参数
%%time
grid_search.fit(X_train, y_train)

# 最佳分类器对应的值
grid_search.best_estimator_  # KNeighborsClassifier(n_neighbors=1)# 最佳分数
grid_search.best_score_      # 0.9860820751064653# 对搜索数组而言最佳参数如下
grid_search.best_params_    #  {'n_neighbors': 1, 'weights': 'uniform'}

knn_clf = grid_search.best_estimator_# 此时对于X_test进行计算的结果
knn_clf.predict(X_test)

3.CV参数

# n_jobs cpu核数-1最大  Verbose一些输出 帮助更好理解输出
# %time
grid_search = GridSearchCV(knn_clf, param_grid, n_jobs=-1, verbose=2)
grid_search.fit(X_train, y_train)

4.其他超参数

metrics: sklearn.neighbors.DistanceMetric — scikit-learn 1.0 documentation

七、数据归一化(Feature Scaling)

1.最值归一化( Normalization)

数据归一化,主要是为了数据处理方便提出来的,把数据映射到0~1范围之内处理,更加便捷快速。

import numpy as np
import matplotlib.pyplot as plt# 随机生成向量 0-100之间
x = np.random.randint(0, 100, 100) 

# 每个值减去最小值  除以 最大值减去最小值(x - np.min(x)) / (np.max(x) - np.min(x))

可以看到归一化处理后数据变为0-1之间

# 建立矩阵
X = np.random.randint(0, 100, (50, 2))
# 前十行 每一列
X[:10,:]

X = np.array(X, dtype = float)
# 前十行 每一列
X[:10,:]

# 最值归一化 有n个特征写循环即可
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]))
print(X[:10,:])

plt.scatter(X[:,0], X[:,1])
plt.show()

# 第0列对应 均值
np.mean(X[:,0])# 第0列方差
np.std(X[:,0])np.mean(X[:,1])np.std(X[:,1])

2.均值方差归一化

# 随机矩阵 50 * 2
X2 = np.random.randint(0, 100, (50, 2))X2 = np.array(X2, dtype=float)
X2[:10,:]# 公式如下
X2[:,0] = (X2[:,0] - np.mean(X2[:,0])) / np.std(X2[:,0])
X2[:,1] = (X2[:,1] - np.mean(X2[:,1])) / np.std(X2[:,1])# 散点图打点
plt.scatter(X2[:,0], X2[:,1])
plt.show()# 第0列均值
np.mean(X2[:,0])# 方差 均值放0 方差为1 的范围
np.std(X2[:,0])np.mean(X2[:,1])np.std(X2[:,1])

八、Scaler-in-Scikit-Learn

1. playML包

终于到了最后一步,我们来看看自己写的代码工具。

最后增加了一份 preprocessing.py文件 其代码大致如下所示

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

2. Scikit-learn中的Scaler

2.1 首先对训练数据集进行处理scikit-learn中的StandardScaler

import numpy as np
from sklearn import datasets
iris = datasets.load_iris()
X = iris.data
y = iris.target# 仍然是鸢尾花 前十行数据如下
print(X[:10,:])

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)
#数据预处理过程 preprocessing
#实例 均值归一化
from sklearn.preprocessing import StandardScaler
standardScalar = StandardScaler() # 均值方差归一化的关键信息
standardScalar.fit(X_train)# 平均值 传入计算出的变量mean_
standardScalar.mean_# 标准差  (描述数据分布范围)
standardScalar.scale_# 归一化结果
standardScalar.transform(X_train)

2.2 使用归一化后的数据进行knn分类 训练跟测试必须同时进行归一化处理

from sklearn.neighbors import KNeighborsClassifier
knn_clf = KNeighborsClassifier(n_neighbors=3)
knn_clf.fit(X_train, y_train)# 准确率100% 由于鸢尾花数据集很小
knn_clf.score(X_test_standard, y_test)knn_clf.score(X_test, y_test) # 0.33333333333333331

2.3 实现我们自己的standardScaler

# 分割
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=666)# 训练
from playML.preprocessing import StandardScaler
my_standardScalar = StandardScaler()
my_standardScalar.fit(X_train)print(my_standardScalar.mean_)
print(my_standardScalar.scale_)X_train = standardScalar.transform(X_train)print(X_train[:10,:])

05-KNN 基础学习相关推荐

  1. 《零基础学习Liunx之三》 The following takes place between 04:00PM and 05:00PM

    previously on 零基础学习Liunx: 上一次讲到Unix的多任务处理. 7.计算机如何保证不同的进程之间互相独立运行? 内核调度器负责将不同的进程区分开,同时,操作系统也要保障各个进程在 ...

  2. python零基础实例-零基础学习Python开发练习100题实例(1)

    零基础学习Python开发练习100题实例(1) 2018-02-25 09:37:59 2864浏览 1.题目:有四个数字:1.2.3.4,能组成多少个互不相同且无重复数字的三位数?各是多少? 程序 ...

  3. python基础代码事例-零基础学习Python开发练习100题实例(2)

    零基础学习Python开发练习100题实例(2) 2018-02-26 13:11:39 1934浏览 11.题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个 ...

  4. Erlang基础学习总结2

    Erlang基础学习总结2 列表函数和操作 lists:max(). lists:reverse([1,2,3]). lists: sort([2,3,1]). lists: split(2,[3,4 ...

  5. 计算机AL教程笔记,计算机系统基础学习笔记(2)-数据的位运算操作

    C语言的位运算操作包括两类,逻辑运算操作和逻辑移位操作. 逻辑运算操作 C语言提供了四种按位逻辑操作符,分别是按位取反,按位与,按位或,按位异或.在编译时,编译器会根据操作数的宽度分别转换为不同的指令 ...

  6. Maven-学习笔记05【基础-使用骨架创建Maven的Java工程】

    Java后端 学习路线 笔记汇总表[黑马程序员] 黑马程序员(腾讯微云)Maven基础讲义.pdf Maven-学习笔记01[基础-Maven基本概念] Maven-学习笔记02[基础-Maven的安 ...

  7. ASP.Net MVC开发基础学习笔记(5):区域、模板页与WebAPI初步

    http://blog.jobbole.com/85008/ ASP.Net MVC开发基础学习笔记(5):区域.模板页与WebAPI初步 2015/03/17 · IT技术 · .Net, Asp. ...

  8. 基础学习笔记之opencv(14):随机数发生器绘制文字

    本文主要介绍下opencv中自带的一个随机数发生器的类RNG,这里我用这个类来画一些图形,和基础学习笔记之opencv(13):基本绘图 一文中类似,只是 这里画出来图像的坐标,大小,颜色,角度等所有 ...

  9. 2022年Spark基础学习笔记目录

    一.Spark学习笔记 在私有云上创建与配置虚拟机 Spark基础学习笔记01:初步了解Spark Spark基础学习笔记02:Spark运行时架构 Spark基础学习笔记03:搭建Spark单机版环 ...

  10. Spark基础学习笔记16:创建RDD

    文章目录 零.本讲学习目标 一.RDD为何物 (一)RDD概念 (二)RDD示例 (三)RDD主要特征 二.做好准备工作 (一)准备文件 1.准备本地系统文件 2.准备HDFS系统文件 (二)启动Sp ...

最新文章

  1. xshell如何登陆堡垒机_Xshell连接有跳板机(堡垒机)的服务器
  2. CV圈太卷了!继谷歌提出MLP-Mixer之后,清华、牛津等学者又发表三篇MLP相关论文...
  3. 解决 Illegal DefaultValue null for parameter type integer 异常
  4. VT-x,VT-d简介
  5. mysql 之 一个库中所有表复制到另一个数据库中的方法和工具
  6. 论文阅读笔记(二)【ACL2021】知识抽取NER
  7. 边缘计算安全技术综述
  8. Telnet 1433端口
  9. 精品资源:40个实用的 PSD 贴纸模板《下篇》
  10. JS:ES6-7 迭代器与生成器
  11. 罗永浩关联直播交易案遭“问停”;中国量子计算原型机“九章”问世;pip 20.3 发布 | 极客头条...
  12. 机器学习:分类算法SVM(支持向量机)
  13. Kafka【问题 02】KafkaTemplate 报错 Bootstrap broker localhost:9092 (id: -1 rack: null) disconnected 问题解决
  14. 用Python生成人人贷借款理由词云图
  15. 微信小程序实战 wx.showNavigationBarLoading(),下拉动画配置无效
  16. 微信小程序:简洁UI好玩的文字转换emoji表情
  17. 班长快速统计到班上同学信息(excel表格)
  18. [NOIP 2015TG D2T3] 运输计划
  19. text/template与html/template的区别
  20. 国防科技大学 计算机硬件技术基础,国防科技大学--操作系统教程【40讲】--罗宇...

热门文章

  1. 为什么浏览器具备查看网页源代码这一功能?
  2. JS 传参Url加密解密
  3. 高效管理你的碎片化知识——RSS打造完美信息流
  4. 中集集团人工智能企业CIMCAI中集飞瞳,深入贯彻国家关于智慧港口数字港口建设部署要求全球顶尖港航AI核心技术打造超一流智慧港口
  5. 蓝桥杯2018省赛Java开发大学C组思路总结
  6. 如何用DJI GS pro制作实景三维模型教程
  7. 十分钟开发物联网:烟雾感应监测(Wifi版)
  8. 如何在Linux终端使用录屏工具Asciinema?
  9. linux查看USB运行状态,如何检查Linux中是否启用了USB3.0 UASP(USB附加SCSI协议)模式?...
  10. 亲密关系科学(06)DISC性格优劣势分析