简介
K-Nearest Neighbors 是一个监督学习算法,其中数据是用与其分类相符的数据点进行训练。测量不同特征值之间的距离或相似度的方法进行分类。
算法原理
为了预测给定数据点的分类,它考虑与其相邻最近的K个数据点的类别,并选择K个临近点大多数所属的类别作为预测分类。
输入与输出
- 输入为训练样本集,训练样本集中对应的类别标签,没标签的新数据,K
-
算法决策过程
将新数据的每个特征与样本集中数据对应的特征比较
- 提取样本集中特征最相似(最近邻)的K(一般不大于20个)个数据的分类标签
选择K个最相似数据中出现次数最多的分类标签,作为新数据的分类标签
算法详细流程
KNN算法是对未知类别的数据集中的每个数据点依次执行:
计算已知类别数据集中的点与当前点之间的距离
- 按照距离递增次序排序
- 选取与当前点最相似的K个点
- 确定前K个点所在类别的出现次数或频率
-
算法关键点
特征中有非数值类型,需将其量化为数值
- 选择合理的计算距离或相似度的方法
- K值的确定
-
使用scikit-learn实现KNN并预测实例
在这里我们使用IBM提供的teleCust1000t数据集,可以预先下载好,也可以在notebook中使用wget进行下载
!wget -O teleCust1000t.csv https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-ML0101EN-SkillsNetwork/labs/Module%203/data/teleCust1000t.csv
加载数据
import pandas as pd
df = pd.read_csv('teleCust1000t.csv')
查看数据基本信息
# 可使用多种方式对数据基本信息进行查看
df.head()
# 对一列进行查看
df['custcat'].value_counts()
# 也可以使用DataFrame的hist方法将数据进行可视化查看
df.hist(column = 'income', bins = 50)
定义特征集和标签集
X: 特征集
- y: 标签集
X = df[['region', 'tenure','age', 'marital', 'address', 'income', 'ed', 'employ','retire', 'gender', 'reside']].values
y = df[['custcat']].values
数据标准化
在一些类似KNN的基于数据点距离的算法中,通过给定数据零均值和单位方差来达到数据标准化,我们可以使用sklearn中的preprocessing可以快速实现此过程from sklearn import preprocessing
X = preprocessing.StrandardScaler().fit(X).transform(X.astype(float))
拆分训练与测试数据
在上面算法关键点中我们提到KNN算法有一个关键点在于K值的确定,通常我们会使用交叉验证误差统计选择法,交叉验证简而言之就是将样本数据拆分为训练和测试数据,通过训练数据训练的模型,再利用测试数据测试其误差率,然后比较不同的K值时交叉验证平均误差率,从而选择较小的K值,因此这一步我们先将数据进行拆分from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 4) # test size 0.2即将20%数据作为测试数据,剩下80%作为训练数据
实现分类器
下面我们通过sklearn提供的KNerghborsClassifier实现分类器 ```python from sklearn.neighbors import KNeighborsClassifier
初始化K为4
k = 4 neigh = KNeighborsClassifier(n_neighbors = k).fit(X_train, y_train)
通过我们的训练结果预测测试数据
yhat = neigh.predict(X_test)
<a name="77FeC"></a>
### 查看结果
我们使用sklearn的metrics提供的accuracy_score方法查看预测的准确度,在多标签分类中,准确度分类得分(accuracy classification score)是一个计算子集准确度的方法
```python
from sklearn import metrics
print("Train set accuracy: ", metrics.accuracy_score(y_train, neigh.predict(X_train)))
print("Test set accuracy: ", metrics.accuracy_score(y_test, yhat))
在上面的例子中我们简单的实现了一个KNN算法并用以预测一个给定的数据集,而对于KNN算法来说,K是一个需要检查的最近邻居数,由用户来指定,但我们能否找到最准确的K值呢。
通常的方式是保留一部分数据用于测试模型的准确性,然后选择K = 1,使用训练数据进行建模,然后计算预测整个测试数据的准确性。重复这个过程并增加K的值,从而找到对于模型最好的K
K = 10
mean_acc = np.zeros((K - 1))
std_acc = np.zeros((K - 1))
for i in range(1, K):
# 重复上面的训练和预测过程
neigh = KNeighborsClassifier(n_neighbors = i).fit(X_train, y_train)
yhat = neigh.predict(X_test)
mean_acc[n - 1] = metrics.accuracy_score(y_test, yhat)
std_acc[n - 1] = np.std(yhat == y_test) / np.sqrt(yhat.shape[0])
print( "The best accuracy was with", mean_acc.max(), "with k=", mean_acc.argmax()+1)