KNNsir人品调查记
KNNsir人品调查记
A机构拟招聘一位行政总裁,小强各个方面都能符合公司的招聘要求,但是招聘委员会的一些成员对小强的人品是否很好心存疑惑,为此,招聘委员会专门请到了大名鼎鼎的神探KNNsir。
所谓“近朱者赤,近墨者黑”,KNNsir决定从小强的人际关系着手调查,经过一番调查,KNNsir发现和小强关系最好的有10个人,分别为A君、B君、C君……J君,这10人中A君、B君、C君、D君、E君曾有过不良的征信,F君、G君、H君、I君、J君一直以来征信良好。KNNsir经过查阅资料,他采用亲近指标和疏远指标来判断两个人之间的关系,并通过技术手段拿到了小强和10个关系最好的朋友的亲近指标( Intimate)和疏远指标( Estranged),他们分别如下:
姓名 | 亲近指标 | 疏远指标 | 人品 |
---|---|---|---|
A君 | 3.393533211 | 2.331273381 | 差 |
B君 | 3.110073483 | 1.781539638 | 差 |
C君 | 1.343853454 | 3.368312451 | 差 |
D君 | 3.582294121 | 4.679917921 | 差 |
E君 | 2.280362211 | 2.866990212 | 差 |
F君 | 7.423436752 | 4.685324231 | 好 |
G君 | 5.745231231 | 3.532131321 | 好 |
H君 | 9.172112222 | 2.511113104 | 好 |
I君 | 7.927841231 | 3.421455345 | 好 |
J君 | 7.939831414 | 0.791631213 | 好 |
小强 | 8.90933607318 | 3.365731514 | ? |
这些数据当然难不倒我们大名鼎鼎的KNNer神探了,只见他随手从工具箱里拿出了几件趁手的工具
import numpy as np
import matplotlib.pyplot as plt
然后把每个人的诚信指标和不诚信指标用序列[亲近指标, 疏远指标]
表示,同时把10个朋友的指标装进了叫做X_train
的容器,把他们的人品值装进了y_train
的容器。于是得X_train
,y_train
表示如下
X_train =np.array([
[3.393533211, 2.331273381],
[3.110073483, 1.781539638],
[1.343853454, 3.368312451],
[3.582294121, 4.679917921],
[2.280362211, 2.866990212],
[7.423436752, 4.685324231],
[5.745231231, 3.532131321],
[9.172112222, 2.511113104],
[7.927841231, 3.421455345],
[7.939831414, 0.791631213]
])
y_train = np.array(["差","差","差","差","差","好","好","好","好","好"])
为了看的一目了然,KNNsir把X_train的值一个个标到了图上,他用的是这个方法
plt.scatter(X_train[y_train == "差", 0],X_train[y_train == "差", 1],color='r', label = 'Good') #plt.scatter()是一个画散点图的方法,X_train[y_train == "差", 0]和X_train[y_train == "差", 1]分别表示人品差的朋友的x,y坐标,color='r',表示用红色表示这些点,并且给他们Good的标签
plt.scatter(X_train[y_train == "好", 0],X_train[y_train == "好", 1],color='g', label = 'Bad') # 和上面一样只是人品好的人用绿色表示,标签为bad
plt.xlabel('Intimate') # 设置X轴的标签
plt.ylabel('Estranged') # 设置y轴的标签
plt.axis([0, 10, 0, 5]) # 设置x轴的最大和最小坐标10和0,y轴最大坐标和最小坐标5和0
plt.legend(loc='upper left') #左上角显示legend
plt.show()
得到了如👉所示的图形:
ScreenClip.png
我们先把小强的[亲近指标, 疏远指标]
赋值给X
X = np.array([8.90933607318, 3.365731514])
为了判断小强和每个朋友的关系亲疏,KNNsir使用了著名的欧拉公式:
欧拉公式:
640.png,
math
工具包中有一个sqrt()
的函数可以很方便的求算平方根,应用公式表达小强和每个朋友的亲属关系可以用下面的代码
from math import sqrt
# 定义一个序列distences的容器记录小强和各个朋友的亲近关系
distances = []
for x_train in X_train:
d = sqrt(np.sum(x_train - x)**2) #np.sum(x_train - x)**2)实现根号内的计算
distances.append(d) # 将结果添加到容器中
# 以下使用列表生成器方法表达,结果一样,更加简单粗暴,适合高手服用
distance = [sqrt(np.sum(x_train - x)**2) for x_train in X_train]
distance
得到结果如下:
[6.550260995180001,
7.383454466180001,
7.5629016821800015,
4.01285554518,
7.1277151641800005,
0.16630660418000076,
2.9977050351800005,
0.5918422611799996,
0.9257710111800002,
3.54360496018]
看到这样的结果,让小白的我们看肯定是一脸懵逼,KNNsir早就想到了,于是乎运用numpy
旗下的argsort
函数帮我们进行了排序,并且还拿到了各个距离对应是哪个朋友
# np.argsort(array) 对一个数组进行排序,返回的是相应的排序后结果的索引
nearest = np.argsort(distances)
nearest
运行得到结果:
array([5, 7, 8, 6, 9, 3, 0, 4, 1, 2], dtype=int64)
也就是小强和[F君、H君、I君、G君、J君、D君、A君、E君、B君、C君]的亲密度是依次递减的。
有了这个结果就可以判断了,从其中选取靠前的六个人看看他们的人品分别是什么
# 选取亲密度最靠前的6个人
k = 6
# 查看这六个人的人品如何
topK_y = [y_train[i] for i in nearest[:k]]
topK_y
运行得到['好', '好', '好', '好', '好', '差']
的结果,其实此时小强的人品如何按照“近朱者赤”我们便可以看出来了,不过责任心极强的KNNsir怎么可能会不负责到底呢,于是乎KNNer用collection中的counter方法把结论拍到你的眼前
from collections import Counter
votes = Counter(topK_y) #统计topk_y中人品好和差的个数,-->Counter({'好': 5, '差': 1})
predect_y = votes.most_common(1)[0][0] #获取votes中排名第一的元素的值,votes.most_common(1)-->[('好', 5)],第一次[0]-->('好', 5),第二次[0]-->'好'
predect_y
结果当然是:好,小强同学的人品是没问题滴!
经过一番忙活,活就算基本上忙完了,突然KNNsir一拍脑门,“哎呀,我怎么忘了还有更方便的方法呀,直接从sklearn中调用KNeighborsClassifier模块就可以轻松实现了”,接着他开始在电脑上点点,很快写下了下面的代码:
from sklearn.neighbors import KNeighborsClassifier
# 创建kNN_classifier实例
kNN_classifier = KNeighborsClassifier(n_neighbors=6)
# kNN_classifier做一遍fit(拟合)的过程,没有返回值,模型就存储在kNN_classifier实例中
kNN_classifier.fit(X_train, y_train)
# kNN进行预测predict,需要传入一个矩阵,而不能是一个数组。
# reshape()成一个二维数组,第一个参数是1表示只有一个数据,第二个参数-1,numpy自动决定第二维度有多少
y_predict = kNN_classifier.predict(x.reshape(1,-1))
y_predict
轻松地按下enter,屏幕上再次出现了‘好’的结果
工作干完了,可以犒赏下自己了,KNNsir潇洒地合上了电脑,“撸串,走起!”