1. KNN 算法基础
KNN(K-Nearest Neighbors)是一种基于实例的监督学习算法,用于分类和回归。其核心思想是:给定一个样本,找到训练集中与其最接近的 K 个样本,然后根据这 K 个样本的标签(分类问题)或值(回归问题)来预测目标样本的标签或值。
-
优点:简单易懂,无需训练过程。
-
缺点:
-
计算复杂度高,尤其是数据量大时。
-
对数据规模和维度敏感。
-
需要选择合适的 K 值和距离度量方法。
-
2. 数据预处理
KNN 对数据的规模和分布非常敏感,因此数据预处理是关键。
2.1 标准化
KNN 基于距离度量,因此需要对特征进行标准化,避免某些特征因量纲不同而主导距离计算。
from sklearn.preprocessing import StandardScaler
# 标准化特征
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
2.2 处理缺失值
KNN 不能直接处理缺失值,需要对缺失值进行填充或删除。
# 填充缺失值
data.fillna(data.mean(), inplace=True)
2.3 处理类别特征
KNN 不能直接处理类别特征,需要将其转换为数值特征(如独热编码)。
from sklearn.preprocessing import OneHotEncoder
# 独热编码
encoder = OneHotEncoder()
X_encoded = encoder.fit_transform(X_categorical)
3. 模型选择和参数调优
KNN 的核心参数是 n_neighbors
(K 值)和 metric
(距离度量方法)。通过调优这些参数可以显著提升模型性能。
3.1 选择 K 值
-
K 值过小:模型容易过拟合。
-
K 值过大:模型容易欠拟合。
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
# 定义参数网格
param_grid = {'n_neighbors': range(1, 30)}
# 网格搜索
grid_search = GridSearchCV(KNeighborsClassifier(), param_grid, cv=5, scoring='accuracy')
grid_search.fit(X_train_scaled, y_train)
# 输出最优 K 值
print("Best K:", grid_search.best_params_)
3.2 选择距离度量方法
常用的距离度量方法包括:
-
'euclidean'
:欧氏距离(默认)。 -
'manhattan'
:曼哈顿距离。 -
'minkowski'
:闵可夫斯基距离(可调整参数p
)。
# 定义参数网格
param_grid = {'n_neighbors': range(1, 30), 'metric': ['euclidean', 'manhattan', 'minkowski']}
# 网格搜索
grid_search = GridSearchCV(KNeighborsClassifier(), param_grid, cv=5, scoring='accuracy')
grid_search.fit(X_train_scaled, y_train)
# 输出最优参数
print("Best Parameters:", grid_search.best_params_)
4. 特征工程
KNN 对特征工程非常敏感,以下是一些常用的特征工程方法:
4.1 特征选择
使用特征选择方法(如基于统计的方法或模型特征重要性)减少特征数量,降低计算复杂度。
from sklearn.feature_selection import SelectKBest, f_classif
# 选择前 10 个最重要的特征
selector = SelectKBest(f_classif, k=10)
X_train_selected = selector.fit_transform(X_train_scaled, y_train)
X_test_selected = selector.transform(X_test_scaled)
4.2 降维
使用 PCA 或 t-SNE 等方法降低特征维度。
from sklearn.decomposition import PCA
# 使用 PCA 降维
pca = PCA(n_components=10)
X_train_pca = pca.fit_transform(X_train_scaled)
X_test_pca = pca.transform(X_test_scaled)
5. 算法实现
以下是 KNN 算法的完整实现:
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
# 初始化 KNN 模型
knn = KNeighborsClassifier(n_neighbors=5, metric='euclidean')
# 训练模型
knn.fit(X_train_scaled, y_train)
# 预测
y_pred = knn.predict(X_test_scaled)
# 评估模型
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)
6. 性能评估
KNN 的性能评估通常包括以下指标:
-
准确率:分类正确的样本比例。
-
混淆矩阵:查看分类结果的详细分布。
-
ROC 曲线和 AUC:评估分类器的分类能力。
from sklearn.metrics import confusion_matrix, roc_auc_score, roc_curve
# 混淆矩阵
print("Confusion Matrix:")
print(confusion_matrix(y_test, y_pred))
# ROC 曲线和 AUC
y_pred_proba = knn.predict_proba(X_test_scaled)[:, 1]
fpr, tpr, thresholds = roc_curve(y_test, y_pred_proba)
auc = roc_auc_score(y_test, y_pred_proba)
print("AUC:", auc)
7. 实战案例
假设我们有一个电商用户行为数据集,目标是预测用户是否会购买商品。
数据集
-
特征:用户登录天数、浏览商品数量、加入购物车数量、下单数量等。
-
标签:是否购买(0 或 1)。
代码实现
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, confusion_matrix, roc_auc_score
# 加载数据
data = pd.read_csv('ecommerce_behavior.csv')
# 特征和标签
X = data.drop('purchased', axis=1)
y = data['purchased']
# 数据集划分
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 标准化
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 初始化 KNN 模型
knn = KNeighborsClassifier(n_neighbors=5, metric='euclidean')
# 训练模型
knn.fit(X_train_scaled, y_train)
# 预测
y_pred = knn.predict(X_test_scaled)
# 评估模型
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)
print("Confusion Matrix:")
print(confusion_matrix(y_test, y_pred))
调优前结果
-
准确率:0.85
-
AUC:0.88
8. 优化策略
通过以下策略优化 KNN 模型:
8.1 调优 K 值和距离度量
from sklearn.model_selection import GridSearchCV
# 定义参数网格
param_grid = {'n_neighbors': range(1, 30), 'metric': ['euclidean', 'manhattan', 'minkowski']}
# 网格搜索
grid_search = GridSearchCV(KNeighborsClassifier(), param_grid, cv=5, scoring='accuracy')
grid_search.fit(X_train_scaled, y_train)
# 输出最优参数
print("Best Parameters:", grid_search.best_params_)
# 使用最优参数训练模型
best_knn = grid_search.best_estimator_
y_pred_optimized = best_knn.predict(X_test_scaled)
accuracy_optimized = accuracy_score(y_test, y_pred_optimized)
print("Optimized Accuracy:", accuracy_optimized)
8.2 特征选择
from sklearn.feature_selection import SelectKBest, f_classif
# 选择前 5 个最重要的特征
selector = SelectKBest(f_classif, k=5)
X_train_selected = selector.fit_transform(X_train_scaled, y_train)
X_test_selected = selector.transform(X_test_scaled)
# 使用最优参数训练模型
best_knn.fit(X_train_selected, y_train)
y_pred_selected = best_knn.predict(X_test_selected)
accuracy_selected = accuracy_score(y_test, y_pred_selected)
print("Accuracy with Feature Selection:", accuracy_selected)
调优后结果
-
准确率:0.91
-
AUC:0.93
9. 最佳实践和技巧
-
数据标准化:KNN 对特征尺度敏感,必须标准化。
-
降维:高维数据会导致计算复杂度高,建议降维。
-
调优 K 值:通过交叉验证选择最优 K 值。
-
并行计算:使用
n_jobs
参数加速计算。 -
缓存距离矩阵:对于大数据集,可以缓存距离矩阵以减少计算时间。
通过以上优化策略,KNN 模型的性能有所提升,另外个人认为一定一定要多理解业务场景,能更准确高效的优化算法。