Импорт данных LISP в RapidMiner (CSV, ...) - PullRequest
1 голос
/ 30 ноября 2011

У меня есть данные в форме LISP, и мне нужно обработать их в RapidMiner. Я новичок в LISP и RapidMiner, а также. RapidMiner не принимает LISP (думаю, это потому, что это язык программирования), поэтому мне, вероятно, нужно каким-то образом преобразовать форму LISP в CSV или что-то в этом роде. Маленький пример кода:

(def-instance Adelphi
   (state newyork)
   (control private)
   (no-of-students thous:5-10)
   ...)
(def-instance Arizona-State
   (state arizona)
   (control state)
   (no-of-students thous:20+)
   ...)
(def-instance Boston-College
   (state massachusetts)
   (location suburban)
   (control private:roman-catholic)
   (no-of-students thous:5-10)
   ...)

Буду очень признателен за любой совет.

1 Ответ

3 голосов
/ 01 декабря 2011

Вы можете использовать тот факт, что парсер Лиспа доступен для пользователя Лиспа. Проблема с этими данными заключается в том, что некоторые значения содержат двоеточия, при этом в Common Lisp используется разделитель имени пакета. Я сделал некоторый рабочий код Common Lisp для решения вашего вопроса, но мне пришлось обойти упомянутую проблему, определив соответствующие пакеты.

Вот код, который, конечно, должен быть расширен (следуя тем же шаблонам, которые уже использованы в нем) для всего, что вы пропустили в примере в вашем вопросе:

(defpackage #:thous
  (:export #:5-10 #:20+))
(defpackage #:private
  (:export #:roman-catholic))

(defstruct (college (:conc-name nil))
  (name "")
  (state "")
  (location "")
  (control "")
  (no-of-students ""))

(defun data->college (name data)
  (let ((college (make-college :name (write-to-string name :case :capitalize))))
    (loop for (key value) in data
       for string = (remove #\| (write-to-string value :case :downcase))
       do (case key
            (state (setf (state college) string))
            (location (setf (location college) string))
            (control (setf (control college) string))
            (no-of-students (setf (no-of-students college) string))))
    college))

(defun read-data (stream)
  (loop for (def-instance name . data) = (read stream nil nil)
     while def-instance
     collect (data->college name data)))

(defun print-college-as-csv (college stream)
  (format stream
          "~a~{,~a~}~%"
          (name college)
          (list (state college)
                (location college)
                (control college)
                (no-of-students college))))

(defun data->csv (in out)
  (let ((header (make-college :name "College"
                              :state "state"
                              :location "location"
                              :control "control"
                              :no-of-students "no-of-students")))
    (print-college-as-csv header out)
    (dolist (college (read-data in))
      (print-college-as-csv college out))))

(defun data-file-to-csv (input-file output-file)
  (with-open-file (in input-file)
   (with-open-file (out output-file
                        :direction :output
                        :if-does-not-exist :create
                        :if-exists :supersede)
     (data->csv in out))))

Основной функцией является data-file-to-csv, которую можно вызвать с помощью (data-file-to-csv "path-to-input-file" "path-to-output-file") в REPL Common Lisp после загрузки этого кода.

РЕДАКТИРОВАТЬ: некоторые дополнительные мысли

На самом деле было бы проще, вместо добавления определений пакетов для всех значений с двоеточиями, выполнять поиск по регулярным выражениям и заменять данные, чтобы добавлять кавычки (") вокруг всех значений. Это заставит Lisp анализировать их как строки В этом случае можно удалить строку for string = (remove #\| (write-to-string value :case :downcase)) и заменить string на value во всех строках оператора case.

Из-за высокой регулярности данных даже не нужно вообще анализировать определения Lisp вообще. Вместо этого вы можете просто извлечь данные с помощью регулярных выражений. Язык, особенно подходящий для преобразования текстовых файлов на основе регулярных выражений, вполне подойдет для этой работы, например AWK или Perl.

...