{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","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":30587,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# Phần 1: Nhập các thư viện cần thiết\n# ------","metadata":{"_uuid":"b0093541-188e-43e9-acb2-d917ae3a5010","_cell_guid":"cadbfcb2-82c3-470f-bad6-eade54542125","execution":{"iopub.status.busy":"2024-06-10T16:27:27.227305Z","iopub.execute_input":"2024-06-10T16:27:27.227791Z","iopub.status.idle":"2024-06-10T16:27:27.252283Z","shell.execute_reply.started":"2024-06-10T16:27:27.227749Z","shell.execute_reply":"2024-06-10T16:27:27.251204Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Cơ sở dữ liệu MNIST (Cơ sở dữ liệu Viện Tiêu chuẩn và Công nghệ sửa đổi Quốc gia) là một cơ sở dữ liệu lớn về chữ số thường được sử dụng để huấn luyện các hình ảnh xử lý hệ thống khác nhau. Khi các kỹ thuật học máy mới xuất hiện, MNIST vẫn là nguồn tài nguyên đáng tin cậy cho cả các nhà nghiên cứu và người học.\n\nCác hình ảnh đen trắng ban đầu đã được chuẩn hóa để vừa với hộp giới hạn 28x28 pixel và khử răng cưa, giới thiệu các mức thang độ xám. Cơ sở dữ liệu MNIST ban đầu chứa 60.000 hình ảnh đào tạo và 10.000 hình ảnh thử nghiệm, nhưng trong cuộc thi này, chúng tôi được cung cấp 42.000 hình ảnh đào tạo (70%) và 18.000 hình ảnh thử nghiệm (30%).\n\nCác kỹ thuật tiên tiến để tiếp cận bất kỳ vấn đề Phân loại hình ảnh nào thường dựa vào Mạng thần kinh chuyển đổi. Kiểu kiến ​​trúc này thực sự tốt trong việc trích xuất các mẫu từ hình ảnh. Tuy nhiên, vì MNIST là một bài toán đơn giản nên trong cuốn sổ tay này, chúng ta sẽ áp dụng các Thuật toán Học máy đơn giản (và chúng ta sẽ có được độ chính xác khá cao!).\n\nĐầu tiên, chúng tôi sẽ thực hiện Phân tích thành phần chính để giảm kích thước của dữ liệu (từ giá trị 784 pixel xuống còn 10 thành phần chính). Sau đó, chúng ta sẽ chạy thuật toán lười học yêu thích của mình: K-Nearest Neighbors. Combinatino này đạt được Độ chính xác thử nghiệm là 0,9271, một điều khá đáng chú ý !!!\n\nMục lục:\n Đọc và khai thác dữ liệu:\n- Kiểm tra xem lượng giá trị.\n- Kiểm tra phạm vi giá trị pixel.\n- Trực quan hóa dữ liệu (Hình ảnh).\n- Kiểm tra xem cân bằng của mục tiêu.\n\nPCA :\n- Giới thiệu thuật toán PCA.\n- Tiền xử lý (quy mô) dữ liệu.\n- Triển khai thuật toán PCA bằng thư viện Sklearn.\n- Nhúng các mô-đun vào Đường ống Sklearn.\n- Vẽ biểu đồ phương sai giải thích của các thành phần.\n- Hiển thị hai chiều của dữ liệu bằng cách sử dụng seaborn.\n- Trực quan hóa dữ liệu ba chiều bằng cách sử dụng âm mưu.\n- Trực quan hóa phép biến đổi nghịch đảo.\n- Kiểm tra xem các thành phần có tương quan với nhau không.\n\n Bộ phân loại KNN:\n- Xây dựng Bộ phân loại KNN bằng Sklearn.\n- Sử dụng kỹ thuật PCA làm công cụ trích xuất đặc trưng cho KNN.\n- Chạy Xác thực chéo tìm kiếm lưới để tối ưu hóa siêu tham số n_neighbors.\n- So sánh số liệu đào tạo và xác nhận để kiểm tra xem có trang bị quá mức không.\n- Vẽ ma trận nhầm lẫn.\n- Tính toán báo cáo phân loại.","metadata":{"_uuid":"85d40f0d-34d6-4e02-90f3-7ef7a60e5573","_cell_guid":"ddf0a964-5157-492a-9699-253bc2caec79","trusted":true}},{"cell_type":"code","source":"## NHẬP THƯ VIỆN PYTHON CẦN THIẾT\n\n# Read & Explore Data\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom sklearn.preprocessing import MinMaxScaler\n\n# Phân tích thành phần chính (PCA)\nfrom sklearn.decomposition import PCA\nfrom sklearn.pipeline import Pipeline\nimport plotly.express as px\n\n# K-Bộ phân loại hàng xóm gần nhất (KNN)\nfrom sklearn.neighbors import KNeighborsClassifier\nfrom sklearn.model_selection import GridSearchCV\nfrom sklearn.metrics import classification_report, \\\n    confusion_matrix, ConfusionMatrixDisplay \n\n# VHT\nfrom scipy.ndimage import rotate","metadata":{"_uuid":"c382c9dc-2109-4ce6-b779-dc8c447da240","_cell_guid":"e169ec97-1f64-46cd-8099-1d09c757dccc","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:27.254464Z","iopub.execute_input":"2024-06-10T16:27:27.255262Z","iopub.status.idle":"2024-06-10T16:27:30.435522Z","shell.execute_reply.started":"2024-06-10T16:27:27.255219Z","shell.execute_reply":"2024-06-10T16:27:30.434386Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def func_array1d_rotate2d(Narray1d,rotate_angle,sizePixel):\n\n    N = Narray1d.shape[0]\n\n    Narray1d_rotate = np.zeros(Narray1d.shape)\n    \n    for i in range(N):\n        image = np.reshape(Narray1d[i,:],(sizePixel,sizePixel))\n        rotated_image = rotate(image,rotate_angle, reshape=False)\n        rotated_array1d = np.reshape(rotated_image,(1,-1))\n        Narray1d_rotate[i,:] = rotated_array1d\n        \n    return Narray1d_rotate","metadata":{"_uuid":"b362968d-9828-4257-92ec-b9e4e49a9cb0","_cell_guid":"8ace7936-3ee9-4fe9-b71e-8d7e3b7eee15","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:30.436932Z","iopub.execute_input":"2024-06-10T16:27:30.437629Z","iopub.status.idle":"2024-06-10T16:27:30.445139Z","shell.execute_reply.started":"2024-06-10T16:27:30.437584Z","shell.execute_reply":"2024-06-10T16:27:30.443577Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"----\n# Phần 2: Đọc dữ liệu và khai thác dữ liệu","metadata":{"_uuid":"a7abf7cf-fbfb-44f8-a5eb-77885d1283fb","_cell_guid":"1e5c33e8-406f-4da5-929d-034f87443736","trusted":true}},{"cell_type":"markdown","source":"Trong phần này, chúng ta sẽ sử dụng thư viện Pandas Python nổi tiếng để đọc dữ liệu từ các tệp .csv.\n\nChúng ta sẽ trực quan hóa việc phân phối các giá trị pixel (biểu đồ) bằng thư viện Seaborn và Matplotlib Python. Chúng ta cũng sẽ kiểm tra xem đảm bảo không có giá trị nào bị thiếu và các lớp mục tiêu có cân bằng.\n\nCuối cùng, chúng ta sẽ trực quan hóa các hình ảnh bằng cách vẽ một hình ảnh từ mỗi lớp.","metadata":{"_uuid":"d4c82fac-2a10-4c14-a95a-653bd16872cd","_cell_guid":"deaebcb3-115c-4e6b-b843-4522382a052d","trusted":true}},{"cell_type":"code","source":"# Đọc file dữ liệu bằng Pandas\ndf_train = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')\ndf_test =  pd.read_csv('/kaggle/input/digit-recognizer/test.csv')","metadata":{"_uuid":"4da57b46-cc50-4ae9-9495-d0dbeb6be5ee","_cell_guid":"8967621a-0c55-49ff-b6e2-05d9efdeedf2","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:30.446609Z","iopub.execute_input":"2024-06-10T16:27:30.447585Z","iopub.status.idle":"2024-06-10T16:27:36.261957Z","shell.execute_reply.started":"2024-06-10T16:27:30.447539Z","shell.execute_reply":"2024-06-10T16:27:36.260799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Kiểm tra kích thước của tàu và kiểm tra DataFrames\nprint(\"df_train shape:\", df_train.shape)  # 70%\nprint(\"df_test shape: \", df_test.shape)  # 30%","metadata":{"_uuid":"5465a268-9ec4-4482-a0d7-e531d25f4917","_cell_guid":"da0e04b7-5ce3-48ec-be64-cee70c71af07","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:36.265142Z","iopub.execute_input":"2024-06-10T16:27:36.265658Z","iopub.status.idle":"2024-06-10T16:27:36.272801Z","shell.execute_reply.started":"2024-06-10T16:27:36.265613Z","shell.execute_reply":"2024-06-10T16:27:36.271360Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Không có giá trị nào bị thiếu trong dữ liệu của chúng ta\nprint(\n    \"Missing values in df_train: \", \\\n    df_train.isna().sum().sum()\n)\nprint(\n    \"Missing values in df_test: \", \\\n    df_test.isna().sum().sum()\n)","metadata":{"_uuid":"f8324800-d007-4d21-9eb6-39bba50ce548","_cell_guid":"758f94a2-69c7-4c9b-b1a3-22cb0f0b1a43","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:36.274263Z","iopub.execute_input":"2024-06-10T16:27:36.275225Z","iopub.status.idle":"2024-06-10T16:27:36.342653Z","shell.execute_reply.started":"2024-06-10T16:27:36.275182Z","shell.execute_reply":"2024-06-10T16:27:36.341336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Nhìn lại năm hàng huấn luyện đầu tiên\ndf_train.head()","metadata":{"_uuid":"b1a7f2dc-6cec-4610-ba22-6ad5a7fb06ac","_cell_guid":"f1a8c252-31ba-46a1-b25c-c6ffff3fa2a9","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:36.344115Z","iopub.execute_input":"2024-06-10T16:27:36.344584Z","iopub.status.idle":"2024-06-10T16:27:36.377479Z","shell.execute_reply.started":"2024-06-10T16:27:36.344539Z","shell.execute_reply":"2024-06-10T16:27:36.376249Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Chúng ta có thể thấy cột đầu tiên là nhãn,\n# và các cột còn lại là 784 pixel\n# đại diện cho hình ảnh thang độ xám 28x28.\n# Hãy tách X và Y\n\nX_train = df_train.drop(columns=['label']).values\ny_train = df_train['label'].values","metadata":{"_uuid":"48085649-c225-4e39-824f-82474ea004ff","_cell_guid":"939c1008-c85e-4ee0-bdab-bcccc4a252e4","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:36.379008Z","iopub.execute_input":"2024-06-10T16:27:36.380822Z","iopub.status.idle":"2024-06-10T16:27:36.520971Z","shell.execute_reply.started":"2024-06-10T16:27:36.380771Z","shell.execute_reply":"2024-06-10T16:27:36.519845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Hãy hình dung sự phân bố của các giá trị pixel\n\nax = sns.histplot(x=X_train.flatten(), color='#4895EE')\n_ = ax.set(title='Pixel Value Histogram', xlabel='Pixel Value')\n\n# Như chúng ta có thể thấy, giá trị 0 đại diện cho nền\n# và >0 đại diện cho các chữ số trong hình ảnh","metadata":{"_uuid":"f724afe4-d098-4f65-aaca-e97a096b8a32","_cell_guid":"36ec9986-72eb-4f04-abf8-84e2df3e3bfa","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:36.522629Z","iopub.execute_input":"2024-06-10T16:27:36.522985Z","iopub.status.idle":"2024-06-10T16:27:48.195273Z","shell.execute_reply.started":"2024-06-10T16:27:36.522954Z","shell.execute_reply":"2024-06-10T16:27:48.193995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Hãy kiểm tra xem mục tiêu có cân bằng không.\n# Nó có nghĩa là mười danh mục trong mục tiêu\n# có sự biểu diễn gần giống nhau trong dữ liệu.\n\nax = sns.countplot(x=y_train, color='#4895EE')\nax.set(\n    title='Target distribution is balanced? Yes!',\n    xlabel='Label'\n)\n# Số lượng mẫu dự kiến ​​cho cân \n# phân bổ lớp là 42000/10 = 4200\n_ = ax.axhline(y=4200, color='#12086F', linestyle='--')\n\n# Vì các lớp mục tiêu là số dư nên chúng ta không có\n# lo lắng về các phương pháp lấy mẫu trong các mô hình của chúng ta.","metadata":{"_uuid":"cd488e69-2d9d-4209-ac52-f11e13ab443b","_cell_guid":"d681064d-2dbe-4c2b-8075-9ce2c254d755","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:48.197130Z","iopub.execute_input":"2024-06-10T16:27:48.197587Z","iopub.status.idle":"2024-06-10T16:27:48.457668Z","shell.execute_reply.started":"2024-06-10T16:27:48.197537Z","shell.execute_reply":"2024-06-10T16:27:48.456457Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Tiếp theo, hãy hình dung một hình ảnh từ mỗi lớp.\n# Chúng ta sẽ sử dụng hàm 'imshow' của matplotlib.\n\nfig, axs = plt.subplots(nrows=2, ncols=5, figsize=(10,5))\n\nfor i in range(10):\n    idx = np.where(y_train==i)[0][2]\n    img = axs[int(i >= 5), i%5].imshow(\n        X=X_train[idx].reshape(28, 28),\n        cmap='Blues'\n    )\n    img.axes.get_yaxis().set_visible(False)\n    img.axes.get_xaxis().set_visible(False)\n    img.axes.set_title(f'Label: {i}')","metadata":{"_uuid":"9d6c909c-609f-4b5d-a907-2d75a3c17401","_cell_guid":"1fa8f38f-f989-4007-86c5-590612877157","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:48.459228Z","iopub.execute_input":"2024-06-10T16:27:48.459701Z","iopub.status.idle":"2024-06-10T16:27:49.154595Z","shell.execute_reply.started":"2024-06-10T16:27:48.459662Z","shell.execute_reply":"2024-06-10T16:27:49.153357Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# transform data","metadata":{"_uuid":"dd9d9d94-7ea8-4f8d-aa91-866959d703e3","_cell_guid":"48cf8b51-1a3e-4d0e-94e5-da53b3aa7c90","trusted":true}},{"cell_type":"code","source":"# -------------------------------------------------- declare\nnumRotate_prior = 10\n\nangleOffset_prior = -10\nangleRange_prior = 20\n\nX_train_pick2rotate = {\n    'index': np.array([   700,701,702,703,704, 705,706,707,708,709,\n                       710,711,712,713,714,75,716,717,718,719,\n                       720, 721, 722, 723, 724, 725, 726, 727,728, 729,\n                       730, 731, 732, 733, 734, 735 ,736, 737, 738, 739,\n                       740, 741, 742, 743, 744, 745, 746, 747, 748, 749,\n                       750, 751, 752,753, 754, 755, 756, 757, 758, 759, \n                       760, 761, 762, 763, 764, 765, 766, 767, 768, 769, \n                       770, 771, 772, 773, 774, 775, 776, 777, 778, 779, \n                       780, 781, 782, 783, 784, 785, 786, 787, 788, 789,\n                       790, 791, 792, 793, 794, 795, 796, 797, 798, 799]),\n    'offset': np.array([\n       \n        [-5, 22, 5, 0, 0, 10, 1, 0, 0, 30],  # 1\n        [5, 10, -15, 5, 30, 20, -30, 0, 18, 0],      # 2\n        [40, 33, 0, 20, 15, 20, -10, -10, 10, 10],        # 3\n        [40, 15, -10, 5, 5,0, -5, 10,5,10],   # 4\n        [25, 17, 0, -35, 10,5, 0, 0, 20, 25],     # 5\n        [30, 5, -8, 0, 0, 0, 8, 0, 18, -5],         # 6\n        [45, -10, -5, 5, -13, 5, -1, 0, 17, 25],     # 7\n        [25, -5, 0, 10, 22, -5, 5, 0, 10, 18],      # 8\n        [50, 15, -12, -8, 0, 20, -30, 5, 0, 15], # 9\n        [0, -10, -10, -10, 15,-5, -35, 0, -10, 25],     # 10\n\n\n        [45,10,-5,10,10,  10,-10,0,10,-15], #11\n        [0,-5,0,0,-5,   -25,-50,0,20,5], #12\n        [20,20,-10,5,0,     10,-50,-5,-10,30], #13\n        [30,0,-10,20,0,  0,0,0,15,0],#14\n        [40,15,0,0,10,     15,-25,0,20,10], #15\n        \n        [45,5,0,20,10,    20,0,0,20,35], #16\n        [25,35,-10,-20,-5,  15,-20,0,-10,0], #17\n        [0,30,-40,0,0,  10,-45,0,10,-20], #18\n        [30,30,-30,0,25,  0,-5,0,0,-12], #19\n        [0,25,0,0,30,    0,0,0,0,-10], #20\n\n        [35, 10, -20, -6, 0, 25, -30, 10, -15, 40],   # 21\n        [30, -5, -15, -8, 0, -5, -10, 0, 0, 10],      # 22\n        [45, 10, 10, 30, 0, 0, -15, 0, -15, 10],   # 23\n        [20, 7, 0, 0, 30, 0, -50, 0, 20, 15],      # 24\n        [-30, -15, -30, 0, 35, 30, -15, 0, 10, 10], # 25\n        [30, 25, 0, 4, 30, 10, -10, 0, 20, 5],      # 26\n        [5, 20, 0, 0, 0, 10, -20, -5, -15, 5],        # 27\n        [0, 0, 0, 0, 25, 0, -15, 0, 5, 40],   # 28\n        [0, 33, 0, -5, 10, 10, -25, 0, 30, 30],     # 29\n        [20, 10, -20, 0, 10, 0, 0, 0, 0, 0],         # 30\n        [0, 20, 0, -15, 20, 10, -20, 0, -10, 5],     # 31\n        [40, 0, 0, 15, 0, -5, -10, 0, 10, 20],      # 32\n        [20, -10, -10,20, 10, -5, -10, 0, 10, -10],      # 33\n        [30, -5, -10, 0, 20, -10, -15, 0, 10, 30],      # 34\n        [-5, -5, -10, 0, 10, 5, -35, 0, 10, 0], # 35\n        [-10, -5, -15, 0, 0, -5, -10, 0, 5, 15],      # 36\n       \n        [20, 12, 0, -10, 10, -5, -10, 0, 15, 15],   # 37\n      \n        [2, 29, -10, -25, 15, 5, -15, 0, -15, 5],   # 38\n        \n        [0, 30, -20, 0, 30, 30, -50, 0, 20, -10],         # 39\n      \n        [20, 20, -10, -10, 10, 10, 10, -10, 10, 10],     # 40\n        [0, 9, 0, 0, 10, -15, -15, 0, 5, 10],      # 41\n      \n        [30, 8, -25, -10, 18, -5, 0, -5, -10, -5], # 42\n       \n        [0, 25, 0, -10, 25, -5, -10, 0, 10, 0],      # 43\n     \n        [15, 30, 0, 0, 22, 10, -35, 0, 20, 5], # 44\n       \n        [0, 20, -10, -20, 0, -5, -10, 0,-10, 0],      # 45\n  \n        [0, 5, 0, 0, 5, 0, -20, 0, 10, -10],        # 46\n      \n        [45, 15, 0, -30, 20, 0, -15, 0, 20, -10],   # 47\n       \n        [0, 25, 0, 0, 10, 10, 5, -10, 20, 20],     # 48\n    \n        [20, 15, 0, 0, 5, 20, -20, 0, 25, -10],         # 49\n       \n        [30, 10, -10, 10, 0, 0, -10, 0, -15, 20],     # 50\n\n        [20, 10, -5, 0, 20, 15, -15, 0, 0, -5],      # 51\n        \n        [40, -10, -10, -20, 25, 5, 20, 0, 5, 25],   # 52\n     \n        [40, 25, -10, 0, 0, 20, 25, -10, 10, 0],   # 53\n     \n        [0, 10, -10, 0, 0, 5, 0, 10, 0, 40] ,      # 54\n     \n        [-5, -15, -15, 0, 0, -5, -35, -25, 15, -30],   # 55\n     \n        [15, -5, -20, 0, 0, 0, 0, 5, -5, 10],       # 56\n     \n        [10, 15, -10, 5, 0, 0, 0, 0, -20, 5],         # 57\n     \n        [45, 10, -10, -10, 15, 25, -15, 0, 10, 15],    # 58\n     \n        [0, 10, 10, -10, 30, 20, -20, -5, 20, 5],      # 59\n     \n        [0, 25, -10, -10, 0, 10, -5, -5, 15, 20],          # 60\n\n        [0, 15, 2, 0, 30, 30, -50, 10, 20, 20],   # 61\n       \n        [10, -10, 0, 5, 5, 0, 10, 5, 10, 10],     # 62\n       \n        [20, 20, -10, 5, 30, 15, -30, 0, -5, 0],  # 63\n      \n        [45, 0, -20, 0, 20, 30, -5, 0, 25, 15],   # 64\n      \n        [20, 20, -5, 25, 25, 20, 10, 0, 10, 20],  # 65\n      \n        [25, -10, -20, 5, 20, 5, 15, 0, 15, 30],    # 66\n     \n        [20, -15, -5, 0, 30, 5, 15, 0, -10, 25],      # 67\n       \n        [40, 5, 5, 0, -5, 0, -130, 0, 10, -10],       # 68\n       \n        [-5, 0, 10, -20, 15, 15, -25, 0, 20, 20],  # 69\n      \n        [40, 25, 5, -20, 0, 10, -10, 0, 10, 0],    # 70\n\n        [10, -20, -30, -5, 20, -10, 10, -15, 15, 5],         # 71\n       \n        [15, 0, -20, 20, 10, 10, -25, 0, -25, 25],    # 72\n       \n        [45, 10, -15, -10, 0, 10, -15, 0, -5, 0],      # 73\n     \n        [45, 25, -5, -15, 5, 20, 0, 0, 0, 5],          # 74\n     \n        [10, 0, -5, 0, 0, 5, -60, 10, 10, -10],      # 75\n     \n        [20, 15, -5, 0, 8, 10, 0, -5, 0, 0],       # 76\n     \n        [45, 20, -15, 5, 0, 0, -10, 0, 5, 0],    # 77\n      \n        [15, 5, -5, 10, -10, 10, 5, 0, 20, 5],  # 78\n       \n        [10, 35, -10, 0, 15, 10, -20, 0, 40, 40],       # 79\n     \n        [10, 25, 0, 5, 30, 0, -30, 0, -5, 0],         # 80\n\n  \n        [45, -20, -10, -15, 15, -5, -15, -5, 25, 0],    # 81\n         \n        [0, 10, 0, 0, 10, 15, -15, 0, 20, 15],      # 82\n     \n        [25, 35, -10, -10, 20, 5, 0, 0, 20, 10],       # 83\n    \n        [10, 37, -10, 0, 10, 20, -25, 0, 0, 0],  # 84\n    \n        [35, 0, 0, 0, 10, 10, -10, 0, 10, 30],       # 85\n       \n        [10, -5, 0, 0, 0, 0, -40, 0, 0, 0],         # 86\n     \n        [50, -10, -10, -10, 5, 20, -5, -5, -15, 30],    # 87\n    \n        [35, -5, -5, 0, 15, 15, 5, 0, 10, 0],      # 88\n    \n        [35, 20, -15, 5, 10, -10, -5, 0, -10, 35],       # 89\n     \n        [0, 10, -10, 0, 5, 20, -50, -10, 10, 0],          # 90\n\n        [0, -3, -20, 0, 5, 0, 0, 0, 0, -20],      # 91\n        \n        [0, 5, -5, -10, 30, -5, -10, 0, -15, 0],       # 92\n      \n        [0, 30, -5, 0, 2, 10, 20, 0, 25, 25],       # 93\n      \n        [5, 0, 5, 15, -5, 0, -5, 0, 0, 10],       # 94\n      \n        [-5, 20, -10, 5, -10, 10, -25, 0, 15, 15],  # 95\n       \n        [0, 30, -10, 0, 5, -5, -10, 0, 25, 10],       # 96\n     \n        [-5, -5, -5, 0, 5, 0, -10, -10, 25, 0],         # 97\n    \n        [35, 20, -15, -10, -10, 0, -15, -10, 5, 25],    # 98\n    \n        [40, 10, 0, 0, 15, 0, 20, 0, -10, 0],      # 99\n      \n        [15, 15, -15, 10, -15, -5, -5, 0, 20, 25],  # 100\n\n    ])\n}\n\nnumPickRotate = len(X_train_pick2rotate['index'])\n\nprint('numPickRotate = ', numPickRotate)\n\n# -------------------------------------------------- rotate\n\nX_sample_rotate = np.zeros((10,numRotate_prior,numPickRotate,X_train.shape[1]))\ny_sample_rotate = np.zeros((10,numRotate_prior,numPickRotate))\n\nfor k0 in range(10):\n    for k1 in range(numRotate_prior):\n        for k2 in range(numPickRotate):\n            \n                idxPick_X_train = X_train_pick2rotate['index'][k2]\n                \n                idx = np.where(y_train==k0)[0][idxPick_X_train]\n                \n                y_sample_rotate[k0,k1,k2] = k0 * numRotate_prior + k1\n                \n                angleRotate = (k1/numRotate_prior * angleRange_prior) + angleOffset_prior + X_train_pick2rotate['offset'][k2][k0]\n                \n                X_sample_rotate[k0,k1,k2,:] = func_array1d_rotate2d(X_train[idx][np.newaxis,:],angleRotate, 28)\n\n                \nX_sample_rotate[X_sample_rotate < 10] = 0\n#X_sample_rotate[X_sample_rotate > 300] = 0\n\n# Hãy chuẩn hóa các giá trị pixel thành khoảng [0,1]\n# Công thức: MinMaxscale(X) = (X - X_min) / (X_max - X_min)\n\nprint(\"Before applying MinMax Scaler:\")\nprint(\"  - Minimum value:\", X_sample_rotate.min())\nprint(\"  - Maximum value:\", X_sample_rotate.max())\n\nminmax_scaler = MinMaxScaler()\n\nfor k0 in range(10):\n    for k1 in range(numRotate_prior):\n        X_sample_rotate[k0,k1,:,:] = minmax_scaler.fit_transform(X_sample_rotate[k0,k1,:,:]) * 255\n\nprint(\"\\nAfter applying MinMax Scaler:\")\nprint(\"  - Minimum value:\", X_sample_rotate.min())\nprint(\"  - Maximum value:\", X_sample_rotate.max())\n\n\n\n# Tiếp theo, hãy hình dung một hình ảnh từ mỗi lớp.\n# Chúng ta sẽ sử dụng hàm 'imshow' của matplotlib.\n\n# cho k2 trong phạm vi (numPickRotate):\nfor k2 in range(5,10):\n    k1 = 0\n    # k1 = numRotate_prior - 1\n\n    fig, axs = plt.subplots(nrows=2, ncols=5, figsize=(10,5))\n\n    for k0 in range(10):\n        img = axs[int(k0 >= 5), k0%5].imshow(\n            X=X_sample_rotate[k0,k1,k2,:].reshape(28, 28),\n            cmap='Blues'\n        )\n        img.axes.get_yaxis().set_visible(False)\n        img.axes.get_xaxis().set_visible(False)\n        img.axes.set_title(f'Label: {k0}')\n        \nX_train_rotate = np.reshape(X_sample_rotate, (-1,784))\ny_train_rotate = np.reshape(y_sample_rotate, (-1,1)).flatten()","metadata":{"_uuid":"2fd8cd6b-8db8-45dc-b5f7-6721c80f11fd","_cell_guid":"6b163e1f-7fee-43a6-b6f6-40c0d402a4fc","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:49.156290Z","iopub.execute_input":"2024-06-10T16:27:49.156665Z","iopub.status.idle":"2024-06-10T16:27:55.417679Z","shell.execute_reply.started":"2024-06-10T16:27:49.156632Z","shell.execute_reply":"2024-06-10T16:27:55.416143Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---------\n# Phần 3: Phân tích thành phần chính","metadata":{"_uuid":"f67ae6c7-11f8-4b88-a23e-bf62fb9fdb43","_cell_guid":"6e9093b4-f586-4545-b99e-b59d492b7958","trusted":true}},{"cell_type":"markdown","source":"Phân tích thành phần chính (PCA) là một kỹ thuật thống kê để giảm tính chiều của tập dữ liệu. Điều này được thực hiện bằng cách chuyển đổi tuyến tính dữ liệu sang một hệ tọa độ mới trong đó (hầu hết) sự thay đổi trong dữ liệu có thể được mô tả với ít thứ nguyên hơn dữ liệu ban đầu.\n\nThành phần chính đầu tiên có thể được định nghĩa một cách tương đương là hướng tối đa hóa phương sai của dữ liệu dự kiến. Thành phần chính thứ i có thể được lấy làm hướng trực giao với thành phần chính thứ i-1 để tối đa hóa phương sai của dữ liệu dự kiến.\n\nsklearn.decomposition.PCA: Giảm kích thước tuyến tính bằng cách sử dụng Phân tách giá trị đơn lẻ của dữ liệu để chiếu dữ liệu đó vào không gian có chiều thấp hơn.\n\nỞ đây chúng ta sẽ sử dụng 10 thành phần chính hàng đầu, giải thích gần 50% phương sai trong dữ liệu. Điều này có nghĩa là chúng ta có thể biểu thị 50% phương sai của dữ liệu với không gian tính năng nhỏ hơn >98% so với dữ liệu ban đầu (10 tính năng so với 784 tính năng)","metadata":{"_uuid":"c9145741-6e7a-4419-bdb0-baca414ed4e7","_cell_guid":"54390ba7-75cb-4867-b577-97f23c85d6f2","trusted":true}},{"cell_type":"code","source":"# Hãy chuẩn hóa các giá trị pixel thành khoảng [0,1]\n# Công thức: MinMaxscale(X) = (X - X_min) / (X_max - X_min)\n\nprint(\"Before applying MinMax Scaler:\")\nprint(\"  - Minimum value:\", X_train.min())\nprint(\"  - Maximum value:\", X_train.max())\n\nminmax_scaler = MinMaxScaler()\nX_train_rotate_scaled = minmax_scaler.fit_transform(X_train_rotate)\n\nprint(\"\\nAfter applying MinMax Scaler:\")\nprint(\"  - Minimum value:\", X_train_rotate_scaled.min())\nprint(\"  - Maximum value:\", X_train_rotate_scaled.max())","metadata":{"_uuid":"aad53bf6-9b1f-4451-844d-ae51f509a68f","_cell_guid":"2f528db2-3b92-425b-a18c-2168dd8862d7","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:55.424529Z","iopub.execute_input":"2024-06-10T16:27:55.425963Z","iopub.status.idle":"2024-06-10T16:27:55.548556Z","shell.execute_reply.started":"2024-06-10T16:27:55.425906Z","shell.execute_reply":"2024-06-10T16:27:55.547378Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Trên thực tế, chúng tôi sẽ nhúng MinMaxScaler và PCA\n# mô-đun vào Đường ống Sklearn.\n\npca = Pipeline(steps=[\n    ('scaler', MinMaxScaler()),\n    ('pca', PCA(n_components=40))\n])\n\nX_train_rotate_pca = pca.fit_transform(X=X_train_rotate)\n\nprint('X_train_pca shape:', X_train_rotate_pca.shape)","metadata":{"_uuid":"6cae5170-3af3-4ed9-a9d8-372ef224e9ba","_cell_guid":"e423b865-ef1d-4c48-9152-917f8b258060","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:55.549736Z","iopub.execute_input":"2024-06-10T16:27:55.550076Z","iopub.status.idle":"2024-06-10T16:27:57.056099Z","shell.execute_reply.started":"2024-06-10T16:27:55.550043Z","shell.execute_reply":"2024-06-10T16:27:57.054767Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Hãy trích xuất tỷ lệ phương sai được giải thích\n# Và hãy tính tổng tích lũy của chúng\n\npca_object = pca.named_steps['pca']\nvar_ratio = pd.Series(\n    data=pca_object.explained_variance_ratio_,\n    index=range(1, 41)\n)\n\ncumsum_var_ratio = var_ratio.cumsum()","metadata":{"_uuid":"68b1ffab-f2de-43fe-a655-e04c6060ec60","_cell_guid":"c3cdf97b-6136-45e0-94c6-bdf23e750bf0","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:57.058000Z","iopub.execute_input":"2024-06-10T16:27:57.059622Z","iopub.status.idle":"2024-06-10T16:27:57.070587Z","shell.execute_reply.started":"2024-06-10T16:27:57.059579Z","shell.execute_reply":"2024-06-10T16:27:57.069451Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Vẽ biểu đồ tỷ lệ phương sai giải thích cho từng thành phần (trái)\n# Và vẽ tổng tích lũy của chúng (phải)\n\nfig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15,5))\n\nsns.barplot(\n    x=var_ratio.index, \n    y=var_ratio.values, \n    color='#4895EE', \n    ax=ax1\n)\nax1.set(\n    title='Explained Variance Ratio PCA',\n    xlabel='Component',\n    ylabel='Var Ratio',\n)\nax1.set_ylim(0, 0.5)\n\nsns.barplot(\n    x=cumsum_var_ratio.index, \n    y=cumsum_var_ratio.values, \n    color='#4895EE', \n    ax=ax2\n)\nax2.set(\n    title='Cumulative Explained Variance Ratio PCA',\n    xlabel='Component',\n    ylabel='Cumulative Var Ratio',\n)\n_ = ax2.set_ylim(0, 0.5)","metadata":{"_uuid":"9ea36679-af0c-40f1-bda2-641ef9c73a4e","_cell_guid":"6fe44c61-1ac9-4157-968d-022d42184ff6","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:57.073597Z","iopub.execute_input":"2024-06-10T16:27:57.075560Z","iopub.status.idle":"2024-06-10T16:27:58.444623Z","shell.execute_reply.started":"2024-06-10T16:27:57.075510Z","shell.execute_reply":"2024-06-10T16:27:58.443389Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Hãy đặt các thành phần ở định dạng Pandas DataFrame\n# Bằng cách này chúng ta có thể sử dụng các thư viện seaborn và âm mưu\n# để trực quan hóa dữ liệu.\n# (các gói này hoạt động tốt hơn với Pandas DataFrames)\n\ndf_train_pca = pd.DataFrame(\n    data=X_train_rotate_pca[:,:3], \n    columns=['x', 'y', 'z']\n)\n# Hãy thêm mục tiêu để đặt màu\ndf_train_pca['target'] = y_train_rotate\n\nprint(df_train_pca.shape)\ndf_train_pca.head()","metadata":{"_uuid":"9796e066-c6af-49c5-af8f-8ebde5e07430","_cell_guid":"4fb22220-cc87-410b-a637-55bc57791987","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:58.446202Z","iopub.execute_input":"2024-06-10T16:27:58.446678Z","iopub.status.idle":"2024-06-10T16:27:58.463167Z","shell.execute_reply.started":"2024-06-10T16:27:58.446636Z","shell.execute_reply":"2024-06-10T16:27:58.462093Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Trực quan hóa hai chiều của dữ liệu\n# Ở đây các thành phần chính của Top2 được vẽ\n\nsns.set_style(\"dark\")\nax = sns.scatterplot(\n    data=df_train_pca,\n    x='x', \n    y='y', \n    hue='target', \n    palette='Blues',\n)\nax.set(\n    title='PCA Two-Dimensional Projection',\n    xlabel='1st Comp.',\n    ylabel='2nd Comp.'\n)\nax.axhline(y=0, linestyle='--', color='#FFBF00', zorder=-1)\nax.axvline(x=0, linestyle='--', color='#FFBF00', zorder=-1)","metadata":{"_uuid":"30135dee-d7d0-4dc8-88f7-3a88a135ad5a","_cell_guid":"147fd5ee-e632-4611-b6de-35d64c6946e9","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:58.464594Z","iopub.execute_input":"2024-06-10T16:27:58.464936Z","iopub.status.idle":"2024-06-10T16:27:59.752851Z","shell.execute_reply.started":"2024-06-10T16:27:58.464908Z","shell.execute_reply":"2024-06-10T16:27:59.751474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Bây giờ, hãy áp dụng biến đổi nghịch đảo để tính toán\n# sự gần đúng của hình ảnh dựa trên nguyên tắc 10\n#thành phần.\n# Chúng ta có thể thấy rằng chỉ với 10 thành phần chúng ta đã truyền tải được một lượng lớn\n# một phần thông tin của mỗi hình ảnh.\n\npca_object = pca.named_steps['pca']\n\nfig, axs = plt.subplots(nrows=10, ncols=2, figsize=(6,20))\n\nfor i in range(10):\n    idx = np.where(y_train==i)[0][0]\n    original_img = axs[i, 0].imshow(\n        X=X_train_rotate[idx].reshape(28, 28),\n        cmap='Blues'\n    )\n    original_img.axes.get_yaxis().set_visible(False)\n    original_img.axes.get_xaxis().set_visible(False)\n    original_img.axes.set_title(f'Original [{i}]:')\n    \n    approx_img_ = pca_object.inverse_transform(X=X_train_rotate_pca[idx])\n    approx_img = axs[i, 1].imshow(\n        X=approx_img_.reshape(28, 28),\n        cmap='Blues'\n    )\n    approx_img.axes.get_yaxis().set_visible(False)\n    approx_img.axes.get_xaxis().set_visible(False)\n    approx_img.axes.set_title(f'Approximation [{i}]:')","metadata":{"_uuid":"77146579-275e-4359-8ec9-7d175da30220","_cell_guid":"329c95b3-2406-402c-b1f8-38487c4fa2f3","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:27:59.754329Z","iopub.execute_input":"2024-06-10T16:27:59.754796Z","iopub.status.idle":"2024-06-10T16:28:00.746720Z","shell.execute_reply.started":"2024-06-10T16:27:59.754753Z","shell.execute_reply":"2024-06-10T16:28:00.745483Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Chứng tỏ các thành phần PCA không tương quan\n# (Câu nói này đúng về mặt định nghĩa và cách xây dựng\n# của thuật toán Phân tích thành phần chính)\n\ncorr = np.corrcoef(x=X_train_rotate_pca, rowvar=False)\ncorr = np.around(corr, decimals=2)\n\nax = sns.heatmap(\n    data=corr, \n    vmax=1, \n    vmin=-1,\n    square=True,\n    linewidths=.5,\n    annot=True,\n    cmap='Blues',\n)\n\n_ = ax.set(\n    title='Correlation PCA Components [Uncorrelated]',\n    xlabel='Components',\n    ylabel='Components'\n)","metadata":{"_uuid":"8c3fa8bb-61ab-43dc-bc7e-e5fecc13e6e2","_cell_guid":"ab321270-3628-423b-8fd6-a7ebaf6ccfe5","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:28:00.748241Z","iopub.execute_input":"2024-06-10T16:28:00.748683Z","iopub.status.idle":"2024-06-10T16:28:04.942722Z","shell.execute_reply.started":"2024-06-10T16:28:00.748644Z","shell.execute_reply":"2024-06-10T16:28:04.941449Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"----\n# Phần 4: Sử dụng K-Nearest Neighbors Classifier phân loại 10 thành phần chính hàng đầu từ PCA.","metadata":{"_uuid":"3d69b1a4-faf3-4405-b740-9d5fc82b8424","_cell_guid":"16cefed3-22ad-4c84-ad87-230ed47df34d","trusted":true}},{"cell_type":"markdown","source":"Thuật toán K-Nearest Neighbors là một thuật toán phân loại học tập có giám sát, không tham số, sử dụng độ gần để phân loại hoặc dự đoán về việc nhóm một điểm dữ liệu riêng lẻ. Dự đoán: Nhãn lớp được chỉ định trên cơ sở đa số phiếu bầu. nhãn được thể hiện thường xuyên nhất xung quanh một điểm dữ liệu nhất định.\n\nTrong dự án này, đầu vào của Bộ phân loại KNN sẽ là 10 thành phần chính hàng đầu từ PCA.\n\nsklearn.neighbors.KNeighborsClassifier: Trình phân loại thực hiện bỏ phiếu k-hàng xóm gần nhất. Chúng ta sẽ chạy GridSearchCV để tối ưu hóa siêu tham số n_neighbors.","metadata":{"_uuid":"1abd82c5-f4e1-4142-acb2-bea45e42488e","_cell_guid":"b9e0603d-4dc8-4761-baad-a34cf6709975","trusted":true}},{"cell_type":"markdown","source":"---\n#  mô hình học máy trên tập dữ liệu Train","metadata":{"_uuid":"334a6d45-a6b2-499e-a95b-2477800b968f","_cell_guid":"e1b5a3d3-ced9-409c-b6f9-b07e7143bc66","trusted":true}},{"cell_type":"code","source":"knn_clf = Pipeline(steps=[\n    ('scaler', MinMaxScaler()),\n    ('pca', PCA(n_components=10)),\n    ('knn', KNeighborsClassifier())\n])\n\nknn_clf_params = {\n    'knn__n_neighbors': [2, 4, 8, 16, 32]\n}\n\nknn_clf_gs = GridSearchCV(\n    estimator=knn_clf, \n    param_grid=knn_clf_params,\n    scoring='accuracy',\n    n_jobs=-1,\n    cv=5,\n    verbose=1,\n    return_train_score=True\n)\n\nknn_clf_gs.fit(X=X_train_rotate_pca, y=y_train_rotate)\n\nprint('best PCA+KNN params:', knn_clf_gs.best_params_)\nprint('best PCA+KNN cv accuracy:', knn_clf_gs.best_score_)","metadata":{"_uuid":"7154a244-1406-4e55-9062-2a876ffcfb42","_cell_guid":"f8b23485-498b-446c-83a4-fdf1e50b8285","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:28:04.944105Z","iopub.execute_input":"2024-06-10T16:28:04.944572Z","iopub.status.idle":"2024-06-10T16:28:22.593899Z","shell.execute_reply.started":"2024-06-10T16:28:04.944513Z","shell.execute_reply":"2024-06-10T16:28:22.592407Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Vẽ sơ đồ độ chính xác trong đào tạo và xác nhận\n# cho mỗi giá trị Siêu tham số được kiểm tra trong quá trình\n# Tìm kiếm lưới.\n# Biểu đồ này cho phép chúng ta kiểm tra xem có trang bị quá mức hay không.\nfig, ax = plt.subplots()\n\nax.plot(\n    range(len(knn_clf_params['knn__n_neighbors'])), \n    knn_clf_gs.cv_results_['mean_train_score'],\n    label='train',\n    color='blue'\n)\nax.plot(\n    range(len(knn_clf_params['knn__n_neighbors'])),\n    knn_clf_gs.cv_results_['mean_test_score'],\n    label='test',\n    color='orange'\n)\nax.set_xticks(\n    ticks=range(len(knn_clf_params['knn__n_neighbors'])),\n    labels=knn_clf_params['knn__n_neighbors']\n)\n\nii = knn_clf_params['knn__n_neighbors'].index(\n    knn_clf_gs.best_params_['knn__n_neighbors']\n)\n\nplt.axvline(x=ii, linestyle='--', color='red', label='best', alpha=0.3)\nplt.legend()\nplt.xlabel(\"'n_neighbors' vals\")\nplt.ylabel('Accuracy')\nplt.title(\"PCA+KNN GridSearchCV Results\")\nplt.show()","metadata":{"_uuid":"43e1d701-a89a-463f-b860-3afbf14bbf36","_cell_guid":"b1316942-7e1c-4f06-8742-d3eb8f7918c3","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:28:22.596062Z","iopub.execute_input":"2024-06-10T16:28:22.597333Z","iopub.status.idle":"2024-06-10T16:28:23.147050Z","shell.execute_reply.started":"2024-06-10T16:28:22.597260Z","shell.execute_reply":"2024-06-10T16:28:23.145685Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---\n# Phần 5: Tạo một tệp tin chứa các dự đoán của mô hình học máy trên tập dữ liệu Test","metadata":{"_uuid":"b609f283-8a5c-477c-9c29-941acfedc9aa","_cell_guid":"5d9eb764-a90a-48b5-b962-be1b347e4925","trusted":true}},{"cell_type":"code","source":"from sklearn.metrics import accuracy_score\n\n# Tính toán và hiển thị Ma trận nhầm lẫn\n# Lưu ý: toàn bộ tập dữ liệu huấn luyện được sử dụng ở đây\n\nX_val = X_train_rotate_pca\nY_val = y_train_rotate\n\nbest_cv_clf = knn_clf_gs.best_estimator_\ny_pred = best_cv_clf.predict(X=X_val)\n\ny_val_number = Y_val // numRotate_prior\ny_pred_number = y_pred // numRotate_prior\n\ny_val_angle = (Y_val % numRotate_prior)\ny_pred_angle = (y_pred % numRotate_prior)\n\nprint('KNN number + angle, Acc({:.2f}%)', accuracy_score(Y_val, y_pred))\nprint('KNN number, Acc({:.2f}%)', accuracy_score(y_val_number, y_pred_number))\nprint('KNN angle, Acc({:.2f}%)', accuracy_score(y_val_angle, y_pred_angle))\n\n# print('y_val_number =', y_val_number)\n# print('y_pred_number =', y_pred_number)\n\ny_val_angle_degree = y_val_angle/numRotate_prior * angleRange_prior + angleOffset_prior\ny_pred_angle_degree = y_pred_angle/numRotate_prior * angleRange_prior + angleOffset_prior\n\n# print('y_val_angle_degree =', y_val_angle_degree)\n# print('y_pred_angle_degree =', y_pred_angle_degree)\n\nconf_matrix = confusion_matrix(y_val_number, y_pred_number)\nconf_matrix_disp = ConfusionMatrixDisplay(conf_matrix)\nconf_matrix_disp.plot(cmap='Blues')\n\nconf_matrix = confusion_matrix(y_val_angle, y_pred_angle)\nconf_matrix_disp = ConfusionMatrixDisplay(conf_matrix)\nconf_matrix_disp.plot(cmap='Blues')","metadata":{"_uuid":"62d7493a-d5c0-42ca-ad56-df419c3367ee","_cell_guid":"fdfdc4ce-7aa6-4c8a-b7c9-8a069cb98054","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:28:23.148623Z","iopub.execute_input":"2024-06-10T16:28:23.148989Z","iopub.status.idle":"2024-06-10T16:28:26.330646Z","shell.execute_reply.started":"2024-06-10T16:28:23.148955Z","shell.execute_reply":"2024-06-10T16:28:26.329569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_val = pca.transform(X_train)\nY_val = y_train\n\nbest_cv_clf = knn_clf_gs.best_estimator_\ny_pred = best_cv_clf.predict(X=X_val)\n\ny_pred_number = y_pred\ny_val_number = Y_val\n\nprint('KNN number, Acc({:.2f}%)', accuracy_score(y_val_number, y_pred_number))\n\nconf_matrix = confusion_matrix(y_val_number, y_pred_number)\nconf_matrix_disp = ConfusionMatrixDisplay(conf_matrix)\nconf_matrix_disp.plot(cmap='Blues')\n\ny_pred_angle = (y_pred % numRotate_prior)\n\ny_pred_angle_degree = y_pred_angle/numRotate_prior * angleRange_prior + angleOffset_prior\n\nprint('y_pred_angle_degree =', y_pred_angle_degree)","metadata":{"_uuid":"da419e38-d545-49ee-a8b6-32f3fa9760c3","_cell_guid":"fa5652c2-d596-4880-8396-b6e77177f4ff","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:28:26.332125Z","iopub.execute_input":"2024-06-10T16:28:26.332576Z","iopub.status.idle":"2024-06-10T16:28:56.182112Z","shell.execute_reply.started":"2024-06-10T16:28:26.332534Z","shell.execute_reply":"2024-06-10T16:28:56.180731Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Bây giờ, hãy áp dụng biến đổi nghịch đảo để tính toán\n# sự gần đúng của hình ảnh dựa trên nguyên tắc 10\n#thành phần.\n# Chúng ta có thể thấy rằng chỉ với 10 thành phần chúng ta đã truyền tải được một lượng lớn\n# một phần thông tin của mỗi hình ảnh.\n\npca_object = pca.named_steps['pca']\n\nfig, axs = plt.subplots(nrows=10, ncols=2, figsize=(6,20))\n\nfor i in range(10):\n    idx = np.where(y_train == i )[0][0]\n    original_img = axs[i, 0].imshow(\n        X=X_train[idx].reshape(28, 28),\n        cmap='Blues'\n    )\n    original_img.axes.get_yaxis().set_visible(False)\n    original_img.axes.get_xaxis().set_visible(False)\n    original_img.axes.set_title(f'Original [{i}]:')\n    \n    approx_img_ = pca_object.inverse_transform(X=X_val[idx])\n    approx_img = axs[i, 1].imshow(\n        X=approx_img_.reshape(28, 28),\n        cmap='Blues'\n    )\n    approx_img.axes.get_yaxis().set_visible(False)\n    approx_img.axes.get_xaxis().set_visible(False)\n    approx_img.axes.set_title(f'Predicted angle [{y_pred_angle_degree[idx]}]:')","metadata":{"_uuid":"bc4e4c18-00b8-4441-900b-83786685d798","_cell_guid":"1393d26a-3a87-4a77-a642-c5b68c94fec3","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:28:56.183635Z","iopub.execute_input":"2024-06-10T16:28:56.184121Z","iopub.status.idle":"2024-06-10T16:28:57.125938Z","shell.execute_reply.started":"2024-06-10T16:28:56.184077Z","shell.execute_reply":"2024-06-10T16:28:57.124644Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div class=\"text_cell_render border-box-sizing rendered_html\">\n<div style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:gray;\n           font-size:110%;\n           font-family:Verdana;\n           letter-spacing:0.5px\">\n<h1 style=\"text-align: center;\n           padding: 10px;\n              color:white\">\nLight CNN Classifier\n</h1>\n</div>\n</div>","metadata":{"_uuid":"a1446365-443d-48e8-aa24-514805f2df61","_cell_guid":"f6dca012-b643-484b-8f63-b0e218c6f1e2","trusted":true}},{"cell_type":"markdown","source":"<img src=\"https://taewanmerepo.github.io/2018/01/cnn/head.png\">","metadata":{"_uuid":"5a238d9f-7fbe-4d2a-85c7-b38f1793fe47","_cell_guid":"d606a8da-01ba-4650-b234-842037898d97","trusted":true}},{"cell_type":"markdown","source":"### CNN is a very efficient ways for computer vision tasks. \na convolutional neural network (CNN, or ConvNet) is a class of Artificial Neural Network (ANN), most commonly applied to analyze visual imagery. They are also known as Shift Invariant or Space Invariant Artificial Neural Networks (SIANN), based on the shared-weight architecture of the convolution kernels or filters that slide along input features and provide translation equivariant responses known as feature maps. Counter-intuitively, most convolutional neural networks are only equivariant, as opposed to invariant, to translation. They have applications in image and video recognition, recommender systems, image classification, image segmentation, medical image analysis, natural language processing, brain-computer interfaces, and financial time series.","metadata":{"_uuid":"3f62053b-0364-4ff6-bb7b-5deba2a02280","_cell_guid":"1c349770-f9d8-4f7f-8efb-d87b402f2f10","trusted":true}},{"cell_type":"code","source":"import plotly.express as px\nfrom plotly.offline import init_notebook_mode, iplot\nimport plotly.graph_objects as go\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"execution":{"iopub.status.busy":"2024-06-10T16:28:57.127696Z","iopub.execute_input":"2024-06-10T16:28:57.128051Z","iopub.status.idle":"2024-06-10T16:28:57.159631Z","shell.execute_reply.started":"2024-06-10T16:28:57.128022Z","shell.execute_reply":"2024-06-10T16:28:57.158187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_confusion_matrix(cm, labels, title):\n    # cm : danh sách ma trận nhầm lẫn(danh sách)\n    # nhãn : tên danh sách dữ liệu(str)\n    #tiêu đề : tiêu đề cho bản đồ nhiệt\n    data = go.Heatmap(z=cm, y=labels, x=labels)\n    annotations = []\n    for i, row in enumerate(cm):\n        for j, value in enumerate(row):\n            annotations.append(\n                {\n                    \"x\": labels[i],\n                    \"y\": labels[j],\n                    \"font\": {\"color\": \"white\"},\n                    \"text\": str(value),\n                    \"xref\": \"x1\",\n                    \"yref\": \"y1\",\n                    \"showarrow\": False\n                }\n            )\n    layout = {\n        \"title\": title,\n        \"xaxis\": {\"title\": \"Predicted value\"},\n        \"yaxis\": {\"title\": \"Real value\"},\n        \"annotations\": annotations\n    }\n    fig = go.Figure(data=data, layout=layout)\n    return fig","metadata":{"execution":{"iopub.status.busy":"2024-06-10T16:28:57.161458Z","iopub.execute_input":"2024-06-10T16:28:57.161860Z","iopub.status.idle":"2024-06-10T16:28:57.170384Z","shell.execute_reply.started":"2024-06-10T16:28:57.161825Z","shell.execute_reply":"2024-06-10T16:28:57.169150Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# từ tensorflow.keras.utils nhập np_utils\nfrom tensorflow.keras import utils\nfrom tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping\nfrom tensorflow.keras import datasets, layers, models","metadata":{"_uuid":"17fc4707-d986-4950-b0fe-ac152932ac00","_cell_guid":"0d0efe69-4e03-4204-86d8-3ee2e5125830","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:28:57.172054Z","iopub.execute_input":"2024-06-10T16:28:57.172608Z","iopub.status.idle":"2024-06-10T16:29:10.347510Z","shell.execute_reply.started":"2024-06-10T16:28:57.172563Z","shell.execute_reply":"2024-06-10T16:29:10.346203Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train_cnn = X_train_rotate.reshape(-1,28,28,1)\n# X_val = np.array(pca.transform(X_train)).reshape(-1,28,28,1)\ny_train_cnn = utils.to_categorical(np.array(y_train_rotate// numRotate_prior))\nX_val = X_train.reshape(-1,28,28,1)\nY_val = utils.to_categorical(np.array(y_train))","metadata":{"_uuid":"598e24f0-4665-4486-ba5d-fb550022bc96","_cell_guid":"b20ca6f3-b288-42fe-8210-9e804c27268e","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:29:10.348986Z","iopub.execute_input":"2024-06-10T16:29:10.349915Z","iopub.status.idle":"2024-06-10T16:29:10.359858Z","shell.execute_reply.started":"2024-06-10T16:29:10.349870Z","shell.execute_reply":"2024-06-10T16:29:10.358923Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train_cnn.shape","metadata":{"execution":{"iopub.status.busy":"2024-06-10T16:29:10.361186Z","iopub.execute_input":"2024-06-10T16:29:10.361621Z","iopub.status.idle":"2024-06-10T16:29:10.397670Z","shell.execute_reply.started":"2024-06-10T16:29:10.361582Z","shell.execute_reply":"2024-06-10T16:29:10.396328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# y_train_rotate// numRotate_prior","metadata":{"execution":{"iopub.status.busy":"2024-06-10T16:29:10.399070Z","iopub.execute_input":"2024-06-10T16:29:10.399508Z","iopub.status.idle":"2024-06-10T16:29:10.407793Z","shell.execute_reply.started":"2024-06-10T16:29:10.399465Z","shell.execute_reply":"2024-06-10T16:29:10.406591Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# X_train_rotate = np.array(X_train_rotate).reshape(-1,28,28,1)\n# # X_val = np.array(pca.transform(X_train)).reshape(-1,28,28,1)\n# X_val = np.array(X_test_crop).reshape(-1,28,28,1)\n# y_train_rotate = utils.to_categorical(np.array(y_train_rotate))\n# Y_val = utils.to_categorical(np.array(y_test_crop))","metadata":{"_uuid":"f978abbd-867f-46a5-b6ec-35f64e740f64","_cell_guid":"9d27fd4b-f9a8-4c46-a856-7e8970246998","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:29:10.409308Z","iopub.execute_input":"2024-06-10T16:29:10.410363Z","iopub.status.idle":"2024-06-10T16:29:10.422569Z","shell.execute_reply.started":"2024-06-10T16:29:10.410304Z","shell.execute_reply":"2024-06-10T16:29:10.421463Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = models.Sequential()\nmodel.add(layers.Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same', \n                 activation ='relu', input_shape = (28,28,1)))\nmodel.add(layers.Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same', \n                 activation ='relu'))\nmodel.add(layers.MaxPool2D(pool_size=(2,2)))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.Dropout(0.25))\nmodel.add(layers.Conv2D(filters = 64, kernel_size = (3,3),padding = 'Same', \n                 activation ='relu'))\nmodel.add(layers.Conv2D(filters = 64, kernel_size = (3,3),padding = 'Same', \n                 activation ='relu'))\nmodel.add(layers.MaxPool2D(pool_size=(2,2), strides=(2,2)))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.Dropout(0.25))\nmodel.add(layers.Flatten())\nmodel.add(layers.Dense(256, activation = \"relu\"))\nmodel.add(layers.Dropout(0.5))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.Dense(10, activation = \"softmax\"))\n\nmodel.summary()","metadata":{"_uuid":"d30da279-3261-4e97-9b79-6e2a01d703d4","_cell_guid":"43ead369-05c5-4e2d-960c-d5773b8a7f7d","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:29:10.424285Z","iopub.execute_input":"2024-06-10T16:29:10.424796Z","iopub.status.idle":"2024-06-10T16:29:10.802996Z","shell.execute_reply.started":"2024-06-10T16:29:10.424752Z","shell.execute_reply":"2024-06-10T16:29:10.801779Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_path = './best_model.h5'\ncheckpointer = ModelCheckpoint(\n    filepath=model_path,\n    monitor='val_accuracy',\n    verbose=1,\n    mode='max',\n    save_best_only=True)\n\nmodel.compile(loss='categorical_crossentropy',\n             optimizer='adam',\n             metrics=['accuracy'])","metadata":{"_uuid":"d131aa49-918d-43dd-be19-62d3110ca17a","_cell_guid":"db889d42-b8bb-4667-8f07-b831a3fbcf38","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:29:10.804708Z","iopub.execute_input":"2024-06-10T16:29:10.805099Z","iopub.status.idle":"2024-06-10T16:29:10.828709Z","shell.execute_reply.started":"2024-06-10T16:29:10.805053Z","shell.execute_reply":"2024-06-10T16:29:10.827594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(X_train_cnn, y_train_cnn, validation_data = (X_val, Y_val), epochs=50, batch_size = 128, callbacks=[checkpointer])","metadata":{"_uuid":"620687bc-89d9-40dc-b133-006fef4e7c78","_cell_guid":"cd8420f8-3c35-407f-93de-b1691d1b534f","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T16:29:10.830085Z","iopub.execute_input":"2024-06-10T16:29:10.830447Z","iopub.status.idle":"2024-06-10T17:13:51.224958Z","shell.execute_reply.started":"2024-06-10T16:29:10.830391Z","shell.execute_reply":"2024-06-10T17:13:51.223928Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import plotly.graph_objects as go\nfrom plotly.subplots import make_subplots\nimport numpy as np\n\nfig = go.Figure()\n\nlabels = ['Loss', 'Accuracy']\ncolors = ['rgb(67,67,67)', 'rgb(49,130,189)']\n\nmode_size = [8, 8]\nline_size = [2, 2]\n\nx_data = np.vstack((np.arange(1, 51),)*2)\n\ny_data = np.array([\n    np.array(history.history['loss']), \n                      np.array(history.history['accuracy'])\n])\n\nfor i in range(0, 2):\n    fig.add_trace(go.Scatter(x=x_data[i], y=y_data[i], mode='lines',\n        name=labels[i],\n        line=dict(color=colors[i], width=line_size[i]),\n        connectgaps=True,\n    ))\n\n    # điểm cuối\n    fig.add_trace(go.Scatter(\n        x=[x_data[i][0], x_data[i][-1]],\n        y=[y_data[i][0], y_data[i][-1]],\n        mode='markers',\n        marker=dict(color=colors[i], size=mode_size[i])\n    ))\n\nfig.update_layout(\n    xaxis=dict(\n        showline=True,\n        showgrid=False,\n        showticklabels=True,\n        linecolor='rgb(204, 204, 204)',\n        linewidth=2,\n        ticks='outside',\n        tickfont=dict(\n            family='Arial',\n            size=12,\n            color='rgb(82, 82, 82)',\n        ),\n    ),\n    yaxis=dict(\n        showgrid=False,\n        zeroline=False,\n        showline=False,\n        showticklabels=False,\n    ),\n    autosize=False,\n    margin=dict(\n        autoexpand=False,\n        l=100,\n        r=20,\n        t=110,\n    ),\n    showlegend=False,\n    plot_bgcolor='white'\n)\n\nannotations = []\n\n# thêm nhãn\nfor y_trace, label, color in zip(y_data, labels, colors):\n   # dán nhãn phía bên trái của ô\n    annotations.append(dict(xref='paper', x=0.05, y=y_trace[0],\n                                  xanchor='right', yanchor='middle',\n                                  text=label + ' {:.2f}'.format(y_trace[0]),\n                                  font=dict(family='Arial',\n                                            size=16),\n                                  showarrow=False))\n  #ghi nhãn bên phải của cốt truyện\n    annotations.append(dict(xref='paper', x=0.95, y=y_trace[49],\n                                  xanchor='left', yanchor='middle',\n                                  text='{:.4f}%'.format(y_trace[49]),\n                                  font=dict(family='Arial',\n                                            size=16),\n                                  showarrow=False))\n# Nội dung\nannotations.append(dict(xref='paper', yref='paper', x=0.0, y=1.05,\n                              xanchor='left', yanchor='bottom',\n                              text='Training Loss & Accuracy',\n                              font=dict(family='Arial',\n                                        size=30,\n                                        color='rgb(37,37,37)'),\n                              showarrow=False))\n# nguồn\nannotations.append(dict(xref='paper', yref='paper', x=0.5, y=-0.1,\n                              xanchor='center', yanchor='top',\n                              text='Epochs',\n                              font=dict(family='Arial',\n                                        size=12,\n                                        color='rgb(150,150,150)'),\n                              showarrow=False))\n\nfig.update_layout(annotations=annotations,height=600, width=1000)\n\nfig.show()","metadata":{"_uuid":"b2a98a55-6032-40d1-8bbf-bf6b35840730","_cell_guid":"7fcbf806-1db3-45b9-8bc0-3abf08dfabd9","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T17:13:51.226682Z","iopub.execute_input":"2024-06-10T17:13:51.226990Z","iopub.status.idle":"2024-06-10T17:13:51.595010Z","shell.execute_reply.started":"2024-06-10T17:13:51.226961Z","shell.execute_reply":"2024-06-10T17:13:51.593897Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"_uuid":"c51476fa-c9d6-4cbc-a5ad-f6ff9706d70e","_cell_guid":"8bdfa1eb-cd3b-4e48-a377-02b2b66506e1","collapsed":false,"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.models import load_model\nmodel = load_model('./best_model.h5')\ny_pred = model.predict(X_val)\nM = confusion_matrix(np.argmax(Y_val,1), np.argmax(y_pred,1))\nplot_confusion_matrix(M, sorted(np.unique(np.argmax(Y_val,1))), 'Simple CNN Confusion Matrix, Acc({:.2f}%)'.format(accuracy_score(np.argmax(Y_val,1), np.argmax(y_pred,1))*100))","metadata":{"_uuid":"57a8380a-11c2-45fb-8190-4e9da5bce1ed","_cell_guid":"bdeca8dc-2a69-4598-b508-873212a964dd","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T17:13:51.601601Z","iopub.execute_input":"2024-06-10T17:13:51.601960Z","iopub.status.idle":"2024-06-10T17:14:23.954821Z","shell.execute_reply.started":"2024-06-10T17:13:51.601928Z","shell.execute_reply":"2024-06-10T17:14:23.953691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div class=\"text_cell_render border-box-sizing rendered_html\">\n<div style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:gray;\n           font-size:110%;\n           font-family:Verdana;\n           letter-spacing:0.5px\">\n<h1 style=\"text-align: center;\n           padding: 10px;\n              color:white\">\nChecking Failure Cases\n</h1>\n</div>\n</div>","metadata":{"_uuid":"8f029ba0-23b9-4fa0-83a3-eae4a5e4b39b","_cell_guid":"d955f566-e62b-4f51-a801-3de790bca12a","trusted":true}},{"cell_type":"code","source":"n = np.where(np.argmax(y_pred,1)!=np.argmax(Y_val,1))\nn = np.array(n).reshape(-1)\nn","metadata":{"_uuid":"042a5e34-2598-420b-bb05-79a34d48eac3","_cell_guid":"3cea1159-64d0-4e09-88e9-7b2f3a4fc1fb","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T17:14:23.956039Z","iopub.execute_input":"2024-06-10T17:14:23.956357Z","iopub.status.idle":"2024-06-10T17:14:23.969586Z","shell.execute_reply.started":"2024-06-10T17:14:23.956328Z","shell.execute_reply":"2024-06-10T17:14:23.968123Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_val_vis = np.array(X_val).reshape(X_val.shape[0], 28, 28)\nX_val_vis = X_val_vis\nfig, axis = plt.subplots(int(len(n)/8), 8, figsize=(35, 15))\nfor i, ax in enumerate(axis.flat):\n    ax.imshow(X_val_vis[n[i]], cmap='binary')\n    digit = np.argmax(y_pred,1)[n[i]]\n    digit2 = np.argmax(Y_val,1)[n[i]]\n    ax.set(title = f\"Pred Number is {digit}\\n Real Number is {digit2}\");","metadata":{"_uuid":"470a60fd-078e-4a6b-99bf-206ffd71cfb8","_cell_guid":"33ee870d-1eaa-4702-ac0b-7d41a9333040","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-06-10T17:14:23.971210Z","iopub.execute_input":"2024-06-10T17:14:23.971639Z","iopub.status.idle":"2024-06-10T17:17:35.205223Z","shell.execute_reply.started":"2024-06-10T17:14:23.971606Z","shell.execute_reply":"2024-06-10T17:17:35.204119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### It looks like even human can't get the right answers.😅","metadata":{"_uuid":"7b0368af-6a8a-44d9-8dee-e994819269d4","_cell_guid":"11579e1a-7889-4904-ab0f-b96007a7069b","trusted":true}},{"cell_type":"markdown","source":"<div class=\"text_cell_render border-box-sizing rendered_html\">\n<div style=\"color:white;\n           display:fill;\n           border-radius:5px;\n           background-color:gray;\n           font-size:110%;\n           font-family:Verdana;\n           letter-spacing:0.5px\">\n<h1 style=\"text-align: center;\n           padding: 10px;\n              color:white\">\nSubmit to Leaderboard\n</h1>\n</div>\n</div>","metadata":{"_uuid":"b052fb30-6e45-4c66-87af-ce25efdbe87e","_cell_guid":"739fd7c4-6753-4052-8204-a0038c866f87","trusted":true}},{"cell_type":"code","source":"X_test = np.array(df_test).reshape(-1,28,28,1)","metadata":{"execution":{"iopub.status.busy":"2024-06-10T17:17:35.206611Z","iopub.execute_input":"2024-06-10T17:17:35.206946Z","iopub.status.idle":"2024-06-10T17:17:35.279508Z","shell.execute_reply.started":"2024-06-10T17:17:35.206915Z","shell.execute_reply":"2024-06-10T17:17:35.278459Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = load_model('./best_model.h5')\ny_pred = model.predict(X_test)\ny_pred = np.argmax(y_pred,1)\npd_submit = pd.read_csv('../input/digit-recognizer/sample_submission.csv')\npd_submit['Label'] = y_pred\npd_submit.to_csv('submission.csv', header=True, index=False)","metadata":{"execution":{"iopub.status.busy":"2024-06-10T17:17:35.280786Z","iopub.execute_input":"2024-06-10T17:17:35.281115Z","iopub.status.idle":"2024-06-10T17:17:57.208591Z","shell.execute_reply.started":"2024-06-10T17:17:35.281086Z","shell.execute_reply":"2024-06-10T17:17:57.207441Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 📃 References 📃","metadata":{"_uuid":"dc3e2507-cb68-47fb-b3e6-3a0c9c7f84f7","_cell_guid":"e301b5a4-ce01-4ba9-ac3b-40983ec40265","trusted":true}},{"cell_type":"markdown","source":"<div style=\"border-radius: 10px; border: #4361EE solid; padding: 15px; background-color: #ffffff00; font-size: 100%; text-align: left;\">\n    <ul>\n        <li>MNIST database. (2023, September 8). In Wikipedia. [<a href=https://en.wikipedia.org/wiki/MNIST_database>LINK</a>]</li>\n        <li>Principal component analysis. (2023, November 18). In Wikipedia. [<a href=https://en.wikipedia.org/wiki/Principal_component_analysis>LINK</a>]</li>\n        <li>PCA, scikit-learn documentation. [<a href=https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html>LINK</a>]\n        <li>K. (2023, September 27). In Wikipedia. [<a href=https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm>LINK</a>]</li>\n        <li>KNNeighborsClassifier, scikit-learn documentation. [<a href=https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html#sklearn.neighbors.KNeighborsClassifier>LINK</a>]</li>\n    </ul>\n</div>","metadata":{"_uuid":"a9ad3adf-fc21-4ebc-9eb2-d83f80966629","_cell_guid":"f861cd0f-8e0d-48d3-95f9-029e6cf80e84","trusted":true}}]}