Python 3:『機械学習実戦』のk近隣アルゴリズム(3)手書き数字の識別


Python 3:『機械学習実戦』のk近隣アルゴリズム(3)手書き数字の識別
  • 転載作者と出典を明記してください:http://blog.csdn.net/u011475210
  • コードアドレス:https://github.com/WordZzzz/ML/tree/master/Ch02
  • オペレーティングシステム:WINDOWS 10
  • ソフトウェアバージョン:python-3.6.2-amd 64
  • 編  者:WordZzzz
  • Python 3機械学習実戦のk近隣アルゴリズム3手書き数字を識別
  • 前言
  • 準備データ
  • 二試験アルゴリズム
  • 三k近隣アルゴリズム総括

  • 前言:
    この博文では、本スラグはk-近隣分類器を用いた手書き識別システムを一歩一歩構築する.図に示すように、0から9までのデータセットが提供されています.
    Python3:《机器学习实战》之k近邻算法(3)识别手写数字_第1张图片
    これらの数字はすでに処理されており、32画素*32画素の白黒画像(テキストフォーマット)に統一されている.
    次に、アルゴリズムの流れを示します.
  • (1)データ収集:テキストファイルを提供します.
  • (2)データの準備:関数img 2 vector()を記述し、画像フォーマットをまだ分類器の実用的なベクトルフォーマットに組み込む.
  • (3)分析データ:Pythonコマンドプロンプトでデータを消去し、要求に合致することを確認します.
  • (4)トレーニングアルゴリズム:このステップはk近隣アルゴリズムには適用されません.
  • (5)テストアルゴリズム:作成関数は、提供されたデータセットの一部をテストサンプルとして使用し、テストサンプルと非テストサンプルの違いは、テストサンプルが分類済みのデータであり、予測分類が実際のカテゴリと異なる場合、エラーとしてマークされる.
  • (6)アルゴリズムを使う:アプリケーションを書く精力がなくて、振り回される大神たちは試して、自分で後で復習する時にこれを書くことができます.主に画像から数字を抽出し、デジタル認識を完了する.

  • 一、データの準備:
      世紀画像はソースコードの2つのサブディレクトリに格納されている:ディレクトリtrainingDigitsには約2000の例が含まれており、各例の内容は下図のように、各数字には約200のサンプルがある.ディレクトリtestDigitsには、約900のテストデータが含まれています.2組のデータは重複していない.
    Python3:《机器学习实战》之k近邻算法(3)识别手写数字_第2张图片
    まず、画像をテストベクトルに変換する必要があります.すなわち、32*32の画像情報を1*1024のNumPy配列で格納します.
    コード実装:
    # -*- coding: UTF-8 -*-
    """
    Created on Aug 18, 2017
    kNN: k Nearest Neighbors
    
    Input:      inX: vector to compare to existing dataset (1xN)
                dataSet: size m data set of known vectors (NxM)
                labels: data set labels (1xM vector)
                k: number of neighbors to use for comparison (should be an odd number)
    
    Output:     the most popular class label
    
    @author: wordzzzz
    """
    
    from numpy import *
    import operator
    from os import listdir
    def img2vector(filename):
        """
        Function:   32*32     1*1024  
    
        Args:       filename:       
    
        Returns:    returnVect:     1*1024  
        """ 
        #       1*1024  
        returnVect = zeros((1, 1024))
        #    
        fr = open(filename)
        #      
        for i in range(32):
            #        32 
            lineStr = fr.readline()
            for j in range(32):
                #     32             
                returnVect[0, 32*i+j] = int(lineStr[j])
        #      1*1024  
        return returnVect

    出力結果:
    >>> reload(kNN)
    
    >>> testVector = kNN.img2vector('testDigits/0_13.txt')
    >>> testVector[0,0:31]
    array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
            0.,  1.,  1.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
            0.,  0.,  0.,  0.,  0.])
    >>> testVector[0,32:63]
    array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,
            1.,  1.,  1.,  1.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
            0.,  0.,  0.,  0.,  0.])

    二、テストアルゴリズム:
    前のkNN.pyコードにfrom os import listdirを追加し、次のテストプログラムを作成してアルゴリズムをテストします.
    def handwritingClassTest():
        """
        Function:           
    
        Args:        
    
        Returns:    returnVect:     1*1024  
        """ 
        #           
        hwLabels = []
        #        
        trainingFileList = listdir('trainingDigits')
        #        
        m = len(trainingFileList)
        #       
        trainingMat = zeros((m,1024))
        #       
        for i in range(m):
            #           
            fileNameStr = trainingFileList[i]
            fileStr = fileNameStr.split('.')[0]
            classNumStr = int(fileStr.split('_')[0])
            #              
            hwLabels.append(classNumStr)
            #    
            trainingMat[i, :] = img2vector('trainingDigits/%s' % fileNameStr)
        #        
        testFileList = listdir('testDigits')
        #       
        errorCount = 0.0
        #        
        mTest = len(testFileList)
        #    
        for i in range(mTest):
            #           
            fileNameStr = testFileList[i]
            fileStr = fileNameStr.split('.')[0]
            classNumStr = int(fileStr.split('_')[0])
            #    
            vectorUnderTest = img2vector('trainingDigits/%s' % fileNameStr)
            #           
            classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)
            #             
            print("the classifier came back with: %d, the real answer is: %d" %(classifierResult, classNumStr))
            #             ,      
            if (classifierResult != classNumStr): errorCount += 1.0
        #      
        print("
    the total number of errors is: %d"
    % errorCount) # print("
    the total error rate is: %f"
    % (errorCount/float(mTest)))

    出力結果:
    >>> reload(kNN)
    
    >>> kNN.handwritingClassTest()
    the classifier came back with: 0, the real answer is: 0
    the classifier came back with: 0, the real answer is: 0
    the classifier came back with: 0, the real answer is: 0
    ······
    the classifier came back with: 9, the real answer is: 9
    the classifier came back with: 9, the real answer is: 9
    the classifier came back with: 9, the real answer is: 9
    
    the total number of errors is: 13
    
    the total error rate is: 0.013742

     k−近隣アルゴリズムは手書きデジタルデータセットを識別し,誤り率は1.2%であった.分類アルゴリズム、データセット、プログラム設定に依存して、分類器の出力結果が大きく異なる場合があります.変数hoRatioと変数kの数値を自分で修正して、検出エラー率が変化するかどうかを確認することができます.
    このアルゴリズムを実際に使用する場合,アルゴリズムの実行効率は高くない.アルゴリズムは各テストベクトルに対して2000回の距離計算を行う必要があるため、各距離計算は1024次元浮動小数点演算を含み、合計900回実行され、また、テストベクトルに2 MBの記憶空間を用意する必要がある.後で話すk決定木科は大量の計算コストを節約する.
    三、k-近隣アルゴリズムのまとめ:
    メリット:
  • k−近隣アルゴリズムは分類データの最も簡単で有効なアルゴリズムであり,インスタンスに基づく学習であり,アルゴリズムを使用する際には実際のデータに近い訓練サンプルデータが必要である.

  • 欠点:
  • k−近隣アルゴリズムは、すべてのデータセットを保存し、データセットの各データに対して距離値を計算し、実際の使用時間と消費時間を記憶しなければならない.
  • さらに、データのインフラストラクチャ情報を与えることができないため、平均インスタンスサンプルと典型的なインスタンスサンプルがどのような特徴を有するか(確率測定法が分類問題を処理する際にこの問題を解決できる)については知らない.

  • シリーズチュートリアル継続リリース中、購読、注目、コレクション、コメント、いいね~( ̄▽ ̄)~
    完の汪(′▽`▽`)。。。zz