机器学习实战kNN

1.首先需要 安装numpy,matplotlib包

可以使用pip -install 来安装

2.分析预测步骤

1>收集数据,可以参考 https://blog.csdn.net/sinat_29957455/article/details/79123394

    也可以在其他数据库中自行下载https://www.zhihu.com/question/63383992/answer/222718972

2>解析文本数据(特征数据和标签数据)

    K-邻近分类是通过特征值近似,来确定标签的一种算法

3>将所有特征数据归一

    通过单个特征数据中,temp_value=max_value-min_value,然后用每一个特征值/temp_value,

    将所有的特征值变为0~1之间的数.

4>加权特征值

扫描二维码关注公众号,回复: 899995 查看本文章

    因为所有特征不可能是,完全相同地取影响最后的结果(标签).

5>测试当前加权特征值算法的错误率

6>反复(4.5)步可以得到一个在当前这个数据集中误差最小的加权值

7>投入使用


解析文本代码

def parse_file(filename):
    fr = open(filename)                             # 打开数据集文件
    array_lines = fr.readlines()                    # 读取所有文件,返回list
    # ['40920\t8.326976\t0.953952\t3\n', '14488\t7.153469\t1.673904\t2\n']
    lens = len(array_lines)                         # 得到行数
    feature_array = zeros((lens, 3))                # 得到一个lens*3的元素全为0ndarray
    labels = []                                     # 准备存放标签
    index = 0
    for line in array_lines:
        line = line.strip()
        # 1148 0.000000   0.332365   2
        # 10062    3.931299   0.487577   2 得到这样的数据
        list_line = line.split('\t')
        # ['14488', '7.153469', '1.673904', '2']
        # ['26052', '1.441871', '0.805124', '1']    得到这样的数据
        feature_array[index, :] = list_line[0:3]       # 将前面三列存入特征ndarray        labels.append(int(list_line[-1]))              # 将标签转为数字放入标签列表中
        index += 1
    return feature_array, labels

使用matplolib画二维散点图分析

def mymatplotlib():
    feature_array_mt, labels_mt = parse_file('datingTestSet2.txt')
    print(feature_array_mt)
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(feature_array_mt[:, 0], feature_array_mt[:, 1], 5 * array(labels_mt), 5 * array(labels_mt))
    plt.show()

归一化数据

def auto_normal(data):
    minvalues = data.min(0)     # 取得最小值
    maxvalues = data.max(0)     # 取得最大值
    ranges = maxvalues - minvalues
    m = data.shape[0]           # shape返回ndarry的维度,[0]为行数[1]为列数
    normal_data_a = data - tile(minvalues, (m, 1))
    normal_data_a = normal_data_a / tile(ranges, (m, 1))
    return normal_data_a, ranges, minvalues

加权函数

def addweight(data, i1, i2, i3):
    f1 = float(i1 / (i1 + i2 + i3))
    f2 = float(i2 / (i1 + i2 + i3))
    f3 = float(i3 / (i1 + i2 + i3))
    lens = data.shape[0]
    added_data = data * tile([f1, f2, f3], (lens, 1))
    return added_data

反复测试权值对当前数据分析的错误概率

def datatest():
    testmat, testlabel = parse_file('datingTestSet2.txt')
    normalmat, temp, minvalue = auto_normal(testmat)
    lenth = normalmat.shape[0]
    flag = True
    for i1 in range(1, 51):
        for i2 in range(1, 51):
            for i3 in range(1, 51):
                normalmat1 = addweight(normalmat, i1, i2, i3)
                error_count = 0
                for i in range(lenth):
                    result = distance(normalmat1[i, :], normalmat1, testlabel, 3)
                    if result != testlabel[i]:
                        error_count += 1
                if error_count < 18:
                    print(error_count)
                    error_rate = float(error_count / lenth)
                    print('the total error rate is :%f' % error_rate)
                    print('i1 = %d,i2 = %d,i3 = %d' % (i1, i2, i3))
                    flag = False
    if flag:
        print('不存在')
其中有一个核心算法也就是Knn的核心算法把特征转化为数值,根据被测试的特征来近似估计被测目标的标签
distance

def distance(in_x, data_set, label_d, k):       # 待测目标,数据集,标签集,和待测目标相近对象个数
    data_size = data_set.shape[0]               # 得到数据集的行数n
    diff_mat = tile(in_x, (data_size, 1)) - data_set    # 待测目标复制n行减去原数据集
    sq_diff_mat = diff_mat**2                   # 平方
    sq_distances = sq_diff_mat.sum(axis=1)      # 将所有距离加起来
    distances = sq_distances**0.5               # 开方
    sorted_dist = distances.argsort()           # 得到从小到大的索引列表
    class_count = {}
    for i in range(k):
        vote_ilabels = label_d[sorted_dist[i]]  # 最近K个对象的标签
        class_count[vote_ilabels] = class_count.get(vote_ilabels, 0)+1  # 统计个数
    sorted_class_count = sorted(class_count.items(), key=operator.itemgetter(1), reverse=True)  # 将字典排序
    return sorted_class_count[0][0]

写完这篇博客,结果还没跑完,电脑太差了,目前的结果

17.0
the
total
error
rate is: 0.017000
i1 = 7, i2 = 7, i3 = 1
17.0
the
total
error
rate is: 0.017000
i1 = 8, i2 = 31, i3 = 1
17.0
the
total
error
rate is: 0.017000
i1 = 8, i2 = 32, i3 = 1
17.0
the
total
error
rate is: 0.017000
i1 = 8, i2 = 33, i3 = 1
17.0
the
total
error
rate is: 0.017000
i1 = 8, i2 = 34, i3 = 1
17.0
the
total
error
rate is: 0.017000
i1 = 13, i2 = 13, i3 = 2
17.0
the
total
error
rate is: 0.017000
i1 = 14, i2 = 13, i3 = 2
17.0
the
total
error
rate is: 0.017000
i1 = 14, i2 = 14, i3 = 2

1000次错误17次

后面就可以使用这些加权值来设定算法

测试函数

def person_test():
    result_list = ['not at all', 'in small doses', 'in large doses']
    game_times = float(input('Percentage of game time played ?'))
    fly_miles = float(input('Number of frequent flyer miles per year?'))
    ice_cream = float(input('How many ice cream a week do you eat?'))
    testmat_p, testlabel_p = parse_file('datingTestSet2.txt')
    normal_data, temp, min_value_p = auto_normal(testmat_p)
    final_data = addweight(normal_data, 8, 31, 1)
    person_data = array([game_times, fly_miles, ice_cream])
    result = distance((person_data - min_value_p) / temp, final_data, testlabel_p, 3)
    print('you will probably like this person: ', result_list[result-1])

这个太简单了,上面的8,31,1都是刚刚跑出来的加权随便选的一个.

43757   7.882601   1.332446   3
11145   3.410627   0.631838   2

猜你喜欢

转载自blog.csdn.net/chirszzz1/article/details/80324615