1、K-近邻算法:
如果一个样本在特征空间中的K个最相似的样本中的大多数属于某一个类别,则该样本也属于这个类别
2、KNN算法流程:
1、计算已知类别中的点与当前点的距离
2、按距离递增次序排序
3、选取与当前点距离最小的K个点
4、统计前K个点所在类别出现的频率
5、返回前K个点出现频率最高的类别作为当前点的预测分类
3、机器学习流程:
1、获取数据
2、数据基本处理
3、特征工程
4、机器学习
5、模型评估
4、 代码实现过程:
'''
-*- coding: utf-8 -*-
@Author : Dongze Xu
@Time : 2021/12/15 15:47
@Function:
'''
import pandas as pd
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
'''
# 1.获取数据集
# 2.基本数据处理
# 2.1 缩小数据范围
# 2.2 选择时间特征
# 2.3 去掉签到较少的地方
# 2.4 确定特征值和目标值
# 2.5 分割数据集
# 3.特征工程 -- 特征预处理(标准化)
# 4.机器学习 -- knn+cv
# 5.模型评估
'''
# 1.获取数据集
data = pd.read_csv("./data/FBlocation/train.csv")
# 2.基本数据处理
# 2.1 缩小数据范围
#选取x∈(2, 2.5); y∈(2, 2.5)
partial_data = data.query("x>2.0 & x<2.5 & y>2.0 & y<2.5")
# 2.2 选择时间特征
#转化为时间格式(年月日形式)
time = pd.to_datetime(partial_data["time"], unit="s")
time = pd.DatetimeIndex(time)
# 2.4 确定特征值和目标值
x = partial_data[["x", "y", "accuracy", "hour", "day", "weekday"]]
y = partial_data["place_id"]
# 2.5 分割数据集
#random_state:随机数种子,test_size:划分
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=2, test_size=0.25)
# 3.特征工程 -- 特征预处理(标准化)
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.机器学习 -- knn+cv
# 4.1 实例化一个训练器
estimator = KNeighborsClassifier()
# 4.2 交叉验证,网格搜索实现
param_grid = {"n_neighbors": [3, 5, 7, 9]}
estimator = GridSearchCV(estimator=estimator, param_grid=param_grid, cv=10, n_jobs=4)
# 4.3 模型训练
estimator.fit(x_train, y_train)
# 5.模型评估
# 5.1 准确率输出
score_ret = estimator.score(x_test, y_test)
# 5.2 预测结果
y_pre = estimator.predict(x_test)
# 5.3 其他结果输出
print("最好的模型是:\n", estimator.best_estimator_)
print("最好的结果是:\n", estimator.best_score_)
print("所有的结果是:\n", estimator.cv_results_)
在结合Pandas与Scikit-learn实现KNN算法时,核心流程分为数据加载与处理、模型构建与训练、预测与评估三部分。以下是具体实现步骤及代码示例:
1. 数据加载与预处理(Pandas核心作用)
1.1 数据加载
使用Pandas读取数据文件(如CSV、Excel),或直接加载Scikit-learn内置数据集:
import pandas as pd
from sklearn.datasets import load_iris
# 加载鸢尾花数据集
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['target'] = iris.target # 添加目标列
1.2 数据清洗
处理缺失值、异常值(KNN对数据质量敏感):
# 填充缺失值(例如用均值)
df.fillna(df.mean(), inplace=True)
# 删除重复数据
df.drop_duplicates(inplace=True)
1.3 特征与标签分离
X = df.drop('target', axis=1) # 特征矩阵
y = df['target'] # 目标变量
1.4 数据标准化(关键步骤)
KNN依赖距离计算,需对特征归一化:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
2. 模型构建与训练(Scikit-learn核心作用)
2.1 划分训练集与测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X_scaled, y, test_size=0.3, random_state=42
)
2.2 初始化KNN模型
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(
n_neighbors=5, # 默认K值
weights='uniform', # 或'distance'(加权投票)
algorithm='auto' # 自动选择最优搜索算法(KD树或暴力搜索)
)
2.3 训练模型
knn.fit(X_train, y_train)
3. 预测与评估
3.1 预测新样本
y_pred = knn.predict(X_test)
3.2 评估性能
from sklearn.metrics import classification_report, accuracy_score
print("准确率:", accuracy_score(y_test, y_pred))
print(classification_report(y_test, y_pred))
3.3 超参数调优(GridSearchCV)
通过交叉验证选择最优K值:
from sklearn.model_selection import GridSearchCV
param_grid = {'n_neighbors': range(3, 15)}
grid = GridSearchCV(knn, param_grid, cv=5)
grid.fit(X_train, y_train)
print("最优K值:", grid.best_params_['n_neighbors'])
4. 实战案例:红酒数据集分类
from sklearn.datasets import load_wine
import pandas as pd
# 加载数据并转为DataFrame
wine = load_wine()
df = pd.DataFrame(wine.data, columns=wine.feature_names)
df['target'] = wine.target
# 预处理与建模流程同上(略)
常见问题与优化方案
问题类型 | 解决方案 |
---|---|
计算速度慢 | 设置 algorithm='kd_tree' 或使用PCA降维 |
类别不平衡 | 使用 class_weight='balanced' 或调整采样策略(如SMOTE) |
高维数据效果差 | 通过特征选择(如SelectKBest)或嵌入L1正则化模型筛选重要特征 |
距离度量敏感 | 尝试不同距离公式(如曼哈顿距离 metric='manhattan' ) |
关键接口说明
Scikit-learn方法 | 功能描述 |
---|---|
knn.fit(X, y) | 训练模型,输入特征矩阵和目标变量 |
knn.predict(X) | 预测新样本类别 |
knn.predict_proba(X) | 返回样本属于各类别的概率(适用于概率投票场景) |
knn.kneighbors(X) | 返回每个样本的K个最近邻的距离和索引(可用于自定义分类逻辑) |
扩展应用
-
缺失值填补:结合
KNNImputer
处理数据缺失:from sklearn.impute import KNNImputer imputer = KNNImputer(n_neighbors=3) df_imputed = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)
-
文本分类:将文本特征向量化(如TF-IDF)后输入KNN模型:
from sklearn.feature_extraction.text import TfidfVectorizer tfidf = TfidfVectorizer() X_text = tfidf.fit_transform(df['text_column'])
通过Pandas与Scikit-learn的结合,可高效完成从数据清洗到模型部署的全流程。实际应用中需注意数据分布和计算效率的平衡,例如对大规模数据集优先使用近似最近邻算法(如Annoy或Faiss库)。