Wordnet × CommonLisp에서 동의어를 추출해보기
17104 단어 WordNet자연 언어 처리common-lispcaveman2
소개
지정한 단어의 동의어·동의어를 조사하는 방법을 찾고 있었는데, 이하의 기사를 발견했으므로 이것을 Common Lisp로 해 보기로 했습니다.
WordNet
한국어 WordNet은 다음 웹 사이트에서 다운로드할 수 있습니다.
이번에는 위 기사와 마찬가지로 sqlite3의 DB로 공개된 것을 사용합니다.
Common Lisp에서 WordNet 사용
여러가지 편리하므로, Web 프레임워크 「 Caveman2 」를 사용합니다.
동의어 추출은 Common Lisp 프로그램에서 수행됩니다.
스켈레톤 프로젝트의 디렉토리 구성
REPL에서 다음 프로그램을 실행하여 해골 프로젝트를 만듭니다.
(ql:quickload :caveman2)
(caveman2:make-project #P"プロジェクトを作成するディレクトリのパス" :author "自分の名前")
(ql:register-local-projects) ; モジュールをlocal-projectsに登録
이하의 디렉토리 구성중에서 ★마크가 붙어 있는 개소를 이번은 만나갑니다.
wordnet-jp
├── README.markdown
├── app.lisp
├── db
│ ├── wnjpn.db ★ ダウンロードしてきたsqlite3のDBをここに置く
│ └── schema.sql
├── wordnet-jp.asd
├── wordnet-jp-test.asd
├── src
│ ├── config.lisp ★ SQLite3の設定関連
│ ├── db.lisp
│ ├── main.lisp
│ ├── view.lisp
│ └── web.lisp ★ SQL文の実行処理関連
├── static
│ └── css
│ └── main.css
├── templates
│ ├── _errors
│ │ └── 404.html
│ ├── index.html ★ テンプレートエンジン
│ └── layouts
│ └── default.html
└── tests
└── myapp.lisp
DB 설정
WordNet sqlite3 DB를 사용하도록 설정을 변경.
다음 프로그램을
src/config.lisp(defconfig :common
`(:databases ((:maindb :sqlite3 :database-name ":memory:"))))
다음과 같이 변경합니다.
src/config.lisp(defconfig :common
`(:databases ((:maindb :sqlite3 :database-name ,(merge-pathnames #P"db/wnjpn.db" *application-root*)))))
WordNet을 이용하는 프로그램
src
디렉토리 아래의 web.lisp
에 처리를 기술해 갑니다.
src/web.lisp(defun get-words (lemma)
(with-connection (db)
(let ((result (retrieve-all (select (:*) (from :word) (where (:= :lemma lemma)))))
lemma-list)
(dolist (n result)
(setf lemma-list (cons (second n) lemma-list)))
lemma-list)))
(defun get-senses (wordid)
(with-connection (db)
(let ((result (retrieve-all (select (:*) (from :sense) (where (:= :wordid wordid)))))
sense-list)
(dolist (n result)
(setf sense-list (cons (second n) sense-list)))
sense-list)))
(defun get-synset (synset)
(with-connection (db)
(let ((result (retrieve-all (select (:*) (from :synset) (where (:= :synset synset)))))
synset-list)
(dolist (n result)
(setf synset-list (cons (sixth n) synset-list)))
synset-list)))
(defun get-words-from-synset (synset lang)
(with-connection (db)
(let ((result (retrieve-all (select (:word.*)
(from :sense :word)
(where (:and (:= :synset synset)
(:= :word.lang lang)
(:= :sense.wordid :word.wordid))))))
words-list)
(dolist (n result)
(setf words-list (cons (sixth n) words-list)))
words-list)))
(defun get-words-from-senses (synonym sense &optional (lang "jpn"))
(dolist (s sense)
(let ((syns (first (get-synset s)))
(words (get-words-from-synset s lang)))
(setf (gethash syns synonym) words)))
synonym)
(defun get-synonym (word)
(let ((words (get-words word))
(synonym (make-hash-table :test #'equal)))
(dolist (id words)
(let* ((sense (get-senses id)))
(setf synonym (get-words-from-senses synonym sense))))
synonym))
(defun wordnet-test (input)
(let ((synonym (get-synonym input)))
(maphash #'(lambda (key val)
(format t "key = ~A, val = ~A~%" key val))
synonym)))
테스트 실행
시험에 실행해 보면 다음과 같이 됩니다.
(ql:quickload :wordnet-jp)
(wordnet-jp.web::wordnet-test "楽しい")
제대로 동의어를 얻을 수 있네요.
웹 애플리케이션화 해보기
모처럼 Caveman2를 사용하고 있으므로 웹 애플리케이션을 만들어 보겠습니다.
브라우저에서 텍스트 상자에서 단어를 입력하여 브라우저에 결과를 표시합니다.
우선은 적당하게 템플릿을 작성합니다.
templates/index.html{% extends "layouts/default.html" %}
{% block title %}Welcome to Caveman2{% endblock %}
{% block content %}
<div id="main">
<form action="/wordnet-search" method="POST">
<input type="text" name="word" value="{{ word }}">
<input type="submit" value="Search">
</form>
{% for synm in synonym %}
<ul>
{% for s in synm %}
{{ s }}
{% endfor %}
</ul>
{% endfor %}
</div>
{% endblock %}
다음으로, 라우팅 및 브라우저에 대한 반영 처리를 기술
src/web.lisp(defroute ("/wordnet-search" :method :POST) (&key |word|)
(render-wordnet-jp |word|))
src/web.lisp(defun render-wordnet-jp (word)
(render #P"index.html" `(:synonym ,(get-synonym word))))
다음 명령으로 실행.
(ql:quickload :wordnet-jp)
(wordnet-jp:start)
적절한 브라우저에서 localhost:5000
에 액세스합니다.
이하, 실행중인 모습
그렇게 할 수 있었습니다.
마지막으로
WordNet을 사용하여 동의어 추출을 Common Lisp에서 시도했습니다.
이런 건 정말 재미있네요.
Reference
이 문제에 관하여(Wordnet × CommonLisp에서 동의어를 추출해보기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/fireflower0/items/3e8c4fe6847511cc0224
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
(ql:quickload :caveman2)
(caveman2:make-project #P"プロジェクトを作成するディレクトリのパス" :author "自分の名前")
(ql:register-local-projects) ; モジュールをlocal-projectsに登録
wordnet-jp
├── README.markdown
├── app.lisp
├── db
│ ├── wnjpn.db ★ ダウンロードしてきたsqlite3のDBをここに置く
│ └── schema.sql
├── wordnet-jp.asd
├── wordnet-jp-test.asd
├── src
│ ├── config.lisp ★ SQLite3の設定関連
│ ├── db.lisp
│ ├── main.lisp
│ ├── view.lisp
│ └── web.lisp ★ SQL文の実行処理関連
├── static
│ └── css
│ └── main.css
├── templates
│ ├── _errors
│ │ └── 404.html
│ ├── index.html ★ テンプレートエンジン
│ └── layouts
│ └── default.html
└── tests
└── myapp.lisp
(defconfig :common
`(:databases ((:maindb :sqlite3 :database-name ":memory:"))))
(defconfig :common
`(:databases ((:maindb :sqlite3 :database-name ,(merge-pathnames #P"db/wnjpn.db" *application-root*)))))
(defun get-words (lemma)
(with-connection (db)
(let ((result (retrieve-all (select (:*) (from :word) (where (:= :lemma lemma)))))
lemma-list)
(dolist (n result)
(setf lemma-list (cons (second n) lemma-list)))
lemma-list)))
(defun get-senses (wordid)
(with-connection (db)
(let ((result (retrieve-all (select (:*) (from :sense) (where (:= :wordid wordid)))))
sense-list)
(dolist (n result)
(setf sense-list (cons (second n) sense-list)))
sense-list)))
(defun get-synset (synset)
(with-connection (db)
(let ((result (retrieve-all (select (:*) (from :synset) (where (:= :synset synset)))))
synset-list)
(dolist (n result)
(setf synset-list (cons (sixth n) synset-list)))
synset-list)))
(defun get-words-from-synset (synset lang)
(with-connection (db)
(let ((result (retrieve-all (select (:word.*)
(from :sense :word)
(where (:and (:= :synset synset)
(:= :word.lang lang)
(:= :sense.wordid :word.wordid))))))
words-list)
(dolist (n result)
(setf words-list (cons (sixth n) words-list)))
words-list)))
(defun get-words-from-senses (synonym sense &optional (lang "jpn"))
(dolist (s sense)
(let ((syns (first (get-synset s)))
(words (get-words-from-synset s lang)))
(setf (gethash syns synonym) words)))
synonym)
(defun get-synonym (word)
(let ((words (get-words word))
(synonym (make-hash-table :test #'equal)))
(dolist (id words)
(let* ((sense (get-senses id)))
(setf synonym (get-words-from-senses synonym sense))))
synonym))
(defun wordnet-test (input)
(let ((synonym (get-synonym input)))
(maphash #'(lambda (key val)
(format t "key = ~A, val = ~A~%" key val))
synonym)))
시험에 실행해 보면 다음과 같이 됩니다.
(ql:quickload :wordnet-jp)
(wordnet-jp.web::wordnet-test "楽しい")
제대로 동의어를 얻을 수 있네요.
웹 애플리케이션화 해보기
모처럼 Caveman2를 사용하고 있으므로 웹 애플리케이션을 만들어 보겠습니다.
브라우저에서 텍스트 상자에서 단어를 입력하여 브라우저에 결과를 표시합니다.
우선은 적당하게 템플릿을 작성합니다.
templates/index.html{% extends "layouts/default.html" %}
{% block title %}Welcome to Caveman2{% endblock %}
{% block content %}
<div id="main">
<form action="/wordnet-search" method="POST">
<input type="text" name="word" value="{{ word }}">
<input type="submit" value="Search">
</form>
{% for synm in synonym %}
<ul>
{% for s in synm %}
{{ s }}
{% endfor %}
</ul>
{% endfor %}
</div>
{% endblock %}
다음으로, 라우팅 및 브라우저에 대한 반영 처리를 기술
src/web.lisp(defroute ("/wordnet-search" :method :POST) (&key |word|)
(render-wordnet-jp |word|))
src/web.lisp(defun render-wordnet-jp (word)
(render #P"index.html" `(:synonym ,(get-synonym word))))
다음 명령으로 실행.
(ql:quickload :wordnet-jp)
(wordnet-jp:start)
적절한 브라우저에서 localhost:5000
에 액세스합니다.
이하, 실행중인 모습
그렇게 할 수 있었습니다.
마지막으로
WordNet을 사용하여 동의어 추출을 Common Lisp에서 시도했습니다.
이런 건 정말 재미있네요.
Reference
이 문제에 관하여(Wordnet × CommonLisp에서 동의어를 추출해보기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/fireflower0/items/3e8c4fe6847511cc0224
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
{% extends "layouts/default.html" %}
{% block title %}Welcome to Caveman2{% endblock %}
{% block content %}
<div id="main">
<form action="/wordnet-search" method="POST">
<input type="text" name="word" value="{{ word }}">
<input type="submit" value="Search">
</form>
{% for synm in synonym %}
<ul>
{% for s in synm %}
{{ s }}
{% endfor %}
</ul>
{% endfor %}
</div>
{% endblock %}
(defroute ("/wordnet-search" :method :POST) (&key |word|)
(render-wordnet-jp |word|))
(defun render-wordnet-jp (word)
(render #P"index.html" `(:synonym ,(get-synonym word))))
(ql:quickload :wordnet-jp)
(wordnet-jp:start)
WordNet을 사용하여 동의어 추출을 Common Lisp에서 시도했습니다.
이런 건 정말 재미있네요.
Reference
이 문제에 관하여(Wordnet × CommonLisp에서 동의어를 추출해보기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/fireflower0/items/3e8c4fe6847511cc0224텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)