{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.5","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":1302,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"Out of a deep rooted fear of being caught in a life or death situation in which a Perceptron is the only way to save everyone and I am somehow the only computer scientist in the room, I decided I would try to build my own (albeit a very simple one) to better understand the Perceptron algorithm.","metadata":{"_cell_guid":"2ed4ea91-bf49-4662-9a8e-da414e66bd65","_uuid":"b5a18c95d655ec717d8aec7b4dfbad023a611a76"}},{"cell_type":"code","source":"%matplotlib inline","metadata":{"_uuid":"e3cd05d62d957bd20912d77e814ae1dc48caac56","_cell_guid":"09417810-3182-4cfb-b868-935fa553da56","execution":{"iopub.status.busy":"2023-12-22T06:28:45.726771Z","iopub.execute_input":"2023-12-22T06:28:45.727239Z","iopub.status.idle":"2023-12-22T06:28:45.734098Z","shell.execute_reply.started":"2023-12-22T06:28:45.727166Z","shell.execute_reply":"2023-12-22T06:28:45.733043Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"%matplotlib inline adalah magic command dalam lingkungan Jupyter Notebook yang digunakan untuk menampilkan plot secara langsung di dalam notebook tanpa memerlukan perintah plt.show() setelah pembuatan plot. Magic command ini mengintegrasikan output dari matplotlib ke dalam notebook, sehingga plot akan ditampilkan di cell notebook yang bersangkutan.","metadata":{}},{"cell_type":"code","source":"import pandas as pd #pandas digunakan untuk bekerja dengan data dalam bentuk DataFrame\nimport numpy as np #numpy digunakan untuk operasi numerik\nimport matplotlib.pyplot as plt #matplotlib.pyplot digunakan untuk membuat plot/grafik.\n\n# Kode ini membaca dua file CSV: train.csv dan test.csv yang terletak di direktori tersebut menggunakan fungsi pd.read_csv() dari pandas. \n# Data dari file CSV tersebut dibaca dan dimasukkan ke dalam dua variabel train dan test, masing-masing sebagai DataFrame.\ntrain = pd.read_csv(\"../input/train.csv\")\ntest  = pd.read_csv(\"../input/test.csv\")\n\n# mendapatkan informasi tentang data yang ada:\nprint(\"Training set has {0[0]} rows and {0[1]} columns\".format(train.shape))\nprint(\"Test set has {0[0]} rows and {0[1]} columns\".format(test.shape))\n# Any files you write to the current directory get shown as outputs \n#Ini adalah komentar yang memberikan informasi bahwa jika ada file yang Anda tulis ke direktori saat ini, \n#file-file tersebut akan ditampilkan sebagai output (misalnya, jika Anda menyimpan plot dalam direktori saat ini menggunakan matplotlib). \n","metadata":{"_uuid":"f3d7909fa8e7e127853b0be31d4bb5c31f0377d3","_cell_guid":"e32c775a-535f-40ed-bc4d-a606b7d94555","execution":{"iopub.status.busy":"2023-12-22T06:28:45.735249Z","iopub.execute_input":"2023-12-22T06:28:45.735592Z","iopub.status.idle":"2023-12-22T06:28:52.302215Z","shell.execute_reply.started":"2023-12-22T06:28:45.735540Z","shell.execute_reply":"2023-12-22T06:28:52.301278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data\nAfter loading the data, store it in the following format:\n\n**Labels** (vector of length 42000)\n\n**Training Data** (matrix of shape 42000,784; the labels are sliced off)\n\nEach handwritten digit used for training is stored as a row in a matrix. \nEach row is 784 points long; this represents\npixel intensities of an image which is 28 by 28 pixels. The row must be reshaped in order to visualize it.\n\n**Weights** (list of vectors, one vector for each class. 10 by 784)\n\nEach weight vector is the same length as a handwritten digit vector. ","metadata":{"_uuid":"24dd418ad1886e2615496e575044952acdb9d864","_cell_guid":"cb261508-50c1-42d3-aaf8-70b02879642b"}},{"cell_type":"code","source":"# Baris ini menetapkan variabel trainlabels dengan kolom label dari DataFrame train. \n#Ini mengasumsikan bahwa ada kolom 'label' yang berisi label kelas untuk setiap sampel dalam data pelatihan.\ntrainlabels = train.label\n\n# Kode ini menetapkan variabel traindata sebagai matriks dari data pelatihan tanpa kolom label. \n# Ini dihasilkan dengan menggunakan train.loc[:, 'pixel0':] untuk mengambil semua kolom mulai dari 'pixel0' hingga kolom terakhir.\n# np.asmatrix() mengonversi data ini ke dalam bentuk matriks. traindata.shape mencetak dimensi dari matriks traindata.\ntraindata = np.asmatrix(train.loc[:,'pixel0':])\ntraindata.shape #traindata.shape mencetak dimensi dari matriks traindata.\n\n# Visualize a single digit (one row from the training data matrix)\nsamplerow = traindata[3:4]#get one row from training data\nsamplerow = np.reshape(samplerow,(28,28))#reshape it to a 28*28 grid\nprint(\"A sample digit from the dataset:\")\nplt.imshow(samplerow, cmap=\"hot\") #digunakan untuk menampilkan gambar dari baris yang dipilih sebagai representasi dari digit dalam dataset.\n\n# Initialize the weight matrix (one row per class)\nweights = np.zeros((10,784)) #Baris ini menginisialisasi matriks bobot weights dengan ukuran (10, 784). \n#Dalam konteks ini, terdapat 10 baris (mewakili kelas-kelas yang berbeda) dan 784 kolom (mewakili fitur-fitur dari setiap sampel, dalam hal ini piksel-piksel dari gambar 28x28). \n#np.zeros digunakan untuk menginisialisasi matriks dengan nilai nol. \nprint(weights.shape) #weights.shape mencetak dimensi dari matriks bobot yang telah dibuat.","metadata":{"_uuid":"d9d47fb7c3d308c29d99e1fed1d3a0714b3b983c","_cell_guid":"7eeb0a58-1e03-4e85-86de-b454117f9916","execution":{"iopub.status.busy":"2023-12-22T06:28:52.303286Z","iopub.execute_input":"2023-12-22T06:28:52.303616Z","iopub.status.idle":"2023-12-22T06:28:52.440643Z","shell.execute_reply.started":"2023-12-22T06:28:52.303570Z","shell.execute_reply":"2023-12-22T06:28:52.439817Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Perceptron Learning (training)\nFor each handwritten digit in the data set, compare its vector to each of the weight \nvectors by taking the dot product. \n\nThe largest resulting dot product is the 'guess'.\nIf the guess is wrong, the incorrect weight vector is updated by subtracting the\ndigit vector and the correct weight vector is updated by adding the digit vector.\n\nThis routine repeats through the dataset many times (epochs) until the number of wrong guesses\nbegins to stabilize (in this case, 15 epochs. If you were to run 20 epochs, you'd see overfitting).","metadata":{"_uuid":"3ce272b113dc671dd59a5df48cc8c9809b49f39e","_cell_guid":"e7215b1f-abbb-45e8-b9ab-2542faed5805"}},{"cell_type":"code","source":"# For E epochs, \nE = 15\nerrors = [] #Inisialisasi list errors yang akan digunakan untuk menyimpan error setelah setiap epoch.\nfor epoch in range(E): #Setiap epoch merupakan satu iterasi melalui seluruh dataset.\n    err = 0 #err sebagai counter untuk jumlah error pada setiap epoch.\n    for i, x in enumerate(traindata): #Iterasi melalui setiap data (x) dalam traindata menggunakan enumerate(traindata)\n        #Variabel i adalah indeks, x adalah data untuk setiap iterasi.\n        dp=[]#Inisialisasi list dp untuk menyimpan hasil dot product dari data dengan matriks bobot (weights).\n        #Iterasi melalui matriks bobot (weights) untuk setiap digit class (0-9). Masing-masing digit class memiliki vektor bobotnya sendiri.\n        for w in weights:\n            dotproduct = np.dot(x,w) #Menghitung dot product antara data (x) dengan vektor bobot (w).\n            dp.append(dotproduct) # Menambahkan hasil dot product ke dalam list dp.\n        guess = np.argmax(dp) #tMengambil index dengan nilai terbesar dari list dp, yang menunjukkan kelas digit yang diestimasi.\n        actual = trainlabels[i] #Menyimpan label aktual dari data.\n        # Jika kelas yang diestimasi (guess) tidak sama dengan kelas aktual (actual), maka bobot yang terkait diperbarui.\n        if guess != actual:\n            weights[guess] = weights[guess] - x #Bobot yang salah diperbarui dengan mengurangkan vektor data (x).\n            weights[actual] = weights[actual] + x # Bobot yang benar diperbarui dengan menambahkan vektor data (x).\n            err += 1 #Increment counter error jika terdapat kesalahan klasifikasi.\n    errors.append(err/42000) #Menambahkan nilai rata-rata error pada epoch saat ini (dibagi dengan total data) ke dalam list errors.\nplt.plot(list(range(0,E)),errors) #Membuat plot grafik yang menunjukkan perubahan error setiap epoch. \n                                    #Sumbu x adalah jumlah epoch, sedangkan sumbu y adalah error yang dihitung dari hasil klasifikasi.","metadata":{"_uuid":"b519e87aaf2844052d7c5690e3165e9c89a58b28","_cell_guid":"d299742d-072e-4bee-a4c4-f2e58f4731db","execution":{"iopub.status.busy":"2023-12-22T06:28:52.442174Z","iopub.execute_input":"2023-12-22T06:28:52.442786Z","iopub.status.idle":"2023-12-22T06:30:52.408762Z","shell.execute_reply.started":"2023-12-22T06:28:52.442699Z","shell.execute_reply":"2023-12-22T06:30:52.407997Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Perceptron Testing\nCreate a csv file to upload as submission.","metadata":{"_uuid":"24ca51d1352a244720c1418975d5f77127807818","_cell_guid":"f61927e2-2c87-4d20-a7dd-09c26bb3f761"}},{"cell_type":"code","source":"testdata = np.asmatrix(test) # Mengonversi data test ke dalam bentuk matriks menggunakan np.asmatrix(). \n                                # Variabel test adalah data uji yang akan digunakan untuk prediksi kelas.\nguesses = [] #Membuat list kosong guesses untuk menyimpan hasil prediksi.\nfor i, z in enumerate(testdata): # Iterasi melalui setiap data dalam testdata menggunakan for i, z in enumerate(testdata).\n                                    # Variabel i adalah indeks, z adalah data untuk setiap iterasi.\n    dp=[] # Membuat list kosong dp untuk menyimpan hasil dot product dari data uji dengan matriks bobot.\n    # Iterasi melalui matriks bobot (weights) untuk setiap digit class (0-9). Masing-masing digit class memiliki vektor bobotnya sendiri.\n    for w in weights:\n        dotproduct = np.dot(z,w) #Menghitung dot product antara data uji (z) dengan vektor bobot (w).\n        dp.append(dotproduct) # Menambahkan hasil dot product ke dalam list dp.\n    guess = np.argmax(dp) #Mengambil index dengan nilai terbesar dari list dp, yang menunjukkan kelas digit yang diestimasi.\n    guesses.append(guess) #Menambahkan hasil prediksi (kelas digit yang diestimasi) ke dalam list guesses untuk setiap data uji.","metadata":{"_uuid":"236f85d37015920c3b107d9a9012736e93b3d6d4","_cell_guid":"488fcea8-9513-4bd1-b60e-e78d7748c8e7","execution":{"iopub.status.busy":"2023-12-22T06:30:52.409993Z","iopub.execute_input":"2023-12-22T06:30:52.410266Z","iopub.status.idle":"2023-12-22T06:30:56.825268Z","shell.execute_reply.started":"2023-12-22T06:30:52.410220Z","shell.execute_reply":"2023-12-22T06:30:56.824300Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"f = open('percep1.csv', 'w') #membuka file 'percep1.csv' dalam mode penulisan ('w'). \n                                #Jika file tersebut sudah ada, maka akan dihapus dan dibuat yang baru. Jika tidak ada, file baru akan dibuat.\ni = 1 #Variabel i diinisialisasi dengan nilai 1.\nf.write('ImageId,Label\\n') #Kode ini menulis string 'ImageId,Label\\n' ke dalam file CSV yang dibuka sebelumnya. \n                            #Ini adalah header untuk kolom-kolom yang akan ditulis ke dalam file CSV.\nfor g in guesses: #Kode ini melakukan iterasi melalui setiap elemen dalam list guesses (yang berisi hasil prediksi).\n    foo = str(i) + ',' + str(g) + '\\n'#Untuk setiap prediksi, kode membentuk sebuah string foo yang berisi nomor gambar (i) \n                                        #dan prediksi kelas digit (g) dalam format 'ImageId,Label\\n'. \n    f.write(foo)\n    i += 1   #String ini ditulis ke dalam file CSV yang telah dibuka sebelumnya, kemudian nilai i diincrement untuk menunjukkan nomor gambar berikutnya.\n\n#f.close() menutup file yang telah ditulis. Ini penting untuk memastikan data ditulis secara lengkap ke dalam file sebelum keluar dari program. \n#print(i) mencetak nilai terakhir dari i. Biasanya ini akan menjadi jumlah total gambar yang diproses untuk membuat file CSV. \n#Jika semua gambar telah ditulis, i akan mencerminkan jumlah total gambar dalam dataset.\nf.close()\nprint(i)","metadata":{"_uuid":"6715cefa6dd326b22e62ae818eb12e07d64e1c3f","_cell_guid":"253fc53e-690f-4cb1-97b0-71c75fef4632","execution":{"iopub.status.busy":"2023-12-22T06:30:56.826665Z","iopub.execute_input":"2023-12-22T06:30:56.826944Z","iopub.status.idle":"2023-12-22T06:30:56.909527Z","shell.execute_reply.started":"2023-12-22T06:30:56.826897Z","shell.execute_reply":"2023-12-22T06:30:56.908648Z"},"trusted":true},"execution_count":null,"outputs":[]}]}