KNNアルゴリズム実践後のまとめ

5188 ワード

質問の簡単な説明:私は1組のデータを持っていて、データ量は500余りで、次元は30で、分類は2種類あって、knnアルゴリズムを使ってデータに対して予測を行います.
一、疑似コード
(1)プロセス全体の疑似コード
Begin:
    Input:データセットdatasets,k値配列;
 
Do:
Datasetsを正規化し、7:3の割合でトレーニングセットとテストセットに分割します.
訓練セットのデータを用いて,k折交差検証に基づいて最適k値を取得する
k値を決定した後、knnアルゴリズムを用いてテストセットのデータを予測する
 
    Output:テストセットの各データが属するカテゴリ.
End
 
(2)knnアルゴリズム擬似コード
Begin:
Input:データセットa,測定対象データb,k
 
Do:
bとaのすべての点のオーステナイト距離を測定し,距離に基づいて近から遠まで配列したリストリストリストリストを得,その中の前のk要素を返す
k個の要素のラベルを分析し,各種のラベルの数を得たが,投票法によれば,最大数のラベルがbのラベルである.
Output:bのラベル
二、knnアルゴリズム
       動作原理:サンプル・データのセットであり、サンプル・セットの各データにラベルが存在します.すなわち、サンプル・セットの各データと所属分類との関係を知っています.ラベルのないデータを入力した後、新しいデータの各特徴をサンプルセットデータに対応する特徴と比較し、サンプルセット特徴が最も類似しているデータ(近隣)の分類ラベルを抽出する.一般に,試料データセットの前のk個の最も類似したデータのみを選択し,これがk近傍アルゴリズムにおけるkの出所であり,通常kは20未満の整数である.最後に,k個の最も類似したデータの中で最も出現回数の多い分類を新しいデータの分類として選択した.Knnアルゴリズムは怠惰な学習に属し、事前に訓練するのではなく、使用時に訓練する.
三、データの処理
1、データの前処理
(1)データ正規化
       データに複数のフィーチャーが存在する場合、いくつかのフィーチャーの数が大きい場合、他の小さい場合の最後の分類結果は、各フィーチャーのアウトラインが異なるため、データを正規化する必要があるため、他のフィーチャーの影響を弱めます.私が採用したのは離差標準化で、元のデータに対する線形変換で、結果を[0,1]区間に落とす.(2)データのランダム化
       元のデータの不合理なソートは、最後にフィットした問題を引き起こす可能性があるため、訓練とテストの前にランダム化しなければなりません.random.shuffle()メソッドを使用してランダム化します.
四、クロス検証kの最適値を得る
       K値は本実験において極めて重要であり,kの値は予測の正確性に直接影響を及ぼす.では、最適k値をどのように取りますか?
       k折交差検証法を用いて,データセットなどをいくつかの部分に分け,各部分を試験セットと訓練セットとして順番に用いた.各k値は複数回予測され,予測結果の正解率は平均値をとることで基本的にこのk値を用いた予測効率を表す.
五、予測を行う
       各予測の精度は必ずしも同じではないが,変動は大きくなく,これは正常な現象である.
六、考える
       符号化の過程で、いくつかの問題や改善が必要な点を考えました.1つは、データの次元ダウンの問題で、次元数が多すぎて次元災害が発生する可能性があります.では、次元がどれだけに達したかで次元ダウンが必要です(今回は次元ダウンはありません).二つ目は投票法の問題であり,二つのラベルの訓練データ量の差が大きい場合,単純に投票法を用いると誤ったラベルが得られる可能性が高く,重み付けを考慮すべきである.第3点は第2点と一定のつながりがあり、2つのラベルのデータ量の差が大きい場合、どのようにフィッティングを避けるかということです.
主なモジュールには、呼び出しが必要なさまざまな方法が含まれています.
from re import sub
from os import listdir
from collections import Counter
from itertools import chain
import jieba
import PIL.Image as im
from sklearn.naive_bayes import MultinomialNB
from wordcloud import WordCloud
from scipy.misc import imread
import numpy as np
import matplotlib.pyplot as plt


#         
#          ,           
allWords = []
def getWordsFromFile(filePath):
    words = []
    with open(filePath,encoding='utf8') as f:
        for line in f:
            #            (     )     。
            line = line.strip()
            #           
            line = sub(r'[.【】0-9、-。,!~\*]', '', line)
            #  
            line = jieba.cut(line)
            #     1  
            line = filter(lambda word:len(word)>1,line)
            #          words   ,      append
            words.extend(line)
    return words

def getTopNWords(topN):
    #                       
    #          txtfiles   
    txtfiles = [str(i)+'.txt' for i in  range(151)]
    for txtFile in txtfiles:
        allWords.append(getWordsFromFile('C:/Users/gh/Desktop/mails/'+txtFile))
    #      
    #         
    freq = Counter(chain(*allWords))
    #freq.most_common(topN)  freq         topN 
    print(freq.most_common(topN))
    return [w[0] for w in freq.most_common(topN)]

#               400   
topWords = getTopNWords(400)

#       ,          
#      , 400                 
vector = []
for words in allWords:
    temp = list(map(lambda x:words.count(x), topWords))
    vector.append(temp)
vector = np.array(vector)
#    ,1      ,0      
labels = np.array([1]*127 + [0]*24)
#    ,           
model = MultinomialNB()
model.fit(vector, labels)

def predict(txtFlie):
    #          ,      
    words = getWordsFromFile(txtFlie)
    currentVector = np.array(tuple(map(lambda x:words.count(x),topWords)))
    result = model.predict(currentVector.reshape(1,-1))
    return '    ' if result == 1 else '    '

pic=np.array(im.open(r'C:/Users/gh/Desktop/map.jpg'))
#          
wc = WordCloud(font_path=r'C:/Windows/Fonts/STZHONGS.TTF',mask = pic ,background_color="white",max_words=1000,max_font_size=300,
              width=3000,height=3000).generate_from_frequencies(Counter(chain(*allWords)))
##  matplotlib pyplot          .
# plt.show(wc)
##            
wc.to_file('C:/Users/gh/Desktop/wordsCloud.png')
print('    '+predict('C:/Users/gh/Desktop/mails/151.txt'))

メソッドの呼び出し:
import knn
import numpy as np
crudeData = r'C:/Users/gh/Desktop/wbcd.txt'
prediction = []
right = 0
#     
datasets = knn.normalize(crudeData)
#              
dataset = datasets[0:len(datasets)*7//10]
predictDatas = datasets[len(dataset):]
#   k 
results = knn.compareK([3, 5, 7, 9,11], datasets)
print(results)
#      k  3      

#     
for i in range(len(predictDatas)):
    neighbor = knn.findKNeighbors(3, predictDatas[i], dataset)
    prediction = knn.getLabel(neighbor)
    if prediction == predictDatas[i][1]:
        right +=1
    print("ID ", int(predictDatas[i][0]), "        :", chr(int(prediction)), "     :", chr(int(predictDatas[i][1])))
print("     :", len(predictDatas), " ,    :", right/len(predictDatas))