機械学習シリーズ2 |ネイバー分類アルゴリズム最寄りのk

1概要

K-最近傍アルゴリズムは、異なる分類の特性値との間の距離を測定する方法を使用します。

2つの長所と短所

利点:高い精度、データの入力がないと仮定すると、外れ値の影響を受けません

デメリット:計算の複雑さ、空間的な複雑さが高い、モデルに保存することはできません

該当するデータ範囲:数値と名目タイプ

3データ準備

3.1データの準備

ベクターは、テストされます。私たちは、データを予測したいです

ターゲットベクトルが含まれていない特性データセットのトレーニングデータセット

(ベクター標的可変組成物)からなるベクトルラベル

kは、我々は20以下、一般的に、同様の数の前に探しているものです

3.2データ削減

前回の記事では、式を次のように簡単正規化を提供し、正規化について話しました:

new_value=(old_value-min)/(max-min)
 
old_value:原来的值
min:在数据集中该特征最小的值
max:在数据集中该特征最大的值

那我们看看如何用代码进行实现这个归一化吧。
import numpy
class Normalization(object):
    def auto_norm(self, matrix):
        """
        数据清洗,归一化
        new_value=(old_value-min)/(max-min)
        :param matrix: 矩阵
        :return: 归一化的矩阵,范围数据,最小值
        """
        # 0表示从列中选值
        # 每列的最小值组成一个向量
        min_value = matrix.min(0)
        # 每列的最大值组成一个向量
        max_value = matrix.max(0)
        # 每列的范围值
        ranges = max_value - min_value
 
        m = matrix.shape[0]
        norm_matrix = numpy.zeros(numpy.shape(matrix))
        # 分子
        norm_matrix = matrix - numpy.tile(min_value, (m, 1))
        # 不是矩阵除法,矩阵除法是linalg.solve(matA,matB)
        norm_matrix = norm_matrix / numpy.tile(ranges, (m, 1))
 
        return norm_matrix, ranges, min_value

原則4

4.1アルゴリズム

上記で調製したデータは、前記
新たなデータを入力し、新しいデータをマトリクスとしてトレーニングデータセットにコピーされ、訓練データベクトルの各セットは、ユークリッド距離を算出する
算出されたユークリッド距離データ(昇順にソートされますヨーロッパの数値)、より類似小さい距離は、からなるインデックス付き位置のアレイ取得
キーとして、最初のk個のデータ・タグ(目的変数)を採取最初のk個のインデックス位置のを、次いで、カウント値が蓄積され
、その後このカウントマップは、ソートのための値降順にソートし
、最初のランクの最後のデータを取得したデータをと最も類似した
4.2ユークリッド距離

次の式は、私たちがここに単に変数の下を意味している、非常に簡単です。
例えば、我々は、次に、データ特性のセットが5である持っている
場合のように、デジタルポーリングまでの時間であり、N 5、1,2,3,4,5 Iの順である:私は

nは、最大数である5

Σ:記号の意味は、私は〜nは式に、iの各値に対して式を計算後の合計値の合計です

XI:私たちは、x2は第二の特徴を表して、私は1,2,3,4,5、それぞれ、それが第一の特徴のX1を表します知っています、...

YI:共感とXI

5コード

import operator
 
from numpy import *
 
class kNN(object):
 
    def createDataSet(self):
        """
        创建测试数据集
        :return:矩阵,标签
        """
        group = numpy.array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
        labels = ['A', 'A', 'B', 'B']
        return group, labels
        
    def classify0(self, inX, dataSet, labels, k):
        """
        k-近邻,欧式距离计算两个向量的距离
        :param inX: 输入向量
        :param dataSet: 训练样本集
        :param labels: 标签向量
        :param k: 最近邻居的数目
        :return: 最近的结果
        """
 
        # 计算欧式距离
 
        # 获得行数
        dataSetSize = dataSet.shape[0]
 
        # 将向量inx纵向复制变成矩阵跟dataSet的数量一样,再减去数据集
        diffMat = tile(inX, (dataSetSize, 1)) - dataSet
 
        # 矩阵平方
        sqDiffMat = diffMat ** 2
 
        # 矩阵每行求和
        sqDIstances = sqDiffMat.sum(axis=1)
 
        # 数组每个值开方
        distances = sqDIstances ** 0.5
 
        # 数组值从小到大的索引号
        sortedDistIndicies = distances.argsort()
 
        # 选最距离最小的k个距离
        classCount = {}
        for i in range(k):
            # 通过索引值获取标签
            voteIlabel = labels[sortedDistIndicies[i]]
            # 累加次数
            classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
 
        # 根据次数从大到小排序
        sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
        return sortedClassCount[0][0]
 
 
if __name__ == '__main__':
    kNN = kNN()
    group, labesl = kNN.createDataSet()
    result = kNN.classify0([0, 0], group, labesl, 3)
    print(result)

上記のコードの結果は、あなたがそれを読んでください、B!シンプルなコードです。

6戦闘

上記の簡単な計算の後、だけでなく、私たちの本当のプロジェクトに。以下は、単純な小さなプロジェクトに手書き文字認識システム、権利を計算します!
6.1データの準備
まず、我々のデータは、私のgithubのを介してダウンロードすることができます!I・ポイント・数字は、我々がする必要がディレクトリデータに保存されています!
6.2製造アルゴリズム

まず、我々はプログラムを書き、?それを通過する手順どのような
データを表示し、データがどのような外観に似ていますか?データが離散することを特徴とする方法

データ行列の複数に書き込み機能の変換アルゴリズム、単一のベクターにデータ、

入力テストベクトル、テストアルゴリズムモデルの精度!

import numpy
import operator
from numpy import *
 
class kNN(object):
    def img2vector(self, filename):
        """
        图片txt转向量
        :param filename: 文件名
        :return: 向量
        """
        # 创建一个1024维度的向量
        return_vec = numpy.zeros((1, 1024))
 
        # 将数据导入到向量
        with open(filename) as fr:
            for i in range(32):
                line = fr.readline()
                # 导入一行数据(32个数字)
                for j in range(32):
                    # 每个数字依次导入
                    return_vec[0, i * 32 + j] = int(line[j])
        return return_vec
        
    def classify0(self, inX, dataSet, labels, k):
        """
        k-近邻,欧式距离计算两个向量的距离
        :param inX: 输入向量
        :param dataSet: 训练样本集
        :param labels: 标签向量
        :param k: 最近邻居的数目
        :return: 最近的结果
        """
 
        # 计算欧式距离
 
        # 获得行数
        dataSetSize = dataSet.shape[0]
 
        # 将向量inx纵向复制变成矩阵跟dataSet的数量一样,再减去数据集
        diffMat = tile(inX, (dataSetSize, 1)) - dataSet
 
        # 矩阵平方
        sqDiffMat = diffMat ** 2
 
        # 矩阵每行求和
        sqDIstances = sqDiffMat.sum(axis=1)
 
        # 数组每个值开方
        distances = sqDIstances ** 0.5
 
        # 数组值从小到大的索引号
        sortedDistIndicies = distances.argsort()
 
        # 选最距离最小的k个距离
        classCount = {}
        for i in range(k):
            # 通过索引值获取标签
            voteIlabel = labels[sortedDistIndicies[i]]
            # 累加次数
            classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
 
        # 根据次数从大到小排序
        sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
        return sortedClassCount[0][0]
        
    def handle_write_class_test(self, train_data_dirname, test_data_dirname):
 
        # 加载训练集
        labels = []
        train_file_list = os.listdir(train_data_dirname)
        train_data_count = len(train_file_list)
        matrix = numpy.zeros((train_data_count, 1024))
        for i in range(train_data_count):
            file_name_ext = train_file_list[i]
            file_name = file_name_ext.split(".")[0]
            file_num = int(file_name.split("_")[0])
            labels.append(file_num)
            matrix[i, :] = self.img2vector("%s/%s" % (train_data_dirname, file_name_ext))
 
        # 加载测试集
        test_file_list = os.listdir(test_data_dirname)
        err_count = 0.0
        test_data_count = len(test_file_list)
        for i in range(test_data_count):
            file_name_ext = test_file_list[i]
            file_name = file_name_ext.split(".")[0]
            file_num = int(file_name.split("_")[0])
            test_vec = self.img2vector("%s/%s" % (test_data_dirname, file_name_ext))
 
            # 测试
            result = self.classify0(test_vec, matrix, labels, 3)
            bool_result = result == file_num
            if not bool_result:
                err_count = err_count + 1.0
            print("result:%s, real:%d, bool:%s" % (result, file_num, bool_result))
 
        print("error count:%f" % (err_count / float(test_data_count)))
 
 
if __name__ == '__main__':
    train_dir = "../data/digits/trainingDigits"
    test_dir = "../data/digits/testDigits"
    kNN = kNN_2_3_2()
    kNN.handle_write_class_test(train_dir, test_dir)

最後に、我々は次のような結果を得るため、エラー率が1.2%にほぼ等しい、結果は良いでした!

result:0, real:0, bool:True
result:0, real:0, bool:True
result:4, real:4, bool:True
result:9, real:9, bool:True
result:7, real:7, bool:True
result:7, real:7, bool:True
result:1, real:1, bool:True
result:5, real:5, bool:True
result:4, real:4, bool:True
result:3, real:3, bool:True
result:3, real:3, bool:True
error count:0.011628
公開された38元の記事 ウォンの賞賛1 ビュー2196

おすすめ

転載: blog.csdn.net/wulishinian/article/details/104711726
おすすめ