1 KNN算法简介
- KNN算法思想:如果一个样本在特征空间中的K个最相似的样本中的大多数属于某一个类别,则该样本也属于这个类别。
- K值过小:用较小领域中的训练实例进行预测。
- 容易受到异常点的影响
- K值的减小意味着整体模型变得复杂,容易发生过拟合
- K值过大:用较大邻域中的训练实例进行预测。
- 受到样本均衡的的问题
- K值的增大意味着整体的模型变得简单,欠拟合
- K值调优的方法:交叉验证、网格搜索;选择奇数,不要选择类别个数的整数倍;5,7()
- 分类问题&回归问题
2 KNN算法API实现
from sklearn.neighbors import KNeighborsClassifier
def dm01_knnapi_classifier():
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)
dm01_knnapi_classifier()
from sklearn.neighbors import KNeighborsRegressor
def dm02_knnapi_regressor():
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)
dm02_knnapi_regressor()
3 距离度量
3.1 欧氏距离(L2)
3.2 曼哈顿距离(MAE,L1)
- 也称“城市街区距离”,曼哈顿城市特点:横平竖直。
3.3 切比雪夫距离(Chebyshev Distance)
3.4 闵可夫斯基距离(Minkowski Distance)
4 特征预处理
- 归一化易受异常值影响
- 自然界中数据符合高斯分布
# 归一化
from sklearn.preprocessing import MinMaxScaler
def dm01_MinMaxScaler():
data=[
[90,2,10,40],
[60,4,15,45],
[75,3,13,46]
]
# 初始化归一化对象
transform=MinMaxScaler()
# 对原始特征进行变换
# data=transformer.fit_transform(data)
# 求最大值、最小值
transform.fit(data)
data=transform.transform(data)
print(data)
dm01_MinMaxScaler()
# 标准化
from sklearn.preprocessing import StandardScaler
def dm03_StandardScale():
data=[
[90,2,10,40],
[60,4,15,45],
[75,3,13,46]
]
# 初始化标准化对象
transformer=StandardScaler()
# 对原始特征进行变换
data=transformer.fit_transform(data)
# 打印归一化后的结果
print(data)
# 打印每一列数据的均值和标准差
print('transfer.mean-->',transformer.mean_)
print('transfer.var-->',transformer.var_)
dm03_StandardScale()
5 [案例]Iris分类
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
def iris_classification():
# 加载数据集
mydataset=load_iris()
# 划分数据集
X_train,X_test,y_train,y_test=train_test_split(mydataset.data,mydataset.target,test_size=0.2,random_state=22)
print(len(mydataset.data))
print(len(X_train))
print(len(X_test))
print(y_train)
# 数据预处理(标准化)
tramsfer=StandardScaler()
X_train=tramsfer.fit_transform(X_train)
X_test=tramsfer.transform(X_test)
# 模型训练
knn=KNeighborsClassifier(n_neighbors=3)
knn.fit(X_train,y_train)
# 模型评估
print(knn.score(X_test,y_test))
# 模型预测
new_data=[[0.5,1.2,2.4,5.2]]
new_data=tramsfer.transform(new_data)
print(knn.predict(new_data))
print(knn.predict_proba(new_data))
iris_classification()
6 超参数选择方法
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.preprocessing import StandardScaler
def iris_classification():
# 加载数据集
mydataset=load_iris()
# 划分数据集
X_train,X_test,y_train,y_test=train_test_split(mydataset.data,mydataset.target,test_size=0.2,random_state=22)
# 数据预处理(标准化)
tramsfer=StandardScaler()
X_train=tramsfer.fit_transform(X_train)
X_test=tramsfer.transform(X_test)
# 模型训练
knn=KNeighborsClassifier()
# knn.fit(X_train,y_train)
estimator=GridSearchCV(estimator=knn,param_grid={'n_neighbors':[3,5,7,9]},cv=4)
estimator.fit(X_train,y_train)
print(estimator.best_estimator_)
print(estimator.best_score_)
print(estimator.best_params_)
print(estimator.cv_results_)
# 模型评估
print(estimator.score(X_test,y_test))
# 模型预测
new_data=[[0.5,1.2,2.4,5.2]]
new_data=tramsfer.transform(new_data)
print(estimator.predict(new_data))
print(estimator.predict_proba(new_data))
iris_classification()
7 [案例]手写数字识别
import pandas as pd
from collections import Counter
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsRegressor
import joblib
# 数据加载
data=pd.read_csv('手写数字识别.csv')
# 数据处理(可视化)
x=data.iloc[:,1:]
y=data.iloc[:,0]
# print(Counter(y))
# print(x.shape)
# digit=x.iloc[1000].values.reshape(28,28)
# print(digit)
# plt.imshow(digit,cmap='gray')
# plt.show()
# print(y.iloc[1000])
# 特征工程(归一化)
x=data.iloc[:,1:]/255
y=data.iloc[:,0]
# 数据集划分
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,stratify=y,random_state=0)
# 模型训练
knn=KNeighborsClassifier(n_neighbors=3)
knn.fit(x_train,y_train)
# 模型评估与预测
print(knn.score(x_test,y_test))
# 模型保存
joblib.dump(knn,'knn.path')
# 预览待识别图片
img=plt.imread('demo.png')
plt.imshow(img,cmap='gray')
plt.show()
# 加载模型进行训练
model=joblib.load('knn.path')
print(model.predict(img.reshape(1,-1)))