本文已参与「新人创造礼」活动,一同开启创造之路。
前言
自己大数据专业初入大三刚刚接触机器学习这一课程,最近在学习这本书《机器学习实战》,第一次操练就是简略易懂的KNN算法了。当然初入一些算法和机器学习的一些库还不是很熟练掌握,有待提升自己的编程结合才能。在此范畴自己有许多不明确疑问,或许文章会有些许过错,望咱们在谈论区纠正,本篇文章过错将会不断更正维护。
一、[KNN算法]
作业原理:存在一个样本数据调集,也称作操练样本集,而且样本会集每个数据都纯在标签,就每一个样本都有一个标签与之对应。输入没带标签的新数据之后,将新数据的每个特征与样本会集数据对应的特征进行比较,然后算法提取样本会集特征最类似数据(最近邻)的分类标签,然后给新数据该标签。咱们只挑选样本数据会集前k个最类似的数据,最终挑选k个最类似数据中出现次数最多的分类,作为新数据的分类。 光看文字了解显然不行深刻,来看看图片。
假定新加入了一个绿正方形,现在咱们要断定它是归于三角形还是归于圆形。首要依据先看间隔正方形最近的图形有哪些,依据它们离正方形的间隔进行排序,再依据确定的k值进行区分,选出离方针最近的k个图形,然后断定在k个里边哪个图形占多数,占多数的则把该方针归为哪一类。
这样应该很好了解,也说明了KNN算法的成果很大程度取决于K的挑选,其中K通常是不大于20的整数。KNN算法中,所挑选的街坊都是现已正确分类的目标。该办法在定类决议计划上只依据最邻近的一个或许几个样本的类别来决议待分样本所属的类别。
二、间隔衡量
因为在各种不同的环境下选用knn算法,衡量变量间隔也有许多种不同的算法。免了目标之间的匹配问题。在KNN算法中一般选用的是欧氏间隔或曼哈顿间隔:
欧氏间隔(二维):
曼哈顿间隔(二维):
三、完成算法
首要算法一般流程
.收集数据->处理数据(标准化)->剖析数据->操练算法->测验算法->运用算法
先创立数据导入块
import operator
from matplotlib import pyplot as plt
#创立数据集
def createrDataSet():
group = np.array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
labels = ['A','A','B','B']
return group,labels
类似这种作用,怎么开端写入knn算法
import operator
#创立数据集
def createrDataSet():
group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
labels = ['A','A','B','B']
return group,labels
ture = 1
#inX:输入向量; dataSet:操练样本集; labels:标签向量 k=最近街坊个数; 其中标签元素数目和矩阵dataSet的行数相同。
def classify0(inX,dataSet,labels,k):
dataSetSize = dataSet.shape[0] #行数
#核算欧式间隔
diffMat = tile(inX,(dataSetSize,1))-dataSet #扩展dataSet行,别离相减,形成(x1-x2)矩阵
sqDiffMat = diffMat**2
sqDistances = sqDiffMat.sum(axis=1)
distances = sqDistances**0.5
sortedDistIndicies = distances.argsort()#从小到大排序,取得索引值(下标)
#挑选间隔最小的k个点
classCount={}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
#排序
sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=ture)
return sortedClassCount[0][0]
详细完成进程现已在代码中标识出来了。
咱们能够通过简略的测验。
from numpy import *
dataSet,labels = KNN.createrDataSet()
inX = array([0,0.3])
k = 3
output = KNN.classify0(inX,dataSet,labels,k)
print("测验数据为:",inX,"分类成果为:",output)
PS.依照机器学习实战的那原本敲代码的话或许会遇到’dict’ object has no attribute ‘iteritems’。
原因:iteritems是为python2环境中dict的函数。在python3报错,将iteritems改为items即可。
四、实战操练
操练当然是咱们的海伦约会实例,也是最常见拿来练手的例子了。 海伦女士一向运用在线约会网站寻找适合自己的约会目标。尽管约会网站会推荐不同的人选,但她并不是喜爱每一个人。通过一番总结,她发现自己往来过的人能够进行如下分类:
- 不喜爱的人
- 魅力一般的人
- 极具魅力的人 首要预备数据,海伦收集的样本数据主要包括以下3种特征:
- 每年取得的飞翔常客路程数
- 玩视频游戏所消耗时刻百分比
- 每周消费的冰淇淋公升数
1.转换数据
将文本记录转换为Numpy解析程序
#输入文件名字符串,输出为操练样本矩阵和类标签
def file2matrix(filename):
fr = open(filename)
arrayOLines = fr.readlines()#得到文件行数
numberOfLines = len(arrayOLines)
returnMat = zeros((numberOfLines,3))#得到与之对应行数,3列的0填充矩阵
classLabelVector = []
index = 0
for line in arrayOLines:
line = line.strip()#截取一切回车字符
listFromLine = line.split('\t')#按tap格局切割
returnMat[index,:] = listFromLine[0:3]#从头开端填充
classLabelVector.append((listFromLine[-1]))#将标签保留
index += 1
# datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')
# print(datingDateMat,datingLabels)
from collections import Counter
##将列表的最终一列由字符串转化为数字,便于以后的核算
dictClassLabel = Counter(classLabelVector)
classLabel = []
kind = list(dictClassLabel)
for item in classLabelVector:
if item == kind[0]:
item = 1
elif item == kind[1]:
item = 2
else:
item = 3
classLabel.append(item)
return returnMat,classLabel#####将文本中的数据导入到列表
咱们能够看到数据
2.剖析数据
咱们能够运用Matplotlib创立散点图
import matplotlib.pyplot as plt
#绘制散点图
fig = plt.figure()
ax = fig.add_subplot(111)#切割为1行1列第1块
ax.scatter(datingDataMat[:,1], datingDataMat[:,2],15.0*array(datingLabels),15.0*array(datingLabels))
plt.show()
这里比照一下‘玩视频游戏所消耗时刻百分比’和‘每周消费的冰淇淋公升数’
很明显
数据还没有处理美观不出什么作用。
3.数据归一化
因为依据knn选用的为欧式间隔,在数据特点权重相同的情况下,数字差值最大的特点对核算成果影响最大,所以咱们必须运用数据归一化避免比较差值过大严重影响核算成果。
那么接下来咱们进行数据归一化,考虑到运用Min-Max标准或许假如max和min不稳定,很容易使得归一化成果不稳定,使得后续运用作用也不稳定。所以咱们选用Z-score标准化。
def autoNorm(dataSet):
sc = StandardScaler()
normDataSet =sc.fit_transform(datingDataMat)
mean = sc.mean_
std = sqrt(sc.var_)
return normDataSet,mean,std
很明显归一化的数据很易于剖析:
4.测验算法
接下来开端评价咱们算法的可靠性,通常咱们只提供已有数据的90%作为操练样本操练分类器,而运用其余的10%数据去测验分类器。一开端想运用线性回归的
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.1,
random_state=0)
发现只能二值核算,有点为难,不知道咱们有什么好的办法来区分数据集,安装书上的办法属实是最原始的区分办法。
#将回来的特征矩阵和分类向量别离存储到datingDataMat和datingLabels中
datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')
#取一切数据的百分之十
hoRatio = 0.10
#数据归一化,回来归一化后的矩阵,数据规模,数据最小值
normMat= autoNorm(datingDataMat)
#取得normMat的行数
m = normMat.shape[0]
#百分之十的测验数据的个数
numTestVecs = int(m * hoRatio)
#分类过错计数
errorCount = 0.0
for i in range(numTestVecs):
#前numTestVecs个数据作为测验集,后m-numTestVecs个数据作为操练集
classifierResult = KNN.classify0(normMat[i,:], normMat[numTestVecs:m,:],
datingLabels[numTestVecs:m], 4)
print("分类成果:%s\t真实类别:%d" % (classifierResult, datingLabels[i]))
if classifierResult != datingLabels[i]:
errorCount += 1.0
print("过错率:%f%%" % (errorCount / float(numTestVecs) * 100))
这是没简化标签时候截的图,后边优化了一下便于核算
5.运用算法
通过测验咱们的knn算法还算不错,现在咱们能够编写一个窗口来运用这个分类器了:
#输出成果
resultList = ['厌烦','有些喜爱','非常喜爱']
#三维特征用户输入
precentTats = float(input("玩视频游戏所耗时刻百分比:"))
ffMiles = float(input("每年取得的飞翔常客路程数:"))
iceCream = float(input("每周消费的冰激淋公升数:"))
#翻开的文件名
filename = "datingTestSet2.txt"
#翻开并处理数据
datingDataMat, datingLabels = file2matrix(filename)
#操练集归一化
normMat, mean, std = autoNorm(datingDataMat)
#生成NumPy数组,测验集
inArr = array([ffMiles, precentTats, iceCream])
#测验集归一化
norminArr = (inArr - mean) / std
#回来分类成果
classifierResult =KNN.classify0(norminArr, normMat, datingLabels, 3)
#打印成果
print("你或许%s这个人" % (resultList[classifierResult-1]))
classifyPerson()
附上我理想女友的数据
的确有点喜爱哈哈哈
总结
详细算法应该很好了解,要运用起来也不难,很好掌握的一个算法,就是在不同的环境下要考虑该怎么改善再运用。下一篇开端学习决议计划树了。