{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt # data visualization\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Да, это Kannada MNIST на Excel\n\nНейронные сети — удивительное чудо и движующая сила современных информационных технологий. С ними можно решать самые разные задачи. Одна из базовых — распознавание рукописных цифр.\n\nСуть в том, что самообущаяся свёрточная нейросеть должна работать с матрицей яркости пикселей (28×28) с операциями свёртки специальными фильтрами, объединением (пуллингом), исключением (дроп-аутом).\n> Но что если сделать шаг назад в инновациях и использовать не машинное обучение, а Microsoft Excel?\n\nKaggle [предлагает](https://www.kaggle.com/c/Kannada-MNIST/data) нам четыре файла, один из которых, `train.csv`, мы будем использовать для проверки нашей гипотез.\n\n![](https://psv4.userapi.com/c856528/u99539515/docs/d13/7eecc796b1f9/1.png)\n\n## Импорт данных\n\nСоздадим в Excel пустую книгу и импортируем файл `test.csv` с помощью получения внешних данных.\n* Кодировка: UTF-8. \n* Разделители: запятые. \n* Формат данных: общий.\n\nВставляем в имеющийся лист.\n\n![Untitled/Untitled%201.png](https://psv4.userapi.com/c856416/u99539515/docs/d9/6b6410215651/Untitled_1.png)\n\nДанных довольно много, более 47 миллионов ячеек, работать с ними долго и неудобно. Скроем некоторые столбцы (оставим по три начальных, средних и конечных), а также оставим меньше видимых строк. Я оставлю первые десять и пару последних, а также добавлю шапку для этих данных.\n\n![Untitled/Untitled%202.png](https://psv4.userapi.com/c856228/u99539515/docs/d10/40212e6c3738/Untitled_2.png)\n\nКолонка — номер пикселя (указан сверху; картинка «вытянута» в одномерный массив). Строка — это номер картинки, или экземпляра.\nБольшинство данных — нули. Действительно, большая площадь изображения занята... ничем. Она пустая. Чёрная. Нулевая.\n\n![Untitled/header.png](https://psv4.userapi.com/c856220/u99539515/docs/d13/49519081acf6/header.png)\n\n## Модели цифр\n\nЧтобы распознать рукописную цифру, нам нужно сверить её с моделями существующих цифр. Наша модель будет простой. Используем среднее арифметическое для яркости пикселя у одинаковых цифр.\n\nИтого получим 10 строчек для каждой цифры. Используем функцию `СРЗНАЧЕСЛИ` (AVERAGEIF), считаем в первой ячейке, а затем растягиваем на всю матрицу.\n\n> 47 миллионов ячеек это много, поэтому необходимо постоянно ждать и сохраняться.\n\n![Untitled/Untitled%203.png](https://psv4.userapi.com/c856432/u99539515/docs/d6/cded2e2d7c11/Untitled_3.png)\n\nДа, изначально должен получится ноль. Никто не пишет в углу холста.\n\nПроверяем, нет ли проблем с адресацией. Удобно ориентироваться по цветной подстветке ячеек.\n\n![Untitled/Untitled%204.png](https://psv4.userapi.com/c856528/u99539515/docs/d6/5a56018a06cd/Untitled_4.png)\n\nЯ потратил много времени при построении различных моделей цифр. Изначально я планировал найти такую функцию контрольных сумм, которая приблизительно, но более менее однозначно описывала цифры. Но более успешным ходом (и самым успешным из простых) оказалась такая модель со средним арифметическим."},{"metadata":{"trusted":true},"cell_type":"code","source":"model = pd.read_csv(\"../input/kannadamnist-avg/model.csv\", header=None)\n\nprint(\"Kannada digits models:\")\nfig = plt.figure()\nfor i in range(1, 11):\n    number = model.iloc[i-1,0:784].values.reshape(28,28)\n    ax = fig.add_subplot(2, 5, i)\n    plt.imshow(number, cmap=plt.get_cmap('gray'))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Проверка на соответствие\n\n«Вытащим» условно-случайную величину из нашего набора данных. Например, из строки 123321. Для этого используем простую адресацию `A12321` и растянем её до 784 пикселя.\n\nЭто число оказалось восьмёркой, а видимые нам значения нулевые. Но это, конечно, совсем не так. Можно убедиться в этом, показав скрытые столбцы.\n\n![Untitled/Untitled%205.png](https://psv4.userapi.com/c856528/u99539515/docs/d2/b8290fea3f96/Untitled_5.png)\n\nДля проверки этих данных (по факту, картинки) на соответствие модели, можем воспользоваться разными инструментами. Я буду расчитывать квадрат коэффициента корелляции и ковариацию. Наша случайная цифра будет сравниваться с 10 моделями. Наибольшие параметры предсказывают наибольшее совпадение. \n\nИспользуем `КВПИРСОН` (RSQ) для вычисления первого параметра. Поместим их напротив наших моделей для удобства восприятия.\n\n![Untitled/Untitled_(1).png](https://psv4.userapi.com/c856232/u99539515/docs/d11/f2d98420a380/Untitled_1.png)\n\nВнимательные читатели сразу уловят суть, но пока расчитаем ещё один параметр — ковариацию. Оба этих параметра отвечают за связь наборов данных. Аргументы обеих функций совпадают:\n\n![Untitled/Untitled%206.png](https://psv4.userapi.com/c856436/u99539515/docs/d18/aba5ad6ba981/Untitled_6.png)\n\nДля наглядности с помощью условного форматирования построим гистограммы, изменим формат и приведём всё в более наглядный вид. Снизу нужно вывести максимумы среди значений.\n\n![Untitled/Untitled%207.png](https://psv4.userapi.com/c856232/u99539515/docs/d16/f1ab1d16ff04/Untitled_7.png)\n\nЧтобы отобразить номер модели, с которой у случайного экземпляра максимальная корреляция и ковариация (argmax), используем функцию `ПОИСКПОЗ` (MATCH). Она сравнивает ячейку максимума со всеми значениями и выводит номер модели, соответствующей максимуму. Фактически, это и есть вывод нашей системы.\n\nЗачем нам два параметра? Аргументы, при которых максимальны корелляция и ковариация, могуть быть разными. Здесь имеет место быть неопределённость вычислений — экземпляр по-разному, но похож на две можели одновременно. \n\n![Untitled/Untitled%208.png](https://psv4.userapi.com/c856220/u99539515/docs/d11/18caf29d02a8/Untitled_8.png)\n\nНе мудрствуя лукаво, случайно возьмём один из двух выводов с помощью `СЛУЧМЕЖДУ` (RANDBETWEEN) и `ИНДЕКС` (INDEX) и назначим нашему экземпляру. Пока это наш главный вывод, поэтому сделаем его выразительнее. Сделаем индикатор при помощью белого текста и условного форматирования. Фон будет появляться при выполнении формулы `СОВПАД` (EXACT) у главного вывода и первой колонки случайного экземпляра.\n\n![Untitled/Untitled%209.png](https://psv4.userapi.com/c856324/u99539515/docs/d9/a37d1ea65869/Untitled_9.png)\n\n## Более случайные экземпляры\n\nВместо придуманного числа [12321] используем функцию `СЛУЧМЕЖДУ` (RANDBETWEEN), которая генирует нам номер случайного экземпляра (от 1 до 60000). Ссылаемся на него с помощью `ИНДЕКС` (INDEX). При каждом изменении в ячейках Excel будет генерировать новое случайное число и 25 значений будут высчитываться заново (по 10 значений квадратного коэффициента корреляции и ковариации, 2 их максимума, 2 argmax и 1 случайный выбор).\n\n![Untitled/Untitled%2010.png](https://psv4.userapi.com/c856432/u99539515/docs/d11/693edd65f325/Untitled_10.png)\n\nЧтобы таким образом проверить на соответствие все экземпляры и вычислить общий процент попаданий, нужно дополнительно 25 × 60 000 = 1 500 000 ячеек. Такое решение «в лоб» не подходит из соображений ресурсоемкости и здравого смысла.\n\nИспользуем макрос, проходим нескольким результатам (вычисление ограничиваем временем) и сохраняем вычисленную цифру напротив экземпляра.\n\n    Sub calc()\n        Application.ScreenUpdating = False\n        \n        Dim AbortTime As Date\n        AbortTime = Now + TimeValue(\"02:00:00\")\n        \n        Dim i As Long, j As Long\n        For i = 3 To 60002\n            For j = 1 To 785\n                Cells(60015, j) = Cells(i, j)\n            Next j\n            Cells(i, \"ADF\") = Cells(60006, \"ADL\")\n            If Now > AbortTime Then Exit For\n        Next i\n        [ADK2].Value = \"Done\"\n        \n        Application.ScreenUpdating = True\n    End Sub\n\nВычисляем число попаданий и получаем точность около **83%**.\n\n## Вычисление на тестовых данных\n\nИмпортируем файл `test.csv` подобное тому, как сделали это с `train.csv`.\n\n![Untitled/Untitled%2011.png](https://psv4.userapi.com/c856532/u99539515/docs/d13/4ae795ee956d/Untitled_11.png)\n\nЗапустим вычислительный макрос для этих полей. После того, как 5000 значений сосчитаны, вставляем их в файл и выкладываем на Kaggle."},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_submission = pd.read_csv(\"../input/output/sample_submission.csv\")\nsample_submission.to_csv('submission.csv',index=False)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}