31  客户购买意愿分析(K近邻算法)

31.1 引言K近邻算法(KNN)

KNN算法:监督学习的分类算法 - 原理: “物以类聚,人以群分” - 决策: 根据K个最近邻居的类别投票 - 金融应用: 客户分类、信用评分

31.2 算法原理

决策规则: 对于样本x,找到其K个最近邻居,这K个邻居中最多数样本所属的类别即为x的预测类别。

距离度量: 常用欧氏距离

\[ d(x,y) = \sqrt{\sum_{i=1}^{n}(x_i - y_i)^2} \]

31.3 社交网络广告案例

列表 31.1
# 注:04_Social_Network_Ads.csv数据文件本地没有,但平台已经内置
# ⚠️ 平台原始代码 - 请原样输入至教学平台(注释除外),平台才会判定答案正确
# 导入相关模块
import pandas as pd
import numpy as np  # 导入NumPy数值计算库
from sklearn.model_selection import train_test_split  # 导入Scikit-learn的train_test_split模块
from sklearn.preprocessing import StandardScaler  # 导入Scikit-learn的StandardScaler模块
from sklearn.neighbors import KNeighborsClassifier  # 导入Scikit-learn的KNeighborsClassifier模块
from sklearn.model_selection import GridSearchCV  # 导入Scikit-learn的GridSearchCV模块
from sklearn.metrics import confusion_matrix  # 导入Scikit-learn的confusion_matrix模块
 
# 导入数据集
data = pd.read_csv("04_Social_Network_Ads.csv")
 
# 数据集划分
x = data[["Age","EstimatedSalary"]]
y = data["Purchased"]  # 提取Purchased列作为y变量
# 划分训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.30, random_state=0)
 
# 数据标准化
transfer1 = StandardScaler()
x_train = transfer1.fit_transform(x_train)  # 对数据进行变换
x_test = transfer1.transform(x_test)  # 对数据进行变换
 
# 训练模型
estimator = KNeighborsClassifier(algorithm='kd_tree')
 
# 模型选择与调优——网格搜索和交叉验证
# 准备要调的超参数
param_dict = {"n_neighbors": [1, 3, 5, 7, 9, 11, 13]}
estimator = GridSearchCV(estimator, param_grid=param_dict, cv=4)  # 创建网格搜索交叉验证对象,自动寻找最优超参数
estimator.fit(x_train,y_train)  # 在数据上训练estimator模型
 
# 模型评估
y_pre = estimator.predict(x_test)
print("预测结果:\n", y_pre)  # 输出预测结果:\n
print("准确率为:\n", estimator.score(x_test, y_test))  # 输出准确率为:\n
# print("对比真实值和预测值:\n", y_test==y_pre)
print("在交叉验证中最好的结果为:\n", estimator.best_score_)
print("使用网格搜索的最好的模型:\n", estimator.best_estimator_)  # 输出使用网格搜索的最好的模型:\n

31.4 模型训练与调优

31.5 模型评估

列表 31.3
# 注:该代码块依赖的数据来自上方平台任务代码块,因其未执行,本块也无法执行

# ==================== 预测测试集 ====================
# 使用最优模型对测试集进行预测
y_pred = grid_search.predict(X_test_scaled)  # 输出预测类别(0或1)

# ==================== 计算准确率 ====================
accuracy = accuracy_score(y_test, y_pred)  # 计算预测准确率
print(f'测试集准确率: {accuracy:.4f}')  # 打印准确率,范围[0,1]

# ==================== 生成混淆矩阵 ====================
# 混淆矩阵展示了预测结果与真实情况的对比
cm = confusion_matrix(y_test, y_pred)  # 生成2x2混淆矩阵
print(f'\n混淆矩阵:')
print(cm)
# 混淆矩阵格式:
#           预测0  预测1
# 实际0    [TN    [FP
# 实际1    [FN    [TP

# ==================== 可视化混淆矩阵 ====================
import matplotlib.pyplot as plt  # 导入绘图库
import seaborn as sns  # 导入统计绘图库

plt.figure(figsize=(8, 6))  # 创建8x6英寸的画布
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')  # 绘制热力图,annot显示数值,fmt整数格式
plt.title('混淆矩阵', fontsize=14)  # 设置标题
plt.xlabel('预测类别', fontsize=12)  # x轴标签
plt.ylabel('真实类别', fontsize=12)  # y轴标签
plt.tight_layout()  # 自动调整布局,避免标签重叠
plt.show()  # 显示图形

# ==================== 输出最优模型 ====================
print(f'\n最佳模型: {grid_search.best_estimator_}')  # 打印最优模型的完整配置

31.6 分析结论

  1. 标准化必要: 年龄和薪资尺度差异大
  2. K值选择: 通过交叉验证确定
  3. 模型性能: 达到较高准确率
  4. 商业应用: 预测用户是否购买