K近邻算法介绍
- 近朱者赤,近墨者黑
- 如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一类别,则该样本也属于该类别
总结knn工作流程
- 计算待分类物体与其他物体之间的距离
- 统计距离最近的k个邻居
- 对于k个邻居,他们属于哪种分类多,待分类物体就属于哪一类
1.手动实现KNN算法
五个步骤
1.读取数据 2.数据的基本处理 3.特征工程 4.数据可视化 训练数据 特征:打斗和亲吻次数 类别:电影类型 预测数据 5.算法实现
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
- 替换Microsoft YaHei字体
- 解决坐标轴负数的负号显示问题
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
1.读取数据
my_df = pd.read_excel('电影数据.xlsx')
print(my_df)
我们需要判断美人鱼电影是动作片还是爱情片,就需要看这个电影距离哪些电影最近,我们选择近邻点个数k为3来做出判断
class MYknn(object):
def __init__(self, train_df, k):
"""
:param train_df: 训练数据
:param k: 近邻点个数
"""
self.train_df = train_df
self.k = k
def predict(self, test_df):
"""预测函数"""
self.train_df['距离'] = np.sqrt((test_df['打斗次数']-train_df['打斗次数'])**2+(test_df['打斗次数']-train_df['接吻次数'])**2)
my_types = self.train_df.sort_values(by='距离').iloc[:self.k]['电影类型']
print(my_types)
my_type = my_types.value_counts().index[0]
print(my_type)
train_df = my_df.loc[:5, ['打斗次数', '接吻次数', '电影类型']]
print(train_df)
test_df = my_df.loc[6, ['打斗次数', '接吻次数']]
print(test_df)
2.算法实现
mk = MYknn(train_df, 3)
mk.predict(test_df)
按距离排序离哪个最近,我们可以发现美人鱼电影距离这三个爱情片是最近的,所以,我们可以认为这是个爱情片。
距离3最近 然后是4 最后是5
当底下出现俩个爱情片,一个动作片的时候我们需要做出判断,得出出现次数最多的电影,来以此进行分类,可见这个电影出现最多的是爱情
2.手动实现KNN算法鸢尾花的实现
注:可以通过该类鸢尾花的 “ 花萼长度 花萼宽度 花瓣长度 花瓣宽度 ” 信息来得到,此类鸢尾花属于以下三种的哪一种 “ 山鸢尾 变色鸢尾 维吉尼亚鸢尾 ”
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
from collections import Counter
1.导入数据
iris = datasets.load_iris()
X = iris.data
Y = iris.target
print(X, Y)
2.训练数据和测试数据
- X_train, X_test, Y_train, Y_test 分别代表:训练数据集特征 测试集特征 训练数据类别 测试数据类别这四类
- 后面添加的random——state可以让随机的数值不发生改变,如果我们不添加的话,训练数据和测试数据将会随机改变
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, random_state=2003)
print(len(X_train))
3.算法实现
- 计算两个样本之间欧式距离
instance1:样本1 instance2:样本2
def euc_dis(instance1,instance2):
dist = np.sqrt(sum((instance1-instance2)**2))
return dist
4.建模
- 给定一个测试数据testInstance,通过KNN算法预测它的标签
X:训练数据的特征 y:训练数据的标签 testInstance : 测试数据 假定 一个测试数据array类型 k:选择多少个近邻点
def knn_classify(X, y, testInstance, k=3):
distance = [euc_dis(x,testInstance) for x in X]
print(distance)
kneighbors = np.argsort(distance)[:k]
count = Counter(y[kneighbors])
return count.most_common()[0][0]
print(np.argsort([11, 2.5, 3.6, 1.5, 9]))
5.测试(预测模型的好坏)
- 其中 012 代表着三种类别
- 模型的正确率是0.921,可见模型效果很好
pred = [knn_classify(X_train,Y_train,data,3) for data in X_test]
print(pred)
count = np.count_nonzero((pred == Y_test) == True)
print(count)
print('模型预测正确率:%.3f'%(count/len(X_test)))
- 当我们发现列表中第一个数据是1 ,代表着第一个花的四个特征来识别出此类花是变色鸢尾 如果是0就是山鸢尾,以此来达到花瓣的预测
3.自带模型的实现(自带API的实现)
添加链接描述
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.externals import joblib
1. 导入数据
iris = datasets.load_iris()
X = iris.data
y = iris.target
2. 训练数据和测试数据
X_train, X_test, y_train, y_test = train_test_split(X, y)
3. 实例化KNN算法分类器
clf = KNeighborsClassifier(n_neighbors=7)
4. 训练
clf.fit(X_train,y_train)
5. 预测
count = np.count_nonzero((clf.predict(X_test) == y_test) == True)
print('模型预测正确率:%.3f'%(count/len(X_test)))
6.保存模型(把我们测试好的模型保存起来,下次使用就不需要训练了
joblib.dump(clf,“test.pkl”)
7. 读取模型
clf = joblib.load("test.pkl")
count = np.count_nonzero((clf.predict(X_test) == y_test) == True)
print('模型预测正确率:%.3f'%(count/len(X_test)))
4.常用距离计算方法
常用距离计算方法: 欧氏距离(欧几里得距离) 曼哈顿距离 闵可夫斯基距离 切比雪夫距离 余弦距离
|