*Python*机器学习算法——k-近邻算法(K-Nearest Neighbors,KNN)

目录

⭐️引言

⭐️理论

1、算法原理:

2、距离度量:

3、选择k值:

4、处理不平衡数据集:

5、归一化:

6、决策规则:

⭐️结语



⭐️引言

        K-近邻算法(K-Nearest Neighbors, KNN)是一种基本的模式识别与机器学习分类算法。它的核心思想是根据输入实例在特征空间中的最近(相似度最高)的训练实例来决定其类别。

⭐️理论

        实现K-近邻算法(KNN)主要依赖于scikit-learn(简称sklearn)这个库。scikit-learn是一个免费软件机器学习库,它包含了一系列用于数据挖掘和数据分析的简单高效的工具。sklearn中的neighbors模块提供了KNN分类器和回归器的实现。


1、算法原理:

        对于给定的数据点,KNN会找到训练集中距离该点最近的k个数据点。

        根据这k个最近邻的多数类别来预测新的数据点的类别。

        距离通常采用欧几里得距离或其他距离度量方法计算。

2、距离度量:

        欧几里得距离是最常用的度量方式,对于两个点 ( x = (x_1, x_2, \ldots, x_n)) 和 (y = (y_1, y_2, \ldots, y_n)),其距离可以表示为: [ d(x, y) = \sqrt{\sum_{i=1}^{n}(x_i - y_i)^2}]

import numpy as np

def euclidean_distance(x, y):
    return np.sqrt(np.sum((x - y) ** 2))

        曼哈顿距离(Manhattan Distance)是一种常用的距离度量方法,适用于连续数值型特征。曼哈顿距离定义为两个点在各个维度上的绝对差值之和。对于两个点 ( x = (x_1, x_2, \ldots, x_n) ) 和 (y = (y_1, y_2, \ldots, y_n)),曼哈顿距离可以表示为:[ d(x, y) = \sum_{i=1}^{n} |x_i - y_i|]

import numpy as np

def manhattan_distance(x, y):
    return np.sum(np.abs(x - y))

        切比雪夫距离(Chebyshev Distance)是一种常用的距离度量方法,适用于连续数值型特征。切比雪夫距离定义为两个点在各个维度上的最大绝对差值。对于两个点(x = (x_1, x_2, \ldots, x_n) 和  y = (y_1, y_2, \ldots, y_n) ,切比雪夫距离可以表示为:

                                         d(x, y) = \max_{i=1}^{n} |x_i - y_i| 

        ( x_i ) 和 ( y_i) 分别是两个点在第 ( i ) 维度上的坐标。

        ( |x_i - y_i| ) 表示两个点在第 ( i ) 维度上的绝对差值。

        最终的距离是所有维度上绝对差值的最大值

import numpy as np

def chebyshev_distance(x, y):
    return np.max(np.abs(x - y))

        余弦相似度适用于高维空间中的向量比较,通常用于文本数据。它衡量的是两个向量之间的夹角余弦值,值范围在 ([-1, 1]) 之间。余弦相似度越接近 1,表示两个向量越相似;越接近 -1,表示两个向量越不相似;0 表示两个向量正交。
        对于两个向量 ( x = (x_1, x_2, \ldots, x_n) ) 和 ( y = (y_1, y_2, \ldots, y_n) ),余弦相似度可以表示为:
                                        text{cosine_similarity}(x, y) = \frac{x \cdot y}{|x| |y|} 
其中:

( x \cdot y ) 是向量 ( x ) 和 ( y ) 的点积(内积)。

( |x| ) 和 ( |y| ) 分别是向量 ( x ) 和 ( y ) 的范数(长度)。

import numpy as np

def cosine_similarity(x, y):
    dot_product = np.dot(x, y)
    norm_x = np.linalg.norm(x)
    norm_y = np.linalg.norm(y)
    return dot_product / (norm_x * norm_y)

        Jaccard 相似度适用于二元特征数据,如集合之间的相似度。它衡量的是两个集合的交集大小相对于它们并集大小的比例。

       对于两个集合 ( A ) 和 ( B ),Jaccard 相似度可以表示为:
                                         text{jaccard_similarity}(A, B) = \frac{|A \cap B|}{|A \cup B|} 

其中:

( |A \cap B|) 是集合 ( A ) 和 ( B ) 的交集大小。

( |A \cup B| ) 是集合 ( A ) 和 ( B ) 的并集大小。

import numpy as np

def cosine_similarity(x, y):
    dot_product = np.dot(x, y)
    norm_x = np.linalg.norm(x)
    norm_y = np.linalg.norm(y)
    return dot_product / (norm_x * norm_y)

3、选择k值:

        k值的选择对模型的影响很大,较小的k值会导致模型过拟合,较大的k值则可能导致欠拟合。通常通过交叉验证来选择最佳的k值。

import numpy as np
from sklearn.model_selection import cross_val_score
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

# 加载数据集
data = load_iris()
X = data.data
y = data.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 定义 k 值的范围
k_values = range(1, 31)

# 存储每个 k 值对应的交叉验证得分
cv_scores = []

# 对每个 k 值进行交叉验证
for k in k_values:
    knn = KNeighborsClassifier(n_neighbors=k)
    scores = cross_val_score(knn, X_train, y_train, cv=5, scoring='accuracy')
    cv_scores.append(scores.mean())

# 找到最佳 k 值
best_k = k_values[np.argmax(cv_scores)]

# 输出结果
print(f"最佳 k 值: {best_k}")
print(f"最佳 k 值对应的交叉验证准确率: {max(cv_scores)}")

4、处理不平衡数据集:

        当类别分布不均匀时,可以通过加权投票来调整不同类别的影响,例如,根据类别出现的频率来加权。

import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import classification_report
from sklearn.datasets import make_classification

# 生成不平衡数据集
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, weights=[0.9, 0.1], random_state=42)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 计算类别权重
class_weights = {}
unique, counts = np.unique(y_train, return_counts=True)
total_samples = len(y_train)
for label, count in zip(unique, counts):
    class_weights[label] = total_samples / (len(unique) * count)

# 创建加权 KNN 模型
knn_weighted = KNeighborsClassifier(n_neighbors=5, weights=lambda x: [class_weights[label] for label in y_train[x]])

# 训练模型
knn_weighted.fit(X_train, y_train)

# 预测测试集
y_pred = knn_weighted.predict(X_test)

# 输出分类报告
print(classification_report(y_test, y_pred))

5、归一化:

        在计算距离之前,通常需要对特征进行归一化处理,以消除不同尺度特征的影响。

        Min-Max 归一化

         Min-Max 归一化将每个特征的值缩放到 [0, 1] 之间。

# 使用 Min-Max 归一化
min_max_scaler = MinMaxScaler()
X_train_minmax = min_max_scaler.fit_transform(X_train)
X_test_minmax = min_max_scaler.transform(X_test)

# 创建 KNN 模型
knn_minmax = KNeighborsClassifier(n_neighbors=5)
knn_minmax.fit(X_train_minmax, y_train)

# 预测测试集
y_pred_minmax = knn_minmax.predict(X_test_minmax)

# 输出分类报告
print("Min-Max 归一化分类报告:")
print(classification_report(y_test, y_pred_minmax))

         Z-Score 标准化

         Z-Score 标准化将每个特征的值标准化为均值为 0、标准差为 1 的分布。

# 使用 Z-Score 标准化
standard_scaler = StandardScaler()
X_train_standard = standard_scaler.fit_transform(X_train)
X_test_standard = standard_scaler.transform(X_test)

# 创建 KNN 模型
knn_standard = KNeighborsClassifier(n_neighbors=5)
knn_standard.fit(X_train_standard, y_train)

# 预测测试集
y_pred_standard = knn_standard.predict(X_test_standard)

# 输出分类报告
print("Z-Score 标准化分类报告:")
print(classification_report(y_test, y_pred_standard))

6、决策规则:

        多数表决:预测类别为k个最近邻中出现次数最多的类别。

# 创建 KNN 模型,使用多数表决
knn_majority = KNeighborsClassifier(n_neighbors=5)

# 训练模型
knn_majority.fit(X_train, y_train)

# 预测测试集
y_pred_majority = knn_majority.predict(X_test)

# 输出分类报告
print("多数表决分类报告:")
print(classification_report(y_test, y_pred_majority))

        加权多数表决:每个邻居的投票权重与它到目标样本的距离成反比。

# 创建 KNN 模型,使用加权多数表决
knn_weighted = KNeighborsClassifier(n_neighbors=5, weights='distance')

# 训练模型
knn_weighted.fit(X_train, y_train)

# 预测测试集
y_pred_weighted = knn_weighted.predict(X_test)

# 输出分类报告
print("加权多数表决分类报告:")
print(classification_report(y_test, y_pred_weighted))

⭐️结语

        K-近邻算法(K-Nearest Neighbors, KNN)是一种基于实例的学习方法,广泛应用于分类和回归任务。其基本原理是通过计算待预测样本与训练集中所有样本的距离,选取距离最近的 k 个邻居,并根据这些邻居的信息进行预测。对于分类任务,预测类别为 k 个最近邻中出现次数最多的类别;对于回归任务,预测值为 k 个最近邻的目标值的平均值。常用的距离度量方法包括欧氏距离、曼哈顿距离和闵可夫斯基距离,其中欧氏距离最为常用。为了消除不同特征尺度的影响,通常需要对特征进行归一化处理,如 Min-Max 归一化和 Z-Score 标准化。k 值的选择对模型影响很大,较小的 k 值可能导致过拟合,较大的 k 值可能导致欠拟合,通常通过交叉验证来选择最佳的 k 值。KNN 算法支持多种决策规则,包括多数表决和加权多数表决。该算法的优点在于简单易懂、适用于多分类问题且能处理非线性问题;缺点在于计算复杂度较高,特别是对于大数据集,且对噪声和异常值敏感。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值