总结:机器学习代码套路
- 准备数据
- (DataFrame可以直接参与训练,但是一般要求都是二维的;一般可以尝试用numpy的ndarray进行训练,df转换成ndarray的方法:
df.values
即可)如果是df,第一个维度一般是样本数量,第二个维度一般是特征数量。对于有监督学习的标签y_train
,一般是一维的,也可以是字符串,但是不能是Series- 创建机器学习算法实例
- 训练
- 预测
- 评估
推荐看视频了解KNN算法的原理:https://www.youtube.com/watch?v=gs9E7E0qOIc
K 近邻算法(K-Nearest Neighbors, KNN) 是一种简单的非参数、惰性学习算法。它不需要显式的训练过程,而是将所有训练数据存储起来,在需要预测时才进行计算。
KNN核心原理:该算法认为在特征空间中,彼此相近(即距离较小)的样本具有相似的标签。一个新样本的类别由它最接近的 K
个邻居的类别决定。
KNN 的三个基本要素:
- 距离度量(Distance Metric):如何计算样本之间的相似度。
- k 值的选择(Choice of k):选择多少个邻居参与决策。
- 分类决策规则(Decision Rule):如何根据
K
个邻居的标签来决定新样本的标签。
1.距离度量
1.1 欧氏距离(Euclidean Distance)
最常用的距离,表示多维空间中的直线距离。
\[d(x,y)=\sqrt {∑_{i=1}^{n}(x_i−y_i)2}\]适用于连续、数值型特征。
1.2 曼哈顿距离(Manhattan Distance)
表示在网格中从一个点到另一个点的距离,只能沿坐标轴方向移动。
\[d(x,y)=∑_{i=1}^n∣x_i−y_i∣\]1.3 闵可夫斯基距离(Minkowski Distance)
是欧氏距离和曼哈顿距离的推广。
\[d(x,y)=(∑_{i=1}^n∣x_i−y_i∣^p)^{1/p}\]当 p=1 时是曼哈顿距离,当 p=2 时是欧氏距离。
1.4 余弦相似度(Cosine Similarity)
衡量两个向量方向上的差异,而非大小。
\[similarity=cos(θ)=\frac{A·B}{∥A∥_2∥B∥_2}\]适用于文本分析等场景,此时向量的长度(范数)不重要,方向更重要。
1.5 汉明距离(Hamming Distance)
计算两个等长字符串中对应位置不同字符的数量。 适用于离散、类别型特征。
2.实战案例1-分类任务
使用 Python 的 scikit-learn 库来实现 KNN 算法,因为它高效且易于使用。
按照sklearn库:
1
!pip install scikit-learn
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 生成一个模拟的分类数据集
# n_features:每个样本的特征数量是2个
# n_informative=2 对分类任务有信息的特征数量
# n_redundant 冗余特征的数量
# random_state随机种子为 42,保证结果的可复现
X, y = make_classification(n_samples=500, n_features=2, n_informative=2, n_redundant=0, random_state=42)
# X 将是一个形状为 (100, 2) 的矩阵,y:形状为 (100,) 的数组,且y只有0, 1两个元素
# display(X, y)
# 把数据划分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# display(X_train.shape)# (70, 2)
# 1.初始化KNN分类器
# n_neighbors=5 k值,邻居数量
# weights="uniform" 投票权重,uniform表示等权重,distance根据距离加权
# metric="euclidean" 距离的度量 :欧式距离/曼哈顿距离
knn_classifier = KNeighborsClassifier(n_neighbors=5, weights="uniform", metric="euclidean")
# 2.训练模型
knn_classifier.fit(X_train, y_train)
# 3.进行预测
y_pred_class = knn_classifier.predict(X_test)
# 4.评估模型 如果n_samples变大,显然会导致准确率下降
acc = accuracy_score(y_test, y_pred_class)
print(f"准确率:{acc:.5f}")
# 可视化分类结果
h = 0.02
# 对特征的最小值减 1(X[:, 0].min() - 1),对最大值加 1(X[:, 0].max() + 1),是为了在可视化时扩展网格范围
x_min,x_max = X[:,0].min() - 1, X[:,0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
Z = knn_classifier.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.figure(figsize=(10, 8))
plt.contourf(xx, yy, Z, alpha=0.3, cmap=plt.cm.coolwarm)
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_test, cmap=plt.cm.coolwarm, edgecolor='k', s=80)
plt.title("KNN分类器决策边界可视化")
plt.xlabel("特征1")
plt.ylabel("特征2")
plt.show()
3.实战案例2-分类任务
准备了下面的数据:
可视化为散点图:
1
2
3
4
data.plot(kind="scatter", x = "武打镜头", y = "接吻镜头", cmap="rainbow", c = [1, 1, 0, 1, 0, 0])
for i, row in data.iterrows():
# print(i, row)
plt.text(row["武打镜头"], row["接吻镜头"], row["电影名称"])
【1】准备数据:
1
2
3
4
5
6
7
8
# 训练数据与测试数据准备
X_train = data[["武打镜头", "接吻镜头"]].values # 要求一定是二维的
y_train = data["分类情况"].values # 要求不能是Series
# 测试数据:
data_test = pd.read_csv("./filtered_movie_data.csv", delimiter=",")
X_test = data_test[["武打镜头", "接吻镜头"]].values
y_test = data_test["分类情况"].values
【2】创建KNN算法的实例
1
knn = KNeighborsClassifier() # 默认是k=5
如果需要调整其他参数,参考下面的表格
KNeighborsClassifier参数
参数 | 描述 | 默认值 |
---|---|---|
n_neighbors |
k 值,即用于分类的邻居数量。该值通常是一个正整数。 |
5 |
weights |
权重函数,用于预测。 | 'uniform' |
'uniform' :所有邻居的权重相同。 |
||
'distance' :根据距离的倒数分配权重,即距离越近的邻居影响越大。 |
||
[callable] :用户自定义的权重函数。 |
||
algorithm |
用于计算最近邻的算法。在数据量不大时,'auto' 是一个不错的选择。 |
'auto' |
'auto' :根据输入数据自动选择最合适的算法。 |
||
'ball_tree' :使用 BallTree 算法。 |
||
'kd_tree' :使用 KDTree 算法。 |
||
'brute' :使用蛮力搜索。 |
||
leaf_size |
传递给 BallTree 或 KDTree 的叶子大小。这个参数会影响树的构建速度和查询速度,以及存储树所需的内存。 |
30 |
p |
Minkowski 距离的幂参数。p=1 等同于曼哈顿距离 (l1 ),p=2 等同于欧氏距离 (l2 )。 |
2 |
metric |
用于树的距离度量。默认值为 'minkowski' ,当 p=2 时,它等同于标准的欧氏距离。 |
'minkowski' |
n_jobs |
用于邻居搜索的并行工作数。-1 表示使用所有处理器。在 fit 方法中不使用。 |
None |
【3】训练:
1
knn.fit(X_train, y_train)
【4】预测:
1
knn.predict(X_test)
【5】评估
1
accuracy_score(y_test, knn.predict(X_test))
4.建立对机器学习的正确认识
机器学习预测错误是很正常的!!!原始的训练数据本身就会影响预测结果。所以训练数据应该尽量多样化。