{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"<h3>Loading and visualizing the digits data</h3>","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nfrom sklearn.metrics import confusion_matrix\nfrom sklearn.model_selection import train_test_split\nimport plotly.graph_objects as go\nimport plotly.express as px","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:47:59.379203Z","iopub.execute_input":"2021-10-17T07:47:59.380001Z","iopub.status.idle":"2021-10-17T07:48:01.630888Z","shell.execute_reply.started":"2021-10-17T07:47:59.379862Z","shell.execute_reply":"2021-10-17T07:48:01.629984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.read_csv('../input/digit-recognizer/train.csv')","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:52:01.707053Z","iopub.execute_input":"2021-10-17T07:52:01.707345Z","iopub.status.idle":"2021-10-17T07:52:05.388841Z","shell.execute_reply.started":"2021-10-17T07:52:01.707316Z","shell.execute_reply":"2021-10-17T07:52:05.387999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.head()","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:52:10.052716Z","iopub.execute_input":"2021-10-17T07:52:10.053027Z","iopub.status.idle":"2021-10-17T07:52:10.082736Z","shell.execute_reply.started":"2021-10-17T07:52:10.052994Z","shell.execute_reply":"2021-10-17T07:52:10.081873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.shape","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:52:15.251031Z","iopub.execute_input":"2021-10-17T07:52:15.251349Z","iopub.status.idle":"2021-10-17T07:52:15.257578Z","shell.execute_reply.started":"2021-10-17T07:52:15.251304Z","shell.execute_reply":"2021-10-17T07:52:15.256707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h3>Counting unique labels in the dataframe</h3>","metadata":{}},{"cell_type":"code","source":"df_train['label'].value_counts().sort_index()","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:52:24.169426Z","iopub.execute_input":"2021-10-17T07:52:24.169707Z","iopub.status.idle":"2021-10-17T07:52:24.188736Z","shell.execute_reply.started":"2021-10-17T07:52:24.169679Z","shell.execute_reply":"2021-10-17T07:52:24.187841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h3>Dataframe unique labels visualization</h3>","metadata":{}},{"cell_type":"code","source":"fig = px.bar(df_train['label'].value_counts().sort_index(), \n             color=df_train['label'].value_counts().index,\n            labels={\n                     \"value\": \"count\",\n                     \"index\": \"label\",\n                 }\n            )\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:52:41.045858Z","iopub.execute_input":"2021-10-17T07:52:41.046140Z","iopub.status.idle":"2021-10-17T07:52:42.080895Z","shell.execute_reply.started":"2021-10-17T07:52:41.046111Z","shell.execute_reply":"2021-10-17T07:52:42.080046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h3>For speed here, reduce the number of rows in the data frame by selecting 10% of each label value</h3>","metadata":{}},{"cell_type":"code","source":"i = []\nfor j in range(10):\n    i.append(j)\n    \ndf_train_cut = df_train.query(\"label == @i\").sample(frac =.10).sort_index()\ndf_train_cut.shape","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:52:53.318194Z","iopub.execute_input":"2021-10-17T07:52:53.318481Z","iopub.status.idle":"2021-10-17T07:52:53.554936Z","shell.execute_reply.started":"2021-10-17T07:52:53.318438Z","shell.execute_reply":"2021-10-17T07:52:53.554136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h3>Again counting unique labels in the dataframe</h3>","metadata":{}},{"cell_type":"code","source":"df_train_cut['label'].value_counts().sort_index()","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:53:00.204092Z","iopub.execute_input":"2021-10-17T07:53:00.204362Z","iopub.status.idle":"2021-10-17T07:53:00.212924Z","shell.execute_reply.started":"2021-10-17T07:53:00.204333Z","shell.execute_reply":"2021-10-17T07:53:00.212046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = px.bar(df_train_cut['label'].value_counts().sort_index(), \n             color=df_train['label'].value_counts().index,\n            labels={\n                     \"value\": \"count\",\n                     \"index\": \"label\",\n                 }\n            )\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:53:05.100086Z","iopub.execute_input":"2021-10-17T07:53:05.100353Z","iopub.status.idle":"2021-10-17T07:53:05.311516Z","shell.execute_reply.started":"2021-10-17T07:53:05.100325Z","shell.execute_reply":"2021-10-17T07:53:05.310865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test = pd.read_csv('../input/digit-recognizer/test.csv')\ndf_test.head()","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:53:32.613766Z","iopub.execute_input":"2021-10-17T07:53:32.614182Z","iopub.status.idle":"2021-10-17T07:53:34.753897Z","shell.execute_reply.started":"2021-10-17T07:53:32.614150Z","shell.execute_reply":"2021-10-17T07:53:34.753019Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test.shape","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:53:47.094998Z","iopub.execute_input":"2021-10-17T07:53:47.095521Z","iopub.status.idle":"2021-10-17T07:53:47.100594Z","shell.execute_reply.started":"2021-10-17T07:53:47.095453Z","shell.execute_reply":"2021-10-17T07:53:47.099936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_cut_reshaped = df_train_cut.iloc[:, 1:785].values.reshape(4200,28,28)\ndf_train_cut_reshaped.shape","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:53:56.966425Z","iopub.execute_input":"2021-10-17T07:53:56.966975Z","iopub.status.idle":"2021-10-17T07:53:56.973126Z","shell.execute_reply.started":"2021-10-17T07:53:56.966935Z","shell.execute_reply":"2021-10-17T07:53:56.972487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nfig, axes = plt.subplots(10, 10, figsize=(16, 16),\n                        subplot_kw={'xticks':[], 'yticks':[]},\n                        gridspec_kw=dict(hspace=0.1, wspace=0.1))\n\nfor i, ax in enumerate(axes.flat):\n    ax.imshow(df_train_cut_reshaped[i], cmap='binary',\n            interpolation='nearest'),\n    ax.text(0.8, 0.8, df_train_cut['label'].to_numpy()[i],\n        transform=ax.transAxes, color='green', fontsize=16)","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:54:04.870947Z","iopub.execute_input":"2021-10-17T07:54:04.871489Z","iopub.status.idle":"2021-10-17T07:54:09.614148Z","shell.execute_reply.started":"2021-10-17T07:54:04.871401Z","shell.execute_reply":"2021-10-17T07:54:09.613454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h3>Data array:</h3>\n<h4>We drop 'feature' column from df_train dataset</h4>","metadata":{}},{"cell_type":"code","source":"X = df_train.iloc[:, 1:785]\nX.shape","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:54:17.723714Z","iopub.execute_input":"2021-10-17T07:54:17.724461Z","iopub.status.idle":"2021-10-17T07:54:17.730808Z","shell.execute_reply.started":"2021-10-17T07:54:17.724417Z","shell.execute_reply":"2021-10-17T07:54:17.729921Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y = df_train['label']\ny.shape","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:54:21.523195Z","iopub.execute_input":"2021-10-17T07:54:21.524046Z","iopub.status.idle":"2021-10-17T07:54:21.529578Z","shell.execute_reply.started":"2021-10-17T07:54:21.523990Z","shell.execute_reply":"2021-10-17T07:54:21.528693Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h4>We have 42000 samples and 784 features.</h4>","metadata":{}},{"cell_type":"markdown","source":"<h3>Unsupervised learning: Dimensionality reduction</h3>\n<h4>We'll reduce the dimensions to 2, using an unsupervised method. We'll make use of a manifold learning algorithm called Isomap, and transform the data to two dimensions:</h4>","metadata":{}},{"cell_type":"code","source":"from sklearn.manifold import Isomap\niso = Isomap(n_components=2)\niso.fit(df_train_cut.iloc[:, 1:785])\ndata_projected = iso.transform(df_train_cut.iloc[:, 1:785])\ndata_projected.shape","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:54:30.779432Z","iopub.execute_input":"2021-10-17T07:54:30.780147Z","iopub.status.idle":"2021-10-17T07:55:49.293129Z","shell.execute_reply.started":"2021-10-17T07:54:30.780097Z","shell.execute_reply":"2021-10-17T07:55:49.292029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h4>We see that the projected data is now two-dimensional. Let's plot this data:</h4>","metadata":{}},{"cell_type":"code","source":"# Convert numpy array to pandas dataframe\ndf_data_projected = pd. DataFrame(data_projected, columns=['Column1', 'Column2'])\n\nfig = px.scatter(x = df_data_projected['Column1'], y = df_data_projected['Column2'],\n                 color=df_train_cut['label'],\n                 color_continuous_scale=[\n                                             (0.00, \"red\"),   (0.1, \"red\"),\n                                            (0.1, \"green\"), (0.2, \"green\"),\n                                            (0.2, \"blue\"),  (0.3, \"blue\"),\n                                             (0.3, \"goldenrod\"),  (0.4, \"goldenrod\"),\n                                             (0.4, \"magenta\"),  (0.5, \"magenta\"),\n                                             (0.5, \"orange\"),  (0.6, \"orange\"),\n                                             (0.6, \"silver\"),  (0.7, \"silver\"),\n                                             (0.7, \"purple\"),  (0.8, \"purple\"),\n                                             (0.8, \"cyan\"),  (0.9, \"cyan\"),\n                                             (0.9, \"black\"),  (1.0, \"black\")\n                                        ]\n                )\n\nfig.update_layout(coloraxis_colorbar=dict(\n    title=\"Labels\",\n    tickvals=[0,1,2,3,4,5,6,7,8,9],\n    lenmode=\"pixels\", len=400,\n))\n\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:56:00.307835Z","iopub.execute_input":"2021-10-17T07:56:00.308169Z","iopub.status.idle":"2021-10-17T07:56:00.423749Z","shell.execute_reply.started":"2021-10-17T07:56:00.308134Z","shell.execute_reply":"2021-10-17T07:56:00.422902Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h4>We will split the data into a training and testing set, and fit a Bernoulli naive Bayes model:</h4>","metadata":{}},{"cell_type":"code","source":"Xtrain, Xtest, ytrain, ytest = train_test_split(X, y, random_state=0)","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:56:08.280022Z","iopub.execute_input":"2021-10-17T07:56:08.280311Z","iopub.status.idle":"2021-10-17T07:56:08.536533Z","shell.execute_reply.started":"2021-10-17T07:56:08.280278Z","shell.execute_reply":"2021-10-17T07:56:08.535733Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.naive_bayes import BernoulliNB\nmodel = BernoulliNB()\nmodel.fit(Xtrain, ytrain)\ny_model = model.predict(Xtest)","metadata":{"execution":{"iopub.status.busy":"2021-10-17T07:56:15.918117Z","iopub.execute_input":"2021-10-17T07:56:15.918386Z","iopub.status.idle":"2021-10-17T07:56:17.167963Z","shell.execute_reply.started":"2021-10-17T07:56:15.918357Z","shell.execute_reply":"2021-10-17T07:56:17.166787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h4>Let's gauge accuracy of the model by comparing the true values of the test set to the predictions:</h4>","metadata":{}},{"cell_type":"code","source":"from sklearn.metrics import accuracy_score\naccuracy_score(ytest, y_model)","metadata":{"execution":{"iopub.status.busy":"2021-10-17T08:07:39.660370Z","iopub.execute_input":"2021-10-17T08:07:39.660682Z","iopub.status.idle":"2021-10-17T08:07:39.668291Z","shell.execute_reply.started":"2021-10-17T08:07:39.660651Z","shell.execute_reply":"2021-10-17T08:07:39.667545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h2>We have about 83% accuracy for classification of the digits</h2>\n<h4>Let's use the confusion matrix to see where we we've gone wrong</h4>","metadata":{}},{"cell_type":"code","source":"import seaborn as sns\nsns.set(rc={'figure.figsize':(15,12)})\n\nmat = confusion_matrix(ytest, y_model)\n\nsns.heatmap(mat, square=True, annot=True, cbar=False, fmt='g')\nplt.xlabel('predicted value')\nplt.ylabel('true value');","metadata":{"execution":{"iopub.status.busy":"2021-10-17T08:08:17.900066Z","iopub.execute_input":"2021-10-17T08:08:17.900979Z","iopub.status.idle":"2021-10-17T08:08:18.762479Z","shell.execute_reply.started":"2021-10-17T08:08:17.900937Z","shell.execute_reply":"2021-10-17T08:08:18.761541Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h4>The diagram shows where the numbers are incorrectly labeled: for example,\na large number of fives here are mistakenly classified as threes, and fours as nines.</h4>\n<h4>We plot the inputs again, with their predicted labels. We'll use green for correct labels, and red for incorrect labels:</h4>","metadata":{}},{"cell_type":"code","source":"fig, axes = plt.subplots(10, 10, figsize=(16, 16),\n                         subplot_kw={'xticks':[], 'yticks':[]},\n                         gridspec_kw=dict(hspace=0.1, wspace=0.1))\n\ntest_images = Xtest.values.reshape(10500,28,28)\n\nfor i, ax in enumerate(axes.flat):\n    ax.imshow(test_images[i], cmap='binary', interpolation='nearest')\n    ax.text(0.8, 0.8, str(y_model[i]),\n            transform=ax.transAxes,\n            fontsize=16,\n            color='green' if (ytest.to_numpy()[i] == y_model[i]) else 'red'\n           )","metadata":{"execution":{"iopub.status.busy":"2021-10-17T08:08:27.411408Z","iopub.execute_input":"2021-10-17T08:08:27.411698Z","iopub.status.idle":"2021-10-17T08:08:31.975078Z","shell.execute_reply.started":"2021-10-17T08:08:27.411667Z","shell.execute_reply":"2021-10-17T08:08:31.974177Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}