鸢尾花分类任务
- 1. 鸢尾花分类步骤
- 1.1 分析问题,搞定输入和输出
- 1.2 每个类别各采集50朵花
- 1.3 选择一种算法,完成输入到输出的映射
- 1.4 第四步:部署,集成
- 2. KNN算法原理
- 2.1 基本概念
- 2.2 核心理念
- 2.3 训练
- 2.4 推理流程
- 3. 使用 sklearn 完成分类任务
- 3.1 代码实现
- 3.2 输出结果
- 4. 距离度量
- 计算内积
- 计算模
- 计算余弦相似度
1. 鸢尾花分类步骤
1.1 分析问题,搞定输入和输出
- 输入:花;
- 输出:类别
- 如何数字化一个实体(entity)?
- 用这个实体的特征/属性来刻画这个实体!!!
- 四个属性:花瓣长,花瓣宽,花萼长,花萼宽
- 输出:从零开始编号:0, 1, 2 …(zero index),鸢尾花一共3类
- 一个样本:花瓣长,花瓣宽,花萼长,花萼宽,类别编号
1.2 每个类别各采集50朵花
- 花瓣长1,花瓣宽1,花萼长1,花萼宽1,类别编号1
- 花瓣长2,花瓣宽2,花萼长2,花萼宽2,类别编号2
- 花瓣长3,花瓣宽3,花萼长3,花萼宽3,类别编号3
… - 花瓣长150,花瓣宽150,花萼长150,花萼宽150,类别编号150
1.3 选择一种算法,完成输入到输出的映射
- 分类算法
- KNN:K紧邻算法
- GNB:高斯贝叶斯
- DT:决策树算法
- SVM:支持向量机
- RF:随机森林算法
- 集成学习算法
1.4 第四步:部署,集成
2. KNN算法原理
2.1 基本概念
- KNN: K-Nearest Neighbors K个最近的邻居,所以也叫 K-近邻 算法
2.2 核心理念
- 近朱者赤,近墨者黑
- 跟什么样的人在一起,你就会变成什么样的人!!!
2.3 训练
- 惰性计算算法
- 规则 + 数据,不是严格意义上的人工智能算法
2.4 推理流程
- 给定一朵花,如何判定它是第几类?
- 第一步:找出这朵花 K 个最近的邻居(最好的兄弟,闺蜜)
- 相似度的度量
几何视角: 1. 欧式空间,距离计算,2. 勾股定理- 向量视角:1. 余弦相似度
- 相似度的度量
- 第二步:K个邻居进行投票,选出类别出现次数最多的类
3. 使用 sklearn 完成分类任务
3.1 代码实现
- knn_demo
from sklearn.datasets import load_iris
# 加载数据
X,y = load_iris(return_X_y=True)
print(X.shape,y.shape)
# 数据集切分
from sklearn.model_selection import train_test_split
# 参数:shuffle=True:打乱数据集,random_state=0 指定随机种子,方便复现结果
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,shuffle=True,random_state=0)
# 引入一个模型
from sklearn.neighbors import KNeighborsClassifier
# 1.构建模型
knn=KNeighborsClassifier(n_neighbors=3)
# 2.训练模型
knn.fit(X_train,y_train)
# 3.预测
y_pred=knn.predict(X_test)
print(y_pred)
print(y_test)
print(y_pred==y_test)
# 4.评估模型
acc = (y_pred==y_test).mean()
print(acc)
# 决策树
from sklearn.tree import DecisionTreeClassifier
# 构建模型
dtc = DecisionTreeClassifier()
# 训练模型
dtc.fit(X_train,y_train)
# 预测
y_pred = dtc.predict(X_test)
# 评估模型
acc = (y_pred==y_test).mean()
print(acc)
# 支持向量机
from sklearn.svm import SVC
svc = SVC()
svc.fit(X_train,y_train)
y_pred = svc.predict(X_test)
acc = (y_pred==y_test).mean()
print(acc)
# 以下是自己手动写一个KNN的过程
import joblib
joblib.dump(value=knn, filename="knn.aura")
class MyKNeighborsClassifier(object):
"""
自定义KNN分类器算法
"""
def __init__(self, n_neighbors=5):
"""
初始化方法:
- 输入:
- 超参 Hyper-Parameter(人为置顶的,不是系统学习的)
- 输出:
- 没有输出
"""
# 超参设置
self.n_neighbors = n_neighbors
def fit(self, X, y):
"""
训练过程
- 输入:
- X:训练集的特征(矩阵)
- y:训练集的标签(向量)
- 输出:
- 无输出
"""
import numpy as np
# 类型转换
X = np.array(X)
y = np.array(y)
# 形状校验
if X.ndim != 2 or y.ndim != 1 or X.shape[0] != y.shape[0]:
raise ValueError("入参有误")
# 把训练集挂载到模型上
self.X = X
self.y = y
def predict(self, X):
"""
预测过程:
- 输入:
- X:待预测的样本的特征(批量)
- 输出:
- y:预测的类别
"""
import numpy as np
from collections import Counter
# 类型转换
X = np.array(X)
# 形状校验
if X.ndim != 2 or X.shape[1] != self.X.shape[1]:
raise ValueError("入参有误")
# 推理过程
results = []
for x in X:
distances = np.sqrt(((self.X - x) ** 2).sum(axis=-1))
idxes = np.argsort(distances)[:self.n_neighbors]
labels = self.y[idxes]
label = Counter(labels).most_common(1)[0][0]
results.append(label)
return np.array(results)
# 1, 构建模型
my_knn = MyKNeighborsClassifier()
# 2,训练
my_knn.fit(X=X_train, y=y_train)
# 3, 预测
y_pred = my_knn.predict(X=X_test)
print(y_pred)
print(y_test)
acc = (y_pred == y_test).mean()
print(acc)
- 模型部署
import joblib
knn = joblib.load(filename="knn.aura")
# 预测 数据都是批量预测的,所以要写成二维结构,就算是一个数据,也要假装是多个
import numpy as np
X = np.array([[6.3,3.3,6.,2.5]])
print(X.shape)
result = knn.predict(X=X)
print(result)
3.2 输出结果
4. 距离度量
计算内积
计算模
计算余弦相似度
import numpy as np
a = np.array([2, 5])
b = np.array([1, 8])
d = np.sqrt(((a - b) ** 2).sum())
d
3.1622776601683795
# 手动计算 a 和 b 的内积
(a * b).sum()
42
# 计算内积更优雅的方式
a @ b
42
# 这样也能计算内积
np.dot(a, b)
42
# 同样是计算内积
a.dot(b)
42
# 手动计算 a 的模
np.sqrt((a ** 2).sum())
5.385164807134504
# 计算 a 的模更优雅的方式,使用 numpy 效率更高
np.linalg.norm(a)
5.385164807134504
# 余弦相似度
cosine_similarity = a @ b / np.linalg.norm(a) / np.linalg.norm(b)
cosine_similarity
0.9673722233802454