报错TypeError: unhashable type: 'numpy.ndarray

来源:4-4 分类准确度

weixin_慕仰9367891

2024-04-27

from sklearn import datasets
import numpy as np
iris = datasets.load_iris()
x = iris.data
y = iris.target.reshape(-1,1)

#定义一个切割全部样本,使其变为测试样本和训练样本的函数
def train_test_split(x,y,ratio=0.2,seed=None):

    assert x.shape[0] == y.shape[0], \
        "the sizes of x and y are not the same"
    assert 0.0 <= ratio <= 1.0, \
        'the split ratio is out of range'
    
    if seed:
        np.random.seed(seed)
    
    test_volume = int(ratio*x.shape[0])
    shuffle = np.random.permutation(x.shape[0])

    x_test = x[shuffle[:test_volume]]
    y_test = y[shuffle[:test_volume]]

    x_train = x[shuffle[test_volume:]]
    y_train = y[shuffle[test_volume:]]
    return x_train,x_test,y_train,y_test

from math import sqrt
from collections import Counter

#定义一个K近邻算法
class KNNClassifier:
    def __init__(self, k):  # __init__函数代表每个对象自带的属性,不会返回任何值
        assert k >= 1 and k % 1 == 0, 'k must be valid'
        self.k = k
        self._X_train = None  # 不希望别人随便动我的这个x的训练变量,因此要在标识符前面加上下划线
        self._y_train = None

    def fit(self, X_train, y_train):  # 根据训练数据集X_train和y_train训练kNN分类器
        self._X_train = X_train  # 不在这里指定要求的特征数量,是为了方便各种特征数量的训练集和预测数量的需要
        self._y_train = y_train  # 其实可以必须为一维的向量

        return self

    def predict(self, X_predict):  # 给定待预测数据集X_predict,返回表示X_predict的结果向量
        assert self._X_train is not None and self._y_train is not None, \
            'must fit before predict'  # 要求必须先进行训练才能进行预测
        assert X_predict.shape[1] == self._X_train.shape[1], \
            'the feature number of X_predict must be equal to X_train'
       
        y_predict = [self._predict(x) for x in X_predict]  # 类似于函数递归地在上一个函数中执行当前还没定义的函数,对X_predict中的所有元素都使用_predict方法

        return np.array(y_predict)  # 在上一行的函数递归之后,每个点的属性已经有了答案,且按照顺序放在了要返回的数据中

    def _predict(self, x): 
        assert x.shape[0] == self._X_train.shape[1], \
            'the feature number of X_predict must be equal to X_train' 
        distances = [sqrt(np.sum((x_train - x) ** 2)) for x_train in
                     self._X_train]  # 找出训练集中所有点与给定的x点一一对应的距离,并按照原本的顺序进行排列成为一个list
        nearest = np.argsort(distances)  # 从左到右列出最近的训练集中的点的索引
        topK_y = [self._y_train[i] for i in
                  nearest[:self.k]] 
        votes = Counter(topK_y) 

        return votes.most_common(1)[0][0]  

    def __repr__(self):
        return f'KNN(K={self.k})'
    
    #将鸢尾花数据集的数据进行切分并应用到该算法中
    
X_train,X_test,y_train,y_test = train_test_split(x,y)
my_knn_clf = KNNClassifier(k=3)
my_knn_clf.fit(X_train,y_train)#进行训练
y_predict = my_knn_clf.predict(X_test)
print(y_predict)

老师,我在输入上述代码之后会在倒数第二行的y_predict = my_knn_clf.predict(X_test)这行代码中出现TypeError: unhashable type: 'numpy.ndarray的错误,但是我几乎可以肯定我写的代码与老师提供的都是一样的呀,到底是为什么呀?

写回答

1回答

weixin_慕仰9367891

提问者

2024-04-27

我知道了,y = iris.target.reshape(-1,1)这一行中被错误地处理成了一个矩阵,而不是向量,导致了最终的错误

0
1
liuyubobobo
继续加油!:)
2024-04-29
共1条回复

Python3入门机器学习 经典算法与应用  

Python3+sklearn,兼顾原理、算法底层实现和框架使用。

5839 学习 · 2437 问题

查看课程