Как бы вы справились с очень большим вектором в Ruby? - PullRequest
3 голосов
/ 27 сентября 2008

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

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

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

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

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

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

Ответы [ 5 ]

3 голосов
/ 27 сентября 2008

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

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

3 голосов
/ 27 сентября 2008

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

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

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

2 голосов
/ 27 сентября 2008

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

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

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

0 голосов
/ 03 октября 2008

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

0 голосов
/ 27 сентября 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...