为了让绝大多数人均可以看懂,因此我就用简单的话语来说解机器学习每个算法php
第一次写ML的博文,因此可能会有些地方出错,欢迎各位大佬提出意见或错误python
祝你们开心进步每一天~算法
博文代码所有为python机器学习
简单的说一下什么是机器学习,机器学习英文名称是Machine Learning, MLide
KNN(k-Nearest Neighbor)中文名为K近邻,是分类算法的一种,KNN的思路为在在数据和标签已知的状况下将测试数据的特征和训练集中的特征进行比较,找到与之最类似的k的数据,那么这个数据对应的类别就是k个数据中出现次数最多的那个类别函数
寻找类似度有多重方法,最经常使用的为欧几里得度量,皮尔逊相关系数,余弦类似度性能
算法流程大体分为 学习
本文使用iris数据集,可从UCI处下载 传送门测试
使用py的三种库pandas,numpy,sklearnidea
查看数据集
前4列为特征,最后一列为标签
1 #获取数据 2 X=np.loadtxt("/Users/galan/py/ML-D/iris.data.txt",delimiter=",",dtype=float,usecols=(0,1,2,3)) 3 y=np.loadtxt("/Users/galan/py/ML-D/iris.data.txt",delimiter=",",dtype=str,usecols=(4,)) 4 #建立训练数据和测试数据 5 X_train,X_test,y_train,y_test=train_test_split(X,y,train_size=.7)
第2,3行为获取特征和标签
第五行中使用sklearn库的train_test_split函数,用来方便分隔测试集和训练集
本文使用欧几里得度量算法,在下方也会列出皮尔逊类似性和余弦类似度的py代码
欧几里得度量多为计算空间中两点间的距离
def eculidean(p,q): sumSq=0.0 #讲差值德平方累加起来 for i in range(len(p)): sumSq+=sum(p[i]-q[i])**2 #求平方根 return (sumSq**0.5)
皮尔逊相关系数是度量两个变量之间相关程度,介于-1和1之间,1表明变量彻底正相关,0表明无关,-1表明彻底负关系
def pearson(x,y): n=len(x) vals=range(n) #简单求和 sumx=sum([float(x[i]) for i in vals]) sumy=sum([float(y[i]) for i in vals]) #求平方和 sumxSq=sum([x[i]**2.0 for i in vals]) sumySq=sum([y[i]**2.0 for i in vals]) #求乘积之和 pSum=sum([x[i]*y[i] for i in vals]) #计算皮尔逊评价值 num=pSum-(sumx*sumy/n) den=((sumxSq-pow(sumx,2)/n)*(sumySq-pow(sumy,2)/n))**.5 if den==0:return 1 r=num/den return r
余弦类似度将向量根据坐标值,绘制到向量空间中求得他们的夹角,并得出夹角对应的余弦值,夹角越小,余弦值越接近于1,它们的方向更加吻合,则越类似。
#vect1,vect2位两个一维向量如(1,1) def getCost(vect1,vect2): sum_x=0.0 sum_y=0.0 sum_xy=0.0 for a,b in zip(vect1,vect2): sum_xy+=a*b sum_x+=a**2 sum_y+=b**2 if sum_x==0.0 or sum_y==0.0: return None else: return sum_xy/((sum_x*sum_y)**0.5)
knn的求证过程
#K值 k=5 #计算全部的欧氏距离组合成字典 Dists={} for i in range(len(X_train)): Dists[eculidean(X_test[0],X_train[i])]=y_train[i] #排序字典 sortedDist=sorted(Dists.iteritems(),reverse=True,key=lambda x:x[0])[:k] classCount={} #寻找最多的类别标签 for i in sortedDist: if i[1] in classCount: classCount[i[1]]+=1 else: classCount[i[1]]=1 print classCount
下面贴出全部的代码
#coding:utf-8 import pandas as pd import numpy as np from sklearn.model_selection import train_test_split #获取数据 X=np.loadtxt("./ML-D/iris.data.txt",delimiter=",",dtype=float,usecols=(0,1,2,3)) y=np.loadtxt("./ML-D/iris.data.txt",delimiter=",",dtype=str,usecols=(4,)) #建立训练数据和测试数据 X_train,X_test,y_train,y_test=train_test_split(X,y,train_size=.7) def eculidean(p,q): sumSq=0.0 #讲差值德平方累加起来 for i in range(len(p)): sumSq+=sum(p-q[i])**2 #求平方根 return (sumSq**0.5) def classify(X_train,X_test,k): #计算全部的欧氏距离 Dists={} for i in range(len(X_train)): Dists[eculidean(X_test,X_train[i])]=y_train[i] #排序字典 sortedDist=sorted(Dists.iteritems(),reverse=True,key=lambda x:x[0])[:k] classCount={} #寻找最多的类别标签 for i in sortedDist: if i[1] in classCount: classCount[i[1]]+=1 else: classCount[i[1]]=1 return sorted(classCount.iteritems(),key=lambda x:x[1],reverse=True) if __name__ == '__main__': print "%s的类别为%s"%(X_test[15],classify(X_train,X_test[0],5)[0][0])
我会每周更新一篇ML博文,方便你们学习,^_^ 共同窗习共同提升,欢迎你们前来对个人文章提出宝贵意见
祝你们周末愉快~