K近傍法
一般的な考え方:アルゴリズムの思想の特徴によってグラフ確立し、次いでKポイントの各々の発生確率を決定する、最小距離K既知の点を選択するために、既知点の予測、の各点までの距離を算出し、選択結果はポイントが予測点の結果として知られていることを最も高い確率に表示されます。
二次元機能は、それが以下に示されている場合、既知点と予測点から計算され、その後、クラス予測点として分類知られているこの点までの最短距離を置きます。
距離式:
したがって、n次元(X11、X12、X13 ....... X1Nの2点のため ) および(X21、X22、X23 ...... X2nを ) 距離
PYコードの実装のKNN
アルゴリズム(算出された距離)
アイデア:トレーニングセットはその後、ラインのアイテム[[X11、X12、X13 ...]、[X21、X22、X23 ...]、[X31、X32、X33 ...] ...]式の全てを備えてテストプロジェクト[XN1、XN2、XN3 ...]、[XN1、XN2、XN3 ...]、[XN1、XN2、XN3 ...] ...]同一の行のように、次いで訓練は二乗で、差分を設定し、K.を選出します
def classify0(inX, dataSet, labels, k):
"""
inX为测试集
dataSet为训练集
labels为训练集的标签
k为KNN算法的参数K
"""
dataSetSize = dataSet.shape[0] #第一步,读取训练集的行数,使用np.shape[0],为了将测试集构造出与他一样大的测试集计算差
diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet #使用np.tile( ) 复制构造出一个训练集一样大的测试集数组,然后与训练集每一个特征作差
sqDiffMat = diffMat**2 #对每一个特征差求平方
sqDistances = sqDiffMat.sum(axis=1) #对特征求平方和,注意设置axis=1,表示横向求和,不设置的话就是求全部和,设置的话就是横向一组
distances = sqDistances**0.5 # 开方,计算出距离
sortedDistIndices = distances.argsort() # 对距离排序,返回从小到大排的索引
classCount = {} #定一个记录类别次数的字典
for i in range(k):#取出前K个最小距离的索引,分别获取对应标签
voteIlabel = labels[sortedDistIndices[i]] #获取标签用于计算对应的概率
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 #计算各个标签的出现次序(用get获得标签的次数,若是没有返回默认值0,加一之后修改对应标签的键值)
sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True) #需要对字典排序取出value最大对应的健,所以先把字典转换为序列,序列是有sort方法的。所以先使用字典的items方法,转换成键值对应的数组,然后使用序列的sorted方法排序,并且传入key和reverse参数,key=operator.itemgetter(1)表示依据可迭代对象1号位置的值,也就是key的value的值来进行排序,然后reverse表示排序顺序从大到小,默认从小到大
#返回次数最多的类别,即所要分类的类别
return sortedClassCount[0][0] #返回排序完成后的第一个元组中第一个值(也就是key)
算法完成
しかし、完了するために一緒に仕事や他の作業を完了する必要があり、その次の仕事も非常に重要です
データのインポートの解決
目的:データを解析することができるnumpyの中に注ぎ
def file2matrix(filename):
"""
filename为文件名
"""
fr = open(filename) #打开文件
arrayOLines = fr.readlines() #读取文件所有内容
numberOfLines = len(arrayOLines) #得到文件行数
returnMat = np.zeros((numberOfLines,3)) #用0填充构造一个矩阵,行数x3个特征
classLabelVector = [] #定义一个标签向量
index = 0 #行的索引值
for line in arrayOLines:
line = line.strip() #删除每行字符串收尾两端的空字符('\n','\r','\t',' )
listFromLine = line.split('\t') #字符串中间分隔符并未去除,所以利用分隔符分割字符串
returnMat[index,:] = listFromLine[0:3] #然后将分割出来的字符放到构造好的矩阵中
#将字符标签改为数字标签,构造出标签向量
if listFromLine[-1] == 'didntLike':
classLabelVector.append(1)
elif listFromLine[-1] == 'smallDoses':
classLabelVector.append(2)
elif listFromLine[-1] == 'largeDoses':
classLabelVector.append(3)
index += 1
return returnMat, classLabelVector #数据读取完成,获得特征矩阵,标签向量
データの可視化
import matplotlib
import matplotlib.pyplot as plt
fig=plt.figure()
ax=fig.add_subplot(111)
ax.scatter(X序列,Y序列,颜色)
ax.legened() #合并图例
plt.show()
データの正規化
距離算出式ので、正方形X21-X11再発根数、X21およびX11は大きい値を有するときに、無視される値が小さいベースを行います小さい値があるが、我々は当初X21考案しますあればとX11と同じ機能の重い重みとして、機能は我々が当初想定無意味見落とさので、私たちは機能の重量が同じになるように正規化する必要があります。正規化アルゴリズムのプロセスを次のようnewValueに=(OLDVALUE - 最小)/(最大 - 最小)を
def autoNorm(dataSet):
minVals = dataSet.min() #获得数据的最大、小值
maxVals = dataSet.max()
ranges = maxVals - minVals #求差值
normDataSet = np.zeros(np.shape(dataSet)) #根据数据集的行列数构造0矩阵
m = dataSet.shape[0] #返回数据集的行数
normDataSet = dataSet - np.tile(minVals, (m, 1)) #原始值减去最小值
normDataSet = normDataSet / np.tile(ranges, (m, 1)) #除以最大和最小值的差,得到归一化数据
return normDataSet, ranges, minVals
アルゴリズムの精度を確認してください
計算アルゴリズムの精度
....省略导入数据等过程,只写出计算准确率的要点
hoRatio = 0.10 #划分10%作为测试集
numTestVecs = int(m * hoRatio) #百分之十的测试数据的个数
errorCount = 0.0 #分类错误计数
for i in range(numTestVecs):
classifierResult = classify0(normMat[i,:], normMat[numTestVecs:m,:],datingLabels[numTestVecs:m], 4) #调用前面的算法获得测试结果
print("分类结果:%d\t真实类别:%d" % (classifierResult, datingLabels[i]))
if classifierResult != datingLabels[i]: #判断是否计入出错总数
errorCount += 1.0
print("错误率:%f%%" %(errorCount/float(numTestVecs)*100))