美文网首页
2020-05-07

2020-05-07

作者: 数据小黑升值记 | 来源:发表于2020-05-07 20:01 被阅读0次

    现在,我们打算回顾乳腺肿瘤数据集,它记录肿瘤的属性变将它们按照良性还是恶性分类。Sklearn 的 KNN 分类器有 95% 的准确率,并且我们打算测试我们自己的算法。

    我们会以下列代码开始:

    import numpy as np
    import warnings
    from collections import Counter
    import pandas as pd
    import random
    
    
    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
    

    这应该看起来很熟悉。要注意我导入了 Pandas 和 random。我已经移除了 Matplotlib 的导入,因为我们不打算绘制任何东西。下面,我们打算加载数据:

    df = pd.read_csv('breast-cancer-wisconsin.data.txt')
    df.replace('?',-99999, inplace=True)
    df.drop(['id'], 1, inplace=True)
    full_data = df.astype(float).values.tolist()
    

    这里,我们加载了数据,替换掉了问号,丢弃了 ID 列,并且将数据转危为列表的列表。要注意我们显式将 DataFrame 转换为浮点类型。出于一些原因,至少对于我来说,一些数据点仍然是数字,但是字符串数据类型并不是很好。

    下面,我们打算把数据打乱,之后将其分割:

    Next, we're going to shuffle the data, and then split it up:
    
    random.shuffle(full_data)
    test_size = 0.2
    train_set = {2:[], 4:[]}
    test_set = {2:[], 4:[]}
    train_data = full_data[:-int(test_size*len(full_data))]
    test_data = full_data[-int(test_size*len(full_data)):]
    

    首先我们打乱了数据(它包含特征和标签)。之后我们为训练和测试集准备了一个字典用于填充。下面,我们指定了哪个是train_data,哪个是test_data。我们选取前 80% 作为train_data(逻辑是在后 20% 的地方分割),之后我们通过在后 20% 的地方分割,来创建test_data

    现在我们开始填充字典。如果不清楚的话,字典有两个键:2 和 4。2 是良性肿瘤(和实际数据集相同),4 是恶性肿瘤,也和数据集相同。我们将其硬编码,但是其他人可以选取分类,并像这样创建字典,它的键是分类中的唯一值。我们仅仅是使其简单。

    for i in train_data:
        train_set[i[-1]].append(i[:-1])
    
    for i in test_data:
        test_set[i[-1]].append(i[:-1])
    

    现在我们填充了字典,我们拥有了测试集,其中键是分类,值是属性。

    最后就是训练和测试的时候了。使用 KNN,这些步骤基本就完成了,因为训练步骤就是把点村进内存,测试步骤就是比较距离:

    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)
    

    现在我们首先迭代测试集的分组(分类,2 或者 4,也是字典的键),之后我们遍历每个数据点,将数据点扔给k_nearest_neighbors,以及我们的训练集train_set,之后是我们的 K,它是 5。我选择了 5,纯粹是因为它是 SKlearn 的KNeighborsClassifier的默认值。所以我们的完整代码是:

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib import style
    import warnings
    from collections import Counter
    #dont forget this
    import pandas as pd
    import random
    style.use('fivethirtyeight')
    
    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('breast-cancer-wisconsin.data.txt')
    df.replace('?',-99999, inplace=True)
    df.drop(['id'], 1, inplace=True)
    full_data = df.astype(float).values.tolist()
    
    random.shuffle(full_data)
    
    test_size = 0.2
    train_set = {2:[], 4:[]}
    test_set = {2:[], 4:[]}
    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)
    

    相关文章

      网友评论

          本文标题:2020-05-07

          本文链接:https://www.haomeiwen.com/subject/nxszghtx.html