聚类-k近邻算法伪代码

231 阅读3分钟

引用:www.cnblogs.com/xiaofeng-bl… 算法简介: 其工作原理是:存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中的每一数据与所属分类的对应关系。

输入没有标签的新数据后,将新数据的每个特征与样本集中对应的数据对应的特征进行比较,然后算法提取出样本集中特征最相似数据(最近邻)的分类标签。(一般来说,我们只选择样本数据集中前k个最相似的数据,这就是k-近邻算法中k的出处,通常k是不大于20的整数。)

最后,我们选择k个最相似数据中出现次数最多的分类,作为新数据的分类。

代码实现

#!/usr/bin/python

#coding:utf-8

import sys

reload(sys)

sys.setdefaultencoding('utf8')

import numpy as np

import pandas as pd

from sklearn import preprocessing

import operator
#获取并加工源数据

def createDataSet():

#sheet_name也是指索引,从0开始

offline_ml_data=pd.read_excel(r"/Users/fabrice/python-test/test_juzhen.xlsx" ,sheet_name=0)

data_cols =offline_ml_data.columns.tolist()

#对分类变量做one_hot转换

one_hot_col=[u'城市']

offline_ml_data=offline_ml_data.join(pd.get_dummies(offline_ml_data.loc[:,one_hot_col]))

#做了one-hot转换后需要删除掉原始的分类变量,以免影响接下来的计算

del offline_ml_data[u'城市']

print(offline_ml_data)

#数据标准化,消除量纲的影响

scaler = preprocessing.StandardScaler().fit(offline_ml_data)

#得到每列的平均值,是一维数组

mean = scaler.mean_

print("mean:",mean)

#得到每列的标准差,是一维数组

std = scaler.var_

print("std:",std)

#直接标准化数据,转换之后,是一个二维数组

data_nomal = scaler.transform(offline_ml_data)

#如果没有经过转换,需要手动把dataFrame转换成二维数组

#offline_ml_data_arr=offline_ml_data.values

return data_nomal,mean,std
# inX: 分类的输入向量

# dataSet: 输入的训练样本集

# labels: 标签向量

# k: 选择最近邻居的数目

def classify0(inX, dataSet, labels, k):

    # 1.计算距离,这里采用的是欧式距离

    dataSetSize = dataSet.shape[0]  # 获取数据集大小,也就是有多少条数据

    diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet  # 将待测试数据扩展

    sqDiffMat = diffMat ** 2  # 差值矩阵中,矩阵元素分别平方

    sqDistances = sqDiffMat.sum(axis = 1)  # 横向求和,得到矩阵

    distances = sqDistances ** 0.5  # 矩阵中,每个元素都开方

    print("distances:",distances)

    sortedDistIndicies = distances.argsort()  # 距离排序

    print("sortedDistIndicies",sortedDistIndicies)



    # 2.选择距离最小的k个点

    classCount = {}

    for i in range(k):

    print('i:',i)

        voteIlabel = labels[sortedDistIndicies[i]]

        print('voteIlabel:',voteIlabel)

        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1

    print("classCount:",classCount)



    # 3.排序,选择label出现频率最高的那个

    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)

    return sortedClassCount[0][0]

#测试代码是否正确执行

predictData,mean,std=createDataSet()

#在createDataSet里对训练集和验证集做同样的标准化

#训练集和验证集划分

##对预测集做和验证集相同的标准化

#假设待验证的数据是m*n,首先把均值和标准差列表转换成m*n矩阵

mean2=np.tile(mean,(m,1))

std2=np.tile(std,(m,1))

#对预测集做矩阵减法,标准化数据

predictData=(predictData-mean2)/std2

labels=['A','A','B']

bb=classify0(inX,aa,labels,1)

print(bb)