概念
给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的 k 个实例,这 k 个实例的多数属于某个类,就把该输入实例分为这个类。
优点:
算法简单
训练简单
适用于任意数量的分类
容易添加更多数据
精度高
对异常值不敏感
无数据输入假定
参数少:
缺点:
高预测成本(大的数据集更糟)
高维数据不太好
计算复杂度高
空间复杂度高
原理
1 2 3 4 5 6 1. 假设有一个带有标签的样本数据集(训练样本集),其中包含每条数据与所属分类的对应关系; 2. 输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较。 - 计算新数据与样本数据集中每条数据的距离。 - 对求得的所有距离进行排序(从小到大,越小表示越相似)。 3. 取前 k (k 一般小于等于 20 )个样本数据对应的分类标签。 4. 求 k 个数据中出现次数最多的分类标签作为新数据的分类。
归一化
归一化就是要把你需要处理的数据经过处理后(通过某种算法)限制在你需要的一定范围内。首先归一化是为了后面数据处理的方便,其次是保正程序运行时收敛加快。
方法
线性函数转换,表达式如下:
$$y=\frac{x-MinValue}{MaxValue-MinValue}$$
说明:x、y分别为转换前、后的值,MaxValue、MinValue分别为样本的最大值和最小值。
对数函数转换,表达式如下:
$$\frac{\partial u}{\partial t} = h^2 \left( \frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} + \frac{\partial^2 u}{\partial z^2}\right)$$
评估指标
ScikitLearn 中的kNN
1 2 3 4 5 6 from sklearn.preprocessing import StandardScaler scaler = StandardScaler() scaler.fit(df.drop('TARGET CLASS', axis=1)) scaled_features = scaler.transform(df.drop('TARGET CLASS', axis=1)) df_feat = pd.DataFrame(scaled_features, columns=df.columns[:-1])
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import classification_report, confusion_matrix X = df_feat y = df['TARGET CLASS'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=101) from sklearn.neighbors import KNeighborsClassifier knn = KNeighborsClassifier(n_neighbors=1) knn.fit(X_train, y_train) pred = knn.predict(X_test) print(confusion_matrix(y_test, pred)) print(classification_report(y_test, pred))
1 2 3 4 5 6 7 8 9 10 11 12 13 error_rate = [] for i in range(1, 40): knn = KNeighborsClassifier(n_neighbors=i) knn.fit(X_train, y_train) pred_i = knn.predict(X_test) error_rate.append(np.mean(pred_i != y_test)) plt.Figure(figsize=(10, 6)) plt.plot(range(1, 40), error_rate, color='blue', ls='dashed', marker='o', markerfacecolor='red', markersize=10) plt.title('Error Rate with K Value') plt.xlabel('K') plt.ylabel('Error Rate')
参考