KNNsir人品调查记

2019-11-10  本文已影响0人  行走读书生活

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_trainy_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潇洒地合上了电脑,“撸串,走起!”

上一篇下一篇

猜你喜欢

热点阅读