機械学習入門--KNNアルゴリズム

12281 ワード

新しい学習の道のり
前のブログは主にAndroidとNodejsについての開発と学習ノートです.一時期の勉強と実習を経て、いくつかの大手工場のOfferをもらいました.心を痛めて、大学四年生の大学院受験に参加することを決心しました.今は大学院受験に成功して、引き続き新しい学習を始めます.主流の本や論文は英語で書かれているので、これから英語で勉強の記録を書いてもいいです.個人的にはマシン学習に関する学習経験はありませんでしたが、今もfrom 0 to nです.
プロジェクトソースコード
このシリーズは全部このプロジェクトに入れるつもりです.言語はPythonで、即時更新します.スターを注文したいです.
https://github.com/CallMeSp/MachineLearning
本文
機械学習開発は大体一定の手順に従います.
  • 収集データ
  • 入力データ
  • を準備します.
  • 入力データを解析する
  • トレーニングアルゴリズム(無監督学習は不要)
  • テストアルゴリズム
  • アルゴリズムを使用する
  • .
    機械学習界にはいわゆる「十大アルゴリズム」または「二十大アルゴリズム」があります.今日持ってきたのは最も簡単な一つです.k-近隣アルゴリズムです.
    動作原理は簡単です.サンプルデータのセットがあり、トレーニングサンプルセットとも呼ばれ、各データにラベルがあります.つまり、サンプルセットの各データと所属分類の対応関係を知っています.ラベルがない新しいデータを入力した後、新しいデータの各特徴をサンプル集中データに対応する特徴と比較し、アルゴリズムでサンプル集中特徴が最も似ている分類ラベルを抽出する.一般的には、サンプルデータの集合前のk個の最も似たデータだけを選択します.これはk-近隣アルゴリズムのkの出所です.KNNと略称します.
    kNNの優劣:
    優勢
    劣勢
    精度が高く、異常値に敏感でない
    計算の複雑さが高い
    データ入力なしの仮定
    空間複雑度が高い
    アルゴリズム:
    def classify0(inX,dataSet,labels,k):
        dataSetSize=dataSet.shape[0]
        #[0] [1]        
        diffMat = tile(inX,(dataSetSize,1))-dataSet
        sqDiffMat=diffMat**2
        sqDistances=sqDiffMat.sum(axis=1)
        #axis=0      
        distances=sqDistances**0.5
        sortedDistIndicies=distances.argsort()
        #                
        classcount={}
        for i in range(k):
            #       k  
            vl=labels[sortedDistIndicies[i]]
            classcount[vl]=classcount.get(vl,0)+1
        sortedclasscount = sorted(classcount.iteritems(),key=operator.itemgetter(1),reverse=True)
        #     k            
        return sortedclasscount[0][0]
    正規化の特徴値
    このような処理は、同等の重みの特徴が範囲の差が大きいため、ある特徴が計算結果に大きな影響を与えることを防止するものであるので、全ての特徴値を0〜1の間に変換して重みが同じであることを保証し、コードを参照してください.
    def autoNorm(dataSet):
        minvals=dataSet.min(0)
        maxvals=dataSet.max(0)
        ranges=maxvals-minvals
        normDataSet=zeros(shape(dataSet))
        m=dataSet.shape[0]
        normDataSet=dataSet-tile(minvals,(m,1))
        normDataSet=normDataSet/tile(ranges,(m,1))
        return normDataSet,ranges,minvals
    サンプル
    環境:linux+Python 2.7テスト用例:gihbリンクに本demoが参照している「Machine Learning inアクション」があります.
    from numpy import *
    import operator
    import matplotlib
    import matplotlib.pyplot as plt
    from os import listdir
    
    #  ,inX      ,dataSet          ,labels       ,k kNN    k,
    def classify0(inX,dataSet,labels,k):
        dataSetSize=dataSet.shape[0]
        diffMat = tile(inX,(dataSetSize,1))-dataSet
        sqDiffMat=diffMat**2
        sqDistances=sqDiffMat.sum(axis=1)
        distances=sqDistances**0.5
        sortedDistIndicies=distances.argsort()
        classcount={}
        for i in range(k):
            vl=labels[sortedDistIndicies[i]]
            classcount[vl]=classcount.get(vl,0)+1
        sortedclasscount = sorted(classcount.iteritems(),key=operator.itemgetter(1),reverse=True)
        return sortedclasscount[0][0]
    
    #          ,        ,       txt     。
    def file2Matrix(filename):
        fr=open(filename)
        arraylines=fr.readlines()
        numberOfLines=len(arraylines)
        returnMat=zeros((numberOfLines,3))
        classLabelVector=[]
        index=0
        for line in arraylines:
            line=line.strip()
            listFromLine=line.split('\t')
            returnMat[index,:]=listFromLine[0:3]
            classLabelVector.append(listFromLine[-1])
            index+=1
        return returnMat,classLabelVector
    
    #  matplotlib  
    def draw():
        datas, labels = file2Matrix('datingTestSet2.txt')
        fig = plt.figure()
        ax = fig.add_subplot(111)
        ax.scatter(datas[:, 1], datas[:, 2], 15.0 * array(map(int,labels)), 15.0 * array(map(int,labels)))
        plt.show()
    
    #   
    def autoNorm(dataSet):
        minvals=dataSet.min(0)
        maxvals=dataSet.max(0)
        ranges=maxvals-minvals
        normDataSet=zeros(shape(dataSet))
        m=dataSet.shape[0]
        normDataSet=dataSet-tile(minvals,(m,1))
        normDataSet=normDataSet/tile(ranges,(m,1))
        return normDataSet,ranges,minvals
    
    # demo         
    def normalization():
        dataSet,labels=file2Matrix('datingTestSet2.txt')
        normMat,ranges,minvals=autoNorm(dataSet)
        print normMat
        print ranges
        print minvals
    
    #      ,     
    def datingClassTest():
        # 10%        , 90%       
        hoRatio=0.10
        dataSet,labels=file2Matrix('datingTestSet.txt')
        normMat,ranges,minvals=autoNorm(dataSet)
        m=normMat.shape[0]
        numTestVecs=int(m*hoRatio)
        errorCount=0.0
        for i in range(numTestVecs):
            classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],labels[numTestVecs:m],3)
            print "the classifier came back with  : %s,the real answer is : %s"%(classifierResult,labels[i])
            if(classifierResult != labels[i]):
                    errorCount+=1
        print "errorCount = %d"%(errorCount)
        print "the total error rate is %f"%(errorCount/float(numTestVecs))
    
    # 32*32       1*1024
    def img2Vector(filename):
        returnVect=zeros((1,1024))
        fr=open(filename)
        for i in range(32):
            lineStr=fr.readline()
            for j in range(32):
                returnVect[0,32*i+j]=int(lineStr[j])
        return returnVect
    
    #       
    def handwritingClassTest():
        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('testDigits/%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))
    実戦
    次にpython爬虫類を書いて、テストケースを取得して、その後、kNNアルゴリズムによっていくつかのテストを行うつもりです.
    to be continued