KNN算法的python实现
KNN算法的python实现
大海201506 发表于8个月前
KNN算法的python实现
  • 发表于 8个月前
  • 阅读 10
  • 收藏 0
  • 点赞 0
  • 评论 0

新睿云服务器60天免费使用,快来体验!>>>   

摘要: 鸢尾花分类问题

1. 处理数据

# filename:文件路径  trainingSet:训练集  testSet:测试集 训练数据集数据量/测试数据集数据量的比值取67/33是一个常用的惯例。
def loadDataset(filename,split,trainingSet=[], testSet=[]):
    with open(filename,'r') as csvfile: #使用open方法打开文件
        lines = csv.reader(csvfile) #使用csv模块读取数据
        dataset = list(lines)
        for x in range(len(dataset)-1):
            for y in range(4):
                dataset[x][y] = float(dataset[x][y])
            if random.random() < split:
            #random.random()用于生成一个0到1的随机符点数: 0 <= n < 1.0。
            #随机地切分训练数据集和测试数据集。训练数据集数据量/测试数据集数据量的比值取67/33是一个常用的惯例,所以split取值一般为0.66
                trainingSet.append(dataset[x])
            else:
                testSet.append(dataset[x])

测试代码

trainingSet=[]
testSet=[]
loadDataset('iris.data',0.66,trainingSet,testSet)
print('trainingSet',repr(len(trainingSet)))
print('testSet',repr(len(testSet)))

2. 相似度

我们需要计算两个数据之间的相似度,便于获取最相似的N个实例来做出预测。

因为有关花的四个测量维度的数据都是数字形式的,并且具有相同的单位。我们可以直接使用欧式距离来测量。

二维平面上两点a(x1,y1)与b(x2,y2)间的欧氏距离: 输入图片说明

# length:告诉函数前几个维度需要处理,忽略后面的维度
def euclideanDistance(instance1,instance2,length):
    distance = 0
    for x in range(length):
        distance += pow((instance1[x]-instance2[x]),2) #所有需要计算的维度距离相加
    return math.sqrt(distance)

测试代码:

data1 = [2,2,2,'a']
data2 = [4,4,4,'b']
# length=3只计算前面三个维度
distance = euclideanDistance(data1,data2,3)
print('distance',repr(distance))

3. 邻近相似度

有了相似度计算的方法,我们可以获取与需要预测的数据最接近的N个数据实例了。

最直接的方法就是计算待预测数据到所有数据实例的距离,取其中距离最小的N个。

# testInstance:待预测数据
def getNeighbors(trainingSet, testInstance, k):
    distances = []
    length = len(testInstance)-1
    for x in range(len(trainingSet)):
        #testinstance
        dist = euclideanDistance(testInstance, trainingSet[x], length)
        distances.append((trainingSet[x], dist))
        #distances.append(dist)
    distances.sort(key=operator.itemgetter(1))
    neighbors = []
    for x in range(k):
        neighbors.append(distances[x][0])
        return neighbors

测试代码:

trainSet = [[2,2,2,'a'],[4,4,4,'b']]
testInstance = [5,5,5]
k = 1
neighbors = getNeighbors(trainSet,testInstance,k)
print(neighbors)

测试结果(邻近元素): [[4, 4, 4, 'b']]

4. 结果

接下来的任务就是基于最近的几个实例来得到预测结果了。

我们可以让这些邻近元素来对预测属性进行投票,得票最多的选项作为预测结果

下面这个函数实现了投票的逻辑,它假设需预测的属性放在数据实例(数组)的最后。

def getResponse(neighbors):
    classVotes = {}
    for x in range(len(neighbors)): #遍历最邻近元素
        response = neighbors[x][-1] #假设需预测的属性放在数据实例(数组)的最后
        if response in classVotes:
            classVotes[response] += 1 # 对预测属性投票
        else:
            classVotes[response] = 1
    sortedVotes = sorted(classVotes.items(), key=None, reverse=True)
    return sortedVotes[0][0] #

测试代码:

neighbors= [[1,1,1,'a'],[2,2,2,'a'],[3,3,3,'b']]
response = getResponse(neighbors)
print(response)

5. 准确度

简单的评估方法:计算在测试数据集中算法正确预测的比例,这个比例叫分类准确度。

# 假设predictions为测试集的预测结果集
def getAccuracy(testSet, predictions):
    correct = 0
    for x in range(len(testSet)):
        if testSet[x][-1] is predictions[x]:
            correct += 1
    return (correct/float(len(testSet))) * 100.0

测试代码:

testSet = [[1,1,1,'a'],[2,2,2,'a'],[3,3,3,'b']]
predictions = ['a','a','a']
accuracy = getAccuracy(testSet,predictions)
print(accuracy)
  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 3
博文 42
码字总数 107139
×
大海201506
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: