Klasik pratik durum: El yazısıyla yazılmış rakam tanımayı gerçekleştirmek için makine öğrenimi KNN algoritmasını kullanma | Kuvvet Projesi

Yazar | Toffee Cat

Kaynak | CSDN blogu, sorumlu editör | Xi Yan

Baş resmi | Visual China'dan CSDN indirmesi

Üretildi | CSDN (ID: CSDNnews)

Algoritmaya Giriş

El yazısıyla yazılan rakam tanıma, KNN algoritmasının özellikle klasik bir örneğidir. Veri kaynaklarını elde etmenin iki yolu vardır, biri MNIST veri setinden ve diğeri UCI Irvine Üniversitesi Makine Öğrenimi Deposundan indirilir. misal.

Temel fikir, aşağıda gösterildiği gibi 32x32'lik bir ikili matriste hangi sayının 0-9 arasında olduğunu anlamak için KNN algoritmasını kullanmaktır.

Veri seti, biri toplam 1934 veri içeren eğitim veri seti, diğeri ise toplam 946 veri içeren test veri seti olmak üzere iki bölümden oluşmaktadır. 5. 55_56.txt numaralı 56. örnek gibi tüm veri isimlendirme formatları tek tiptir Bu, örneğin gerçek etiketinin çıkarılmasını kolaylaştırmak için yapılır.

Ayrıca iki veri formatı vardır, biri yukarıdaki resimdeki gibi 0 ve 1'den oluşan bir metin dosyasıdır; diğeri ise görüntüyü yukarıdaki resimle aynı formata dönüştürmek için biraz işlem gerektiren el yazısı dijital bir resimdir ve aşağıdakilerin tümü Giriş.

Algoritma adımları

  • Veri toplayın: veri kaynaklarını açın

  • Verileri analiz edin ve nasıl işleneceğini öğrenin

  • Eğitim verilerini içe aktarın ve yapılandırılmış bir veri biçimine dönüştürün

  • Mesafeyi hesapla (Öklid mesafesi)

  • Test verilerini içe aktarın ve model doğruluğunu hesaplayın

  • El yazısı sayılar, pratik uygulama modeli

  • Tüm veriler 0 ve 1'den oluştuğu için veri standardizasyonuna ve normalleştirmeye gerek yoktur.

    Algoritma uygulaması

    Veri işleme

    İki örnek arasındaki mesafeyi hesaplarken, her özniteliğin bire bir karşılığı vardır, bu nedenle burada 32x32 dijital matris, örnekler arasındaki mesafenin hesaplanmasını kolaylaştırmak için 1x1024 dijital matrise dönüştürülür.

    1 # Metin dosyalarını işleme 2def img_deal (dosya): 3 # 1 * 1024 tek boyutlu sıfır matrisi oluşturun 4 the_matrix = np.zeros ((1,1024)) 5 fb = açık (dosya) Aralıktaki i için 6 (32): 7 # satır satır okumak 8 lineStr = fb.readline (32) aralığında j için 9: 10 # 32 * 32 = 1024 öğeyi tek boyutlu sıfır matrisine atayın 11 the_matrix = int (lineStr) 12 matrisi döndür

    Öklid mesafesini hesapla

    Numpy, tek boyutlu bir matrisi birkaç kez yatay ve birkaç kez dikey olarak kopyalayabilen bir karo yöntemine sahiptir; bu nedenle, bir test verisi karo yöntemiyle işlendikten sonra, yeni bir matris elde etmek için eğitim verileri çıkarılır ve ardından matrisin her biri Veri (yatay) kareler eklendikten ve kök açıldıktan sonra, test verileri ile her bir eğitim verisi arasındaki mesafe elde edilebilir.

    Bir sonraki adım, tüm mesafeleri artan sırada sıralamak, en üstteki K'yi ve bu aralıkta her sayı kategorisinin numarasını almak ve daha sık görünen numara kategorisinin etiketini döndürmektir.

    1def sınıflandırması (test_data, train_data, etiket, k): 2 Boyut = train_data.shape 3 # Her bir test verisi satırını kopyalayın Zamanları eksi egzersiz verilerini boyutlandırın, Boyutları yatay olarak kopyalayın ve dikey olarak 1 kez kopyalayın 4 the_matrix = np.tile (test_data, (Size, 1)) - train_data 5 # çıkarma sonucunun karesi 6 sq_the_matrix = the_matrix ** 27 # karelerin toplamı, eksen = 1 yatay temsil eder 8 all_the_matrix = sq_the_matrix.sum (axis = 1) 9 # Sonuç son mesafeyi elde etmek için kök numarasını açın 10 mesafe = all_the_matrix ** 0.511 # Mesafeyi küçükten büyüğe sıralayın ve sonucu dizin olarak verin 12 sort_distance = distance.argsort 13 dis_Dict = {} 14 # İlk k'yi alın (K) aralığında i için 15: 16 # İlk K etiketlerini alın 17 the_label = etiket 18 # Etiketin anahtarını ve değerini sözlüğe aktarın 19 dis_Dict = dis_Dict.get (the_label, 0) +120 # Sözlüğü değerin boyutuna göre, büyükten küçüğe, yani K aralığında sıralayın, en sık kullanılan etiketleri filtreleyin 21 sort_Count = sıralanmış (dis_Dict.items, key = operator.itemgetter (1), reverse = True) 22 # En sık kullanılan etikete geri dönün 23 return sort_Count

    Test veri seti uygulaması

    Öncelikle eğitim veri setinin işlenmesi gerekir. Listdir yöntemi, bir klasördeki tüm dosyaları döndürmek ve ardından satır ve 1024 sütun sayısı ile eğitim veri setindeki her verinin gerçek etiketini içeren bir eğitim veri matrisi oluşturmaktır. Kesme ekstraksiyonu etiketler listesinde saklanır, yani sınıflandırma fonksiyonunda geçirilen etiket mesafeden hesaplanır.

    1 etiket = 2 # listdir yöntemi, bir klasörde bulunan dosyaları döndürmektir 3 train_data = listdir ('trainingDigits') 4 # Klasördeki dosya sayısını alın 5 m_train = len (train_data) 6 # Sütun numarası train_matrix ve satır 1024 olan bir sıfır matrisi oluşturun 7 tren_matrix = np.zeros ((m_train, 1024)) Aralıktaki i için 8 (m_train): 9 file_name_str = train_data 10 file_str = dosya_adı_str.split ('.') 11 # eğitim setindeki her verinin gerçek etiketini kesin 12 dosya_num = int (dosya_dizi.split ('_')) 13 labels.append (dosya_numarası) 14 # Eğitim veri kümesindeki tüm verileri train_matrix'e aktarın 15 train_matrix = img_deal ('trainingDigits /% s'% file_name_str)

    Daha sonra test eğitim veri seti yukarıdaki ile aynı şekilde işlenir ve test veri matrisi TestClassify, eğitim veri matrisi train_matrix, eğitim verileri gerçek etiket etiketleri ve K hesaplama mesafe sınıflandırma fonksiyonuna geçirilir ve son olarak model doğruluk oranı hesaplanır. Ve tahmin edilen hata verilerini çıktı olarak alın.

    1hata = 2 test_matrix = listdir ('testDigits') 3 doğru = 0.04 m_test = len (test_matrix) Aralıktaki i için 5 (m_test): 6 file_name_str = test_matrix 7 file_str = dosya_adı_str.split ('.') 8 # Test veri setindeki her verinin gerçek sonucu 9 dosya_num = int (dosya_dizi.split ('_')) 10 TestClassify = img_deal ('testDigits /% s'% file_name_str) 11 classify_result = sınıflandır (TestClassify, train_matrix, etiketler, 3) 12 baskı ('Öngörülen sonuç:% s \ tGerçek sonuç:% s'% (classify_result, file_num)) 13 classify_result == file_num: 14 doğru + = 1.015 başka: 16 error.append ((file_name_str, classify_result)) 17 baskı ("Doğru oran: {:. 2f}%". Format (doğru / float (m_test) * 100)) 18 baskı (hata) 19 baskı (len (hata))

    Kod çalıştırma kısmının ekran görüntüsü aşağıdaki gibidir

    K = 3 olduğunda, doğruluk oranı% 98.94'e ulaşır Bu model için doğruluk oranı çok etkileyicidir, ancak işletim verimliliği nispeten düşüktür ve 30 saniyeye yaklaşır. Her bir test verisinin yaklaşık 2000 eğitim verisinden mesafeyi hesaplaması gerektiğinden ve her hesaplama 1024 boyutlu kayan nokta işlemi içerdiğinden, yüksek frekanslı çok boyutlu hesaplamalar modelin düşük verimliliğinin ana nedenidir.

    K değeri

    Aşağıdaki şekil K değeri ile model doğruluğu arasındaki ilişkiyi göstermektedir: K = 3 olduğunda, modelin doğruluğu zirveye ulaşır K arttıkça doğruluk küçülür ve küçülür, bu nedenle bu verilerin gürültüsü hala nispeten küçüktür.

    El yazısı rakam testi

    Modelleme tamamlandıktan sonra modelin doğruluğu da iyidir El yazısı sayıları neden kendiniz test ediyorsunuz? Bu yüzden birkaç numarayı elle yazdım.

    Normal olarak çekilen resimler RGB renkli resimlerdir ve pikseller de farklıdır, bu nedenle resim üzerinde iki işlem yapmanız gerekir: yukarıdaki algoritmamızın gereksinimlerini karşılamak için resmi siyah beyaz bir resme dönüştürmek ve pikseli 32x32'ye dönüştürmek; pikseller için , Değer genellikle 0-255 arasındadır; 255 beyazı, 0 siyahı temsil eder, ancak el yazısı dijital piksellerin rengi standartlaştırılmadığından, siyah ve beyaz arasındaki farkı değerlendirmek için bir eşik belirledik.

    Metin koduna resim aşağıdaki gibidir:

    1def pic_txt: Aralıktaki i için 2 (0,10): 3 img = Image.open ('. \ El yazısı \% s.png'% i) 4 # Resim pikselini 32X32 olarak değiştirin 5 img = resim yeniden boyut ((32,32)) 6 # Renkli resimleri siyah beyaz resimlere dönüştürün 7 img = img.convert ('L') 8 #Kaydet 9 yol = '. \ El yazısı \% s_new.jpg'% i 10 img. Kaydet (yol) 11 (0,10) aralığında i için: 12 fb = open ('. \ Hand_written \% s_handwritten.txt'% i, 'w') 13 new_img = Image.open ('. \ El yazısı \% s_new.jpg'% i) 14 # Resmin genişliğini ve yüksekliğini okuyun 15 genişlik, yükseklik = new_img.size Aralıktaki i için 16 (yükseklik): Aralıktaki j için 17 (genişlik): 18 # Piksel alın 19 renk = new_img.getpixel ((j, i)) 20 # Yüksek piksel resimdeki beyazdır 21 renk ise > 170: 22 fb.write ('0') 23 başka: 24 fb.write ('1') 25 fb.write ('\ n') 26 fb. Yakın

    Genel kod çalıştıran ekran görüntüsü aşağıdaki gibidir:

    Doğruluk oranı% 70. Sonuçta çok az test verisi var 10 sayı arasında 4, 7 ve 8'in tahminleri yanlış, bu oldukça etkileyici.Işık probleminden dolayı bazı numaraların sol alt köşesinde doğru olacak şekilde bazı koyu gölgeler olacak. Test sonuçlarının belirli bir etkisi vardır. Benzer durumlardan kaçınırsanız ve daha fazla test verisi eklerseniz, doğruluk oranı kesinlikle artacaktır.

    Tsinghuanın "Jitu" ve "Tianyuan" ları büyük ölçüde açık kaynaklara sahipti ve yerel derin öğrenme çerçevesi parlak bir anda başladı
    önceki
    PyTorch'u kıyaslayan Tsinghua ekibi, kendi geliştirdiği bir AI çerçevesi olan "Planlama" | AI Teknolojisi Ekoloji Teorisi'ni başlattı
    Sonraki
    Programcılar neden çok çalışmasın?
    ES 2020'nin yeni özelliklerine başlamak için on dakika
    GitHub Eylemleri ile yüksek kaliteli Python kodu nasıl yazılır?
    "SQL bilmiyorum, hiçbir şey yapamam!" Kıdemli Ar-Ge: Bu, programcılar için önemli bir beceridir
    WeChat iOS sürümü resmi olarak karanlık modu destekliyor; Google, I / O geliştirici konferansının tamamen iptal edildiğini duyurdu; Visual Studio 201916.5 yayınlandı | Geek Headlines
    Hayat kısadır, sadece Python kullanmak için değil, aynı zamanda VSCode'da kullanmak için de | The Force Project
    Bitcoin logosunun arkasındaki tarihsel ve sembolik anlamlar nelerdir? Logodaki "B" neden sağa doğru eğiliyor?
    Kolayca bir resim arama sistemi kurmanız için 7 ipucu
    500 milyon Weibo verisinin sızdırıldığından şüpheleniliyor Python tarayıcıları Tiankeng'e adım atmaktan nasıl kaçınabilir?
    Yann LeCun bir sonraki Madame Curie olacak mı?
    Bu sefer değişmez sınıfı anlamazsam, sadece anlıyorum
    bir düşüncen var! Bu programcılar grubu, yeni koronavirüsü ortadan kaldırmak için emekli madencilik makinelerini kullanmaya çalıştı.
    To Top