- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试用 Python 从头开始实现 K 最近邻算法。我编写的代码对于 Breast-Cancer-Wisconsin.csv
数据集效果很好。
但是,当我尝试为 Iris.csv 数据集运行相同的代码时,我的实现失败并给出 KeyError。
这两个数据集的唯一区别是,在 Breast-Cancer-Wisconsin.csv
中只有 2 个类别(“2”表示恶性,“4”表示良性),并且标签是整数,在 Iris.csv
中有 3 个类('setosa'、'versicolor'、'virginica'),并且所有这 3 个标签都是字符串类型。
这是我编写的代码(针对 Iris.csv
):
import numpy as np
from math import sqrt
import matplotlib.pyplot as plt
from matplotlib import style
from collections import Counter
import warnings
import pandas as pd
import random
style.use('fivethirtyeight')
dataset = {'k':[[1,2],[2,3],[3,1]], 'r':[[6,5],[7,7],[8,6]]}
new_features = [5,7]
#[[plt.scatter(j[0],j[1], s=100, color=i) for j in dataset[i]] for i in dataset]
#plt.scatter(new_features[0], new_features[1], s=100)
#plt.show()
def k_nearest_neighbors(data, predict, k=3):
if len(data) >= k:
warnings.warn('K is set to a value less than total voting groups!')
distances = []
for group in data:
for features in data[group]:
euclidean_distance = np.linalg.norm(np.array(features) - np.array(predict))
distances.append([euclidean_distance, group])
votes = [i[1] for i in sorted(distances)[:k]]
vote_result = Counter(votes).most_common(1)[0][0]
return vote_result
df = pd.read_csv('iris.csv')
df.replace('?', -99999, inplace=True)
#full_data = df.astype(float).values.tolist()
#random.shuffle(full_data)
test_size = 0.2
train_set = {'setosa':[], 'versicolor':[], 'virginica':[]}
test_set = {'setosa':[], 'versicolor':[], 'virginica':[]}
train_data = full_data[:-int(test_size*len(full_data))]
test_data = full_data[-int(test_size*len(full_data)):]
for i in train_data:
train_set[i[-1]].append(i[:-1])
for i in test_data:
test_set[i[-1]].append(i[:-1])
correct = 0
total = 0
for group in test_set:
for data in test_set[group]:
vote = k_nearest_neighbors(train_set, data, k=5)
if group == vote:
correct += 1
total += 1
print('Accuracy : ', correct/total)
当我运行上述代码时,我在第 49 行收到一条 KeyError
消息。
有人可以向我解释一下我哪里出错了吗?另外,如果有人能指出我如何修改这个算法以在将来对多个类(而不是 2 或 3 个)进行分类,那就太好了?
另外,如果类是字符串类型而不是整数,我该如何处理?
我想到的一个解决方案是将所有字符串类型转换为整数类型并尝试解决,但这可行吗?
引用文献
最佳答案
让我们从你的最后一个问题开始:
one solution I thought of was to convert all string types to integer types and try to solve but would that work?
是的,那会起作用。您不必对代码中每个问题的所有类的名称进行硬编码。相反,您可以编写一个函数来读取类属性的所有不同值,并为每个不同的值分配一个数值。
Could anyone please explain to me where I am going wrong?
问题很可能是您正在读取的实例的类属性不是 'setosa'、'versicolor'、'virginica'
(类似于 Iris-setosa
> 也许?)。上面的想法应该可以解决这个问题。
Also, it would be great if someone could point out how do I modify this algorithm to classify multiple classes (instead of 2 or 3) in the future?
正如之前所讨论的,您只需要避免在代码中对类的名称进行硬编码
Also, how do I handle if the classes are in string type instead of integer?
def get_class_values(data):
classes_seen = {}
for i in data:
_class = data[-1]
if _class not in classes_seen:
classes_seen[_class] = len(classes_seen)
return classes_seen
像这样的函数将返回所有类(无论类型)和数字代码(从 0 到 N-1)之间的映射。使用这个映射也可以解决之前提到的所有问题。
关于python-3.x - 从头开始实现 K 最近邻时,如何修复代码中的 KeyError 错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49262248/
我是一名优秀的程序员,十分优秀!