Как бы вы обработали очень большой вектор в Ruby?

Я планирую написать программу на Ruby для анализа некоторых данных, полученных из онлайн-анкеты. Есть сотни тысяч ответов, и каждый респондент отвечает примерно на 200 вопросов. На каждый вопрос можно ответить с несколькими вариантами ответа, поэтому на каждый есть фиксированное количество возможных ответов.

Намерение состоит в том, чтобы использовать часть демографических данных, предоставленных каждым респондентом, для обучения системы, которая затем может угадывать ту же часть демографических данных (например, возраст) у респондента, который отвечает на тот же вопросник, но не указывает демографические данные. данные.

Поэтому я планирую использовать вектор (в математическом смысле, а не в смысле структуры данных) для представления ответов для данного респондента. Это означает, что каждый вектор будет большим (более 200 элементов), а общий набор данных будет огромным. Я планирую хранить данные в базе данных MySQL.

Так. 2 вопроса:

  1. Как мне сохранить это в базе данных? Одна строка на ответ на один вопрос или одна строка на респондента? Или что-то другое?

  2. Я планирую использовать что-то вроде алгоритма k-ближайшего соседа или простого алгоритма машинного обучения, такого как наивный байесовский классификатор, чтобы научиться классифицировать новые ответы. Должен ли я манипулировать данными исключительно через SQL или я должен загружать их в память и хранить в каком-то огромном массиве?

Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
3
0
358
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Первое, что приходит на ум: хранение в памяти может быть абсолютно разумным для обработки. Допустим, вы резервируете один байт для каждого ответа, у вас есть миллион ответов и 200 вопросов, а затем у вас есть массив на 200 МБ. Немаленький, но определенно не исчерпывающий объем памяти на современном настольном компьютере, даже с 32-битной ОС.

Что касается базы данных, я думаю, у вас должно быть три таблицы. Один для респондента с демографическими данными, один для вопросов и, поскольку у вас есть отношение n: m между этими таблицами, третий с идентификатором респондента, идентификатором вопроса и кодом ответа.

Если вам не нужны дополнительные данные для вопросов (например, текст вопроса или что-то в этом роде), вы даже можете оптимизировать таблицу вопросов.

Используйте массив массивов в памяти. Я только что создал массив размером 500000x200 пикселей, и ему потребовалось около 500 МБ ОЗУ. Легко управляется на машине 2 ГБ и на много-много порядков быстрее, чем при использовании SQL.

Лично я бы вообще не стал помещать данные в MySQL. Просто добавьте и удалите его и / или используйте JSON или CSV.

Я не очень хорошо разбираюсь в базах данных, поэтому отвечу на второй вопрос:

Если вы действительно хотите сэкономить на памяти (или предвидеть ситуацию, когда будет намного больше данных), вы можете взять лучшее из обоих миров: использовать Ruby как инструмент для сбора данных. Попросите его извлечь некоторые данные из БД, а затем записать результаты обратно в БД (возможно, в другой таблице или в другой базе данных). Это дает то преимущество, что вы используете столько памяти, сколько хотите.

Если вам определенно нужно хранилище базы данных, и стоит рассмотреть комментарии в другом месте об альтернативах, то я бы посоветовал не хранить 200 с лишним ответов в 200 с лишним строк: у вас, похоже, нет очевидной потребности в гибкости, которую дизайн даст, а эффективность у сотен тысяч респондентов будет ужасной.

Использование СУБД дает вам возможность хранить очень большие объемы данных, получать к ним доступ различными многомерными способами и расширять структуру ваших данных со временем. Но то, что вы получаете в гибкости по сравнению с вариантом с плоским файлом (или с маршалированным файлом или другим), вы часто теряете в производительности. Я должен признаться, что сам слишком рано достиг третьей нормальной формы. Я предполагаю, что вопрос в том, какая гибкость в запросах, по вашему мнению, потребуется, и сколько изменений, по вашему мнению, могут претерпеть ваши данные? Если вы думаете, что находитесь на нижнем уровне обоих вариантов, подумайте о том, чтобы оставить SQL на полке. Если вы выделите доступ к данным на отдельный уровень, то изменение в дальнейшем будет дешевым. Просто мысль...

Я ожидаю, что вы сможете закодировать индивидуальный ответ таким образом, чтобы его можно было легко использовать в коде, и вряд ли он займет более 200 символов, меньше, если вы используете какую-то упаковку или битовое отображение. Если подумать, мне больше нравится идея растрового отображения - она ​​делает простое сравнение с использованием чего-то вроде расстояния Хэмминга абсолютным бризом.

Не забывайте, что Ruby - это динамический объектный язык, поэтому простое целое число, вероятно, займет больше места, чем простое int в C. Ему нужно дополнительное пространство, чтобы можно было охарактеризовать, было ли оно «украшено» какими-либо дополнительными информация, методы и т. д.

Другие вопросы по теме