KNN算法
KNN算法简介
K-近邻算法(K-Nearest Neighbors,KNN)是一种基本的机器学习算法,它主要用于分类任务,同时也可以用于回归任务。KNN算法的核心思想非常简单:一个新样本的分类结果,由其最近的K个邻居投票决定。
比如根据你的“邻居“来判断你的类别
KNN算发思想:如果一个样本在特征空间中k个最相似的样本中的大多数属于某一类别,则样本也属于这个类别
K-近邻算法
• 样本相似性:样本都是属于一个任务数据集的。样本距离越近则越相似。
K-近邻算法流程
分类流程
1.计算未知样本到每一个训练样本的距离
2.将训练样本根据距离大小升序排列
3.取出距离最近的K 个训练样本
4.进行多数表决,统计K 个样本中哪个类别
的样本个数最多
5.将未知的样本归属到出现次数最多的类别
回归流程
1.计算未知样本到每一个训练样本的距离
2.将训练样本根据距离大小升序排列
3.取出距离最近的K 个训练样本
4.把这个K 个样本的目标值计算其平均值
5.作为将未知的样本预测的值
K值选择
•K值过小:用较小邻域中的训练实例进行预测容易受到异常点的影响K值的减小就意味着整体模型变得复杂,容易发生过拟合
•K值过大:用较大邻域中的训练实例进行预测受到样本均衡的问题且K值的增大就意味着整体的模型变得简单,欠拟合
无论输入实例是什么,只会按训练集中最多的类别进行预测,受到样本均衡的影响
KNN算法API使用-分类问题
KNN分类API:
sklearn.neighbors.KNeighborsClassifier(n_neighbors=5)
#n_neighbors:int,可选(默认= 5),k_neighbors查询默认使用的邻居数
from sklearn.neighborsimport KNeighborsClassifier
def dm01_knnapi_分类():
estimator = KNeighborsClassifier(n_neighbors=1)
X = [[0], [1], [2], [3]]
y = [0, 0, 1, 1]
estimator.fit(X, y)
myret= estimator.predict([[4]])
print('myret-->', myret)
KNN算法API使用-回归问题
KNN回归API:
sklearn.neighbors.KNeighborsRegressor(n_neighbors=5)
from sklearn.neighborsimport KNeighborsRegressor
def dm02_knnapi_回归():
estimator = KNeighborsRegressor(n_neighbors=2)
X = [[0, 0, 1],
[1, 1, 0],
[3, 10, 10],
[4, 11, 12]]
y = [0.1, 0.2, 0.3, 0.4]
estimator.fit(X, y)
myret= estimator.predict([[3, 11, 10]])print('myret-->', myret)
距离度量(常用距离计算方法)
欧式距离(Euclidean Distance)
直观的距离度量方法
两个点在空间中的距离一般都是指欧氏距离
曼哈顿距离(Manhattan Distance)
也称为“城市街区距离”(City Block distance),曼哈顿城市特点:横平竖直
举个例子:
ABCD四点X=[[1,1],[2,2],[3,3],[4,4]],
计算ABACADBCBD曼哈顿距离
经计算得: AB=|2−1|+|2−1|=2
d = 2 4 6 2 4 2
切比雪夫距离(Chebyshev Distance)
国际象棋中,国王可以直行、横行、斜行,所以国王走一步可以移动到相邻8个方格中的任意一个。
国王从格子(x1,y1)走到格子(x2,y2)最少需要多少步?这个距离就叫切比雪夫距离。
举个例子:
ABCD四点X=[[1,1],[2,2],[3,3],[4,4]],
计算ABACADBCBD曼哈顿距离
经计算得: AB=max(2−1,2−1)=1
d = 1 2 3 1 2 1
闵可夫斯基距离(MinkowskiDistance)
•不是一种新的距离的度量方式。
•是对多个距离度量公式的概括性的表述
•两个n维变量a(x11,x12,…,x1n)与b(x21,x22,…,x2n)
间的闵可夫斯基距离定义为
其中p是一个变参数:
当p=1 时,就是曼哈顿距离;
当p=1 时,就是曼哈顿距离;
当p=2 时,就是欧氏距离;
当p→∞ 时,就是切比雪夫距离
根据p 的不同,闵氏距离可表示某一类种的距离
特征预处理
归一化
特征的单位或者大小相差较大,或者某特征的方差相比其他的特征要大出几个数量级,容易影响
(支配)目标结果,使得一些模型(算法)无法学习到其它的特征。
数据归一化
◆如果出现异常点,影响了最大值和最小值,那么结果显然会发生改变
◆应用场景:最大值与最小值非常容易受异常点影响,鲁棒性较差,只适合传统精确小数据场景。
•归一化:通过对原始数据进行变换把数据映射到【mi,mx】(默认为[0,1])之间
数据归一化API:
sklearn.preprocessing.MinMaxScaler(feature_range=(0,1)… )
#feature_range缩放区间
#fit_transform(X) 将特征进行归一化缩放
#todo 1.导包
from sklearn.preprocessing import MinMaxScaler
#todo 2.数据
x = [[90, 2, 10, 40],
[60, 4, 15, 45],
[75, 3, 13, 46]]
#todo 3.实例化(归一化)对象
min_max_scaler = MinMaxScaler()
#todo 4.归一化对象
x_min_max = min_max_scaler.fit_transform(x)
print(f'原始数据:{x}')
print(f'归一化后的数据:\n{x_min_max}')
标准化
•数据标准化:通过对原始数据进行标准化,转换为均值为0标准差为1的标准正态分布的数据
数据标准化
◆如果出现异常点,由于具有一定数据量,少量的异常点对于平均值的影响并不大
◆应用场景:适合现代嘈杂大数据场景。(以后就是用你了)
mean 为特征的平均值
σ 为特征的标准差
数据标准化API:
sklearn.preprocessing. StandardScaler()
#fit_transform(X) 将特征进行归一化缩放
#todo 1.导包
from sklearn.preprocessing import StandardScaler
#todo 2.数据
x = [[90,2,10,40],
[60,2,5,40],
[75,3,13,46]]
#todo 3.实例化(标准化)
scaler = StandardScaler()
#todo 4 标准化对象
data = scaler.fit_transform(x)
print('data-->', data)
print('scaler.mean_-->', scaler.mean_)#均值
print('scaler.var_-->', scaler.var_)#标准差
利用KNN算法对鸢尾花分类
1 获取数据集
from sklearn.datasetsimport load_iris
iris = load_iris()
# print(iris)
# print(f'特征名->\n{iris.feature_names}\n{iris.data[:10]}')
# print(f'目标值->\n{iris.target_names}\n{iris.target}')
2 数据基本处理
import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt
#载入鸢尾花数据集并显示特征名称.feature_names
iris = load_iris()
#print(iris.feature_names)
# 把数据转换成dataframe格式设置data, columns属性目标值名称
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['target'] = iris.target
# print(f'数据展示->\n{df}')
# 指定横轴
col1 = 'sepal length (cm)'
col2 = 'sepal width (cm)'
#sns.lmplot()显示
sns.lmplot(x=col1, y=col2, data=df, hue='target', fit_reg=False)
plt.title('iris')
plt.xlabel(col1)
plt.ylabel(col2)
plt.show()
3 数据集预处理-数据标准化
from sklearn.model_selectionimport train_test_split # 数据集划分
# 加载数据集
iris = load_iris()
# 划分数据集
X_train, X_test, y_train, y_test= train_test_split(iris.data, iris.target, test_size=0.3, random_state=22)
print('数据总数量', len(mydataset.data))
print('训练集中的x-特征值', len(X_train))
print('测试集中的x-特征值', len(X_test))
print(y_train)
4 机器学习(模型训练)
#导入类库
from sklearn.preprocessingimport StandardScaler
from sklearn.model_selectionimport train_test_split
from sklearn.neighborsimport KNeighborsClassifier
# 加载数据集
iris = load_iris()
# 划分数据集
X_train, X_test, y_train, y_test= train_test_split(iris.data, iris.target, test_size=0.3, random_state=22)
# 数据集预处理-数据标准化
transfer = StandardScaler()
x_train= transfer.fit_transform(x_train)
# 让测试集的均值和方法, 转换测试集数据;
x_test= transfer.transform(x_test)
# 4 机器学习(模型训练)
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(x_train, y_train)
# 5 模型评估直接计算准确率100个样本中模型预测对了多少
myscore= knn.score(x_test, y_test)
print(‘myscore-->’, myscore)
5 模型评估
# 加载数据集
iris = load_iris()
# 划分数据集
X_train, X_test, y_train, y_test= train_test_split(iris.data, iris.target, test_size=0.3, random_state=22)
# 数据集预处理-数据标准化
transfer = StandardScaler()
x_train= transfer.fit_transform(x_train)
# 让测试集的均值和方法, 转换测试集数据;
x_test= transfer.transform(x_test)
# 机器学习(模型训练)
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(x_train, y_train)
# 利用sklearn.metrics包中的accuracy_score方法
y_predict= knn.predict(x_test)
myresult= accuracy_score(y_test, y_predict)
print('myresult-->', myresult)
6 模型预测
# 对新数据进行预测
mydata = [[5., 3.4, 1.5, 0.2],
[4.4, 2.9, 1.4, 0.2],
[4.9, 3.1, 1.5, 0.1]]
y_predict = knn.predict(mydata)
print(f'预测结果->\n{y_predict}')
7总结
1 鸢尾花数据集下载和使用
• 加载数据集mydataset = load_iris()
• 数据集属性 dataset.data .target .target_names .feature_names .DESCR
2 案例的总体处理流程
获取数据集
数据基本处理
特征工程
机器学习(模型训练)
模型评估
3 使用可视化加载和探索数据,以确定特征是否能将不同类别分开
4 通过标准化特征,并随机抽样到训练集和测试集来准备数据。
5 通过统计学,利用准确率评估机器学习模型
#-*- coding:utf-8 -*-
# @Time : 2019/1/3 0003 14:09
# @File : knn_iris.py
# @Software: PyCharm
#todo 1.导包
from sklearn.metrics import accuracy_score
from sklearn.datasets import load_iris
import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
#todo 2.加载数据集
iris = load_iris()
# print(iris)
# print(f'特征名->\n{iris.feature_names}\n{iris.data[:10]}')
# print(f'目标值->\n{iris.target_names}\n{iris.target}')
#todo 3.数据展示
def show_iris_data():
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['target'] = iris.target
# print(f'数据展示->\n{df}')
# 指定横轴
# col1 = 'sepal length (cm)'
# col2 = 'sepal width (cm)'
# sns.lmplot(x=col1, y=col2, data=df, hue='target', fit_reg=False)
# plt.title('iris')
# plt.xlabel(col1)
# plt.ylabel(col2)
# plt.show()
feature_names = iris.feature_names
# print(f'特征值->\n{feature_names}'
for i in range(len(feature_names)):
for j in range(i+1, len(feature_names)):
col1 = feature_names[i]
col2 = feature_names[j]
sns.lmplot(x=col1, y=col2, data=df, hue='target', fit_reg=False)
plt.title('iris')
plt.xlabel(col1)
plt.ylabel(col2)
plt.show()
#todo 4.数据基本处理
def data_process():
"""
数据处理和KNN模型的训练与预测。
该函数从iris数据集中加载数据,将其划分为训练集和测试集,
对数据进行标准化处理,然后训练一个KNN分类器,并对测试集进行预测,
最后输出预测的准确率以及对新数据进行预测。
"""
# 加载iris数据集
x = iris.data
y = iris.target
# 将数据集划分为训练集和测试集,测试集比例为20%
# 划分数据集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=22)
# 实例化标准化处理器,并对训练集和测试集进行标准化处理
# 标准化
ss = StandardScaler()
x_train = ss.fit_transform(x_train)
x_test = ss.transform(x_test)
# 实例化KNN分类器,设置邻居数量为5
#todo 5.实例化模型
knn = KNeighborsClassifier(n_neighbors=5)
# 使用训练集训练KNN分类器
#todo 6.模型训练
knn.fit(x_train, y_train)
# 使用训练好的分类器对测试集进行预测
#todo 7.模型评估
y_predict = knn.predict(x_test)
# 计算预测的准确率
score = accuracy_score(y_test, y_predict)
print(f'准确率->\n{score}')
# 对新数据进行预测
#todo 8.模型预测
mydata = [[5., 3.4, 1.5, 0.2],
[4.4, 2.9, 1.4, 0.2],
[4.9, 3.1, 1.5, 0.1]]
y_predict = knn.predict(mydata)
print(f'预测结果->\n{y_predict}')
if __name__ == '__main__':
data_process()
# show_iris_data()