За най-доброто изживяване на уебсайта на Oliver Wyman Labs,
моля надстройте браузъра си до IE9 или по-нова версия

Четене на ARFF файлове с Elixir

oliver

Ако прилагате подход за машинно обучение, вероятно ще искате да го тествате на публично достъпни набори от данни. Голям брой от тези набори от данни използват файловия формат ARFF, установен от Weka. Не знам за читатели на Elixir ARFF, така че ще проуча писането на такъв („Arfficionado“) в този блог.

Кратко описание на ARFF

ARFF (Формат на файл с атрибут-връзка) указва заглавна секция и секция с данни. Разделът за заглавие декларира името на набора от данни, както и имената и типовете на атрибутите на набора от данни. Разделът с данни посочва по един екземпляр на ред, като изброява стойностите на атрибутите (в реда на атрибутите, посочен в заглавния раздел), последван от по избор тегло на екземпляра. Запетаите или разделите се използват за разделяне на стойностите и всяко празно пространство около стойностите трябва да се игнорира. Липсващите стойности са представени от?. Всеки текст след% се третира като коментар в края на реда. Стойностите, които съдържат интервали, запетаи и др., Могат да бъдат цитирани в единични или двойни кавички (които могат да бъдат избегнати с обратна наклонена черта). Разрешени са празни редове и редове за коментари. Съществува и режим на разредено кодиране за секцията с данни, който изброява ненулеви атрибути като двойки индекс-стойност. Атрибутите могат да бъдат числови (цяло число или реални), номинални (изброяване), низ (подходящ за текст), дата (ISO-8601 или низ java.text.SimpleDateFormat) или релационни (за бъдеща употреба).

Предвидено използване на ARFF четец

Има няколко неща, които може да искате да направите с ARFF файл, например:

  • филтриране на екземпляри според някои критерии
  • съберете всички екземпляри и ги върнете като списък
  • вмъкване на екземпляри в ets таблица
  • четете и обработвайте файла на партиди

Изглежда разумно да подадете ARFF файл на четеца като поток от линии и да предадете модул за обратно извикване, който осигурява желаното специфично поведение.

Четецът ще анализира файла ARFF и за всяко съответно събитие извиква съответния обратен извикване на манипулатора. Четецът следи състоянието на манипулатора. При извикване на обратно извикване той преминава в текущото състояние и в замяна получава актуализираното състояние. Това позволява на модула на манипулатора да натрупва данни, да управлява ets референции и т.н. Крайното състояние на манипулатора ще бъде върнато на повикващия.

Идеи за изпълнение

ARFF може да бъде токенизиран и анализиран ред по ред. Рекурсивното спускане е подходяща техника за това. Официалните „спецификации“ могат да бъдат превърнати в единични тестове. Информацията за атрибутите се разпространява по множество редове и трябва да се натрупва, за да може да се използва за правилно излъчване на стойностите на инстанцията.

Входящият поток може да се консумира от Enum.reduce_ While/3, което в крайна сметка позволява на обратните извиквания на модула за обработка да прекъснат обработката, преди потокът да бъде изчерпан. Обратните обаждания на манипулатора трябва да се върнат, за да работи това.

След като основната структура е на място, има смисъл да се тества чрез обработка на големи колекции от ARFF файлове. В бъдеще това може да бъде разширено до тестове за двупосочно пътуване, при които манипулаторът създава изходен ARFF файл от събитията, които получава, и входът и изходът трябва да се съгласят (минус разликите в празното пространство, които вероятно ще бъдат загубени).

Изпълнение

Следвах идеите, описани по-горе, и в крайна сметка получих 231 реда код на Elixir, които считам за доста компактни. В настоящото си въплъщение Arfficionado определя следните обратни извиквания на манипулатора:

Единствената цел на line_comment/2 и begin_data/2 е да улови възможни коментари във входния файл, за да даде възможност за бъдещи тестове за двупосочно пътуване. В интерес на отслабването на поведението, може да премахна тези обратни обаждания в даден момент. Отношението за обратно извикване/3, атрибути/2 и особено екземпляр/4 предоставят действителна информация за ARFF. close/1 се извиква, когато входният поток е изчерпан или прекъснат, за да се даде възможност на модула за обработка да почисти.

Въпреки че Arfficionado се справя добре с голяма част от моите тестови файлове, в момента има някои съществени ограничения:

  • ARFF позволява персонализирани формати за дата/час, следвайки конвенциите на java.text.SimpleDateFormat. Прекарах нула цикли за това и следователно Arfficionado поддържа само формата ISO-8601 (и не зависи от външни библиотеки).
  • Понастоящем не се поддържат обратни наклонени черти в цитираните низове.
  • ARFF позволява атрибути от типа „релационни“, поддръжка за които все още не съм внедрил.
  • ARFF има режим на оскъдно кодиране, който все още не съм внедрил.
  • Повечето ARFF файлове са добре оформени, но някои се отклоняват от „спецификацията“. Достатъчно счупените ARFF файлове понастоящем ще доведат до изключения при четене. Механизмът за обработка/възстановяване на грешки би бил от полза.
  • Типовите спецификации за обратно извикване на манипулатора могат да бъдат значително по-строги.
  • Не съм поставял бенчмаркинг на Arfficionado и очаквам да има място за подобрение.

Заключение и бъдеща работа

Беше забавно да се създаде първа версия на Elixir ARFF четец. Подобренията ми с най-висок приоритет са добавянето на добър механизъм за обработка/възстановяване на грешки и правенето на Arfficionado по-снизходително по отношение на често срещаните (доброкачествени) отклонения от спецификацията на ARFF.