Haskell에서 자연언어 처리 100개 노크의 제1장을 풀어본다. 【중편~bi-gram이란】
Haskell에서 자연 언어 처리 100개의 1장을 풀어보세요!
Haskell에서 자연언어 처리 100개 노크의 제1장을 풀어본다. 【전편】 계속
뭐 1장만이라면 대단히 고생하지 않을 것이라고 누구나가 츳코미를 넣고 있겠지만. .
05문제의 내용이 상당히 풍부해져 버렸다
그래서 하나의 기사로했습니다.
문제와 해답에 이르기까지의 과정
05. n-gram
주어진 시퀀스 (문자열, 목록 등)에서 n-gram을 만드는 함수를 만듭니다. 이 함수를 사용하여 "I am an NLPer"라는 문장에서 단어 bi-gram, 문자 bi-gram을 얻습니다.
우선, n-gram
이란 무엇인가로부터 시작되어 버린다.
우선 위키로 조사한다.
「N문자 인덱스법」 「N그램법」 등이라고도 한다. 검색 대상을 단어 단위가 아닌 문자 단위로 분해하고 후속 N-1 문자를 포함한 상태에서 출현 빈도를 구하는 방법.
분명히 ↑만으로는 모르겠다. (영어판 wiki에는 다소 자세하고 있다.)
그 밖에도 조사해 가면,
이웃 (연속) n 개
등으로 쓰여져 드디어 다가온다.
조사를 진행하면 아무래도
単語n-gram
는 연속 n개의 단어文字n-gram
는 연속 n개의 문자
라는 인식인것 같다.
n이 2일 때 n-gram은 bi-gram이라고도 할 수 있는 것 같다.
구체적으로 보면,
↑ 출처
위는 "This is a sentence"
에 대하여 単語n-gram
이다.文字n-gram
는 최소 단위를 단어가 아닌 문자로 한 버전이라고 봐도 좋을 것이다.
그렇다면 Haskell에서는 어떻게 n-gram
함수를 사용합니까?
리스트의 선두의 n개를 취해, 다음은 리스트의 선두를 들여다 본 리스트로부터 선두의 n개를 취해,....
라고 할 수 있으므로 再帰
에 의한 정의를 할 수 있는 것 같다.
실제로 take
와 drop
를 사용하여,
ngramngram :: Int -> [a] -> [[a]]
ngram n xs | n <= length xs = take n xs : ngram n (drop 1 xs)
| otherwise = []
같이 재귀로 기술할 수 있다.
다만, 구그하면 다른 것에도 여러 가지 방법은 있는 것 같다.
본 것에 공통적으로 보이는 것은
꼬리와 맵과 takemap (take n) . tails
사용하는 방법입니다.tails
함수는 부분 목록 목록을 생성하는 함수로, 예를 들어 "sentence"
에 tails
를 적용하면
꼬리Prelude Data.List> tails "sentence"
["sentence","entence","ntence","tence","ence","nce","ce","e",""]
와 같이, 가장 큰 요소가 리스트의 선두가 된다.
그러므로 map (take n)
를 계속 적용하면
꼬리와 맵과 takePrelude Data.List> map (take 2) . tails $ "sentence"
["se","en","nt","te","en","nc","ce","e",""]
같은 결과가 된다.
그리고는 take 되어, filter 나름을 쓰면 기대하는 결과를 얻을 수 있다.
그래서 해답은 다음과 같습니다.
05.hsmodule Main where
import qualified Data.List as List
import qualified System.IO as IO
-- 解答その1
ngram :: Int -> [a] -> [[a]]
ngram n xs | n <= List.length xs = List.take n xs : ngram n (List.drop 1 xs)
| otherwise = []
-- 解答その2
ngram' :: Int -> [a] -> [[a]]
ngram' n = List.filter (\xs -> List.length xs == n) . List.map (List.take n) . List.tails
main :: IO()
main = do
let sentence = "I am an NLPer"
wbigram = Main.ngram 2 $ List.words sentence -- 単語bi-gram
cbigram = Main.ngram 2 sentence -- 文字bi-gram
IO.print wbigram
IO.print cbigram
출력[["I","am"],["am","an"],["an","NLPer"]]
["I "," a","am","m "," a","an","n "," N","NL","LP","Pe","er"]
Reference
이 문제에 관하여(Haskell에서 자연언어 처리 100개 노크의 제1장을 풀어본다. 【중편~bi-gram이란】), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/ayase/items/0deb22e34787ddcd3132
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
그래서 하나의 기사로했습니다.
문제와 해답에 이르기까지의 과정
05. n-gram
주어진 시퀀스 (문자열, 목록 등)에서 n-gram을 만드는 함수를 만듭니다. 이 함수를 사용하여 "I am an NLPer"라는 문장에서 단어 bi-gram, 문자 bi-gram을 얻습니다.
우선, n-gram
이란 무엇인가로부터 시작되어 버린다.
우선 위키로 조사한다.
「N문자 인덱스법」 「N그램법」 등이라고도 한다. 검색 대상을 단어 단위가 아닌 문자 단위로 분해하고 후속 N-1 문자를 포함한 상태에서 출현 빈도를 구하는 방법.
분명히 ↑만으로는 모르겠다. (영어판 wiki에는 다소 자세하고 있다.)
그 밖에도 조사해 가면,
이웃 (연속) n 개
등으로 쓰여져 드디어 다가온다.
조사를 진행하면 아무래도
単語n-gram
는 연속 n개의 단어文字n-gram
는 연속 n개의 문자
라는 인식인것 같다.
n이 2일 때 n-gram은 bi-gram이라고도 할 수 있는 것 같다.
구체적으로 보면,
↑ 출처
위는 "This is a sentence"
에 대하여 単語n-gram
이다.文字n-gram
는 최소 단위를 단어가 아닌 문자로 한 버전이라고 봐도 좋을 것이다.
그렇다면 Haskell에서는 어떻게 n-gram
함수를 사용합니까?
리스트의 선두의 n개를 취해, 다음은 리스트의 선두를 들여다 본 리스트로부터 선두의 n개를 취해,....
라고 할 수 있으므로 再帰
에 의한 정의를 할 수 있는 것 같다.
실제로 take
와 drop
를 사용하여,
ngramngram :: Int -> [a] -> [[a]]
ngram n xs | n <= length xs = take n xs : ngram n (drop 1 xs)
| otherwise = []
같이 재귀로 기술할 수 있다.
다만, 구그하면 다른 것에도 여러 가지 방법은 있는 것 같다.
본 것에 공통적으로 보이는 것은
꼬리와 맵과 takemap (take n) . tails
사용하는 방법입니다.tails
함수는 부분 목록 목록을 생성하는 함수로, 예를 들어 "sentence"
에 tails
를 적용하면
꼬리Prelude Data.List> tails "sentence"
["sentence","entence","ntence","tence","ence","nce","ce","e",""]
와 같이, 가장 큰 요소가 리스트의 선두가 된다.
그러므로 map (take n)
를 계속 적용하면
꼬리와 맵과 takePrelude Data.List> map (take 2) . tails $ "sentence"
["se","en","nt","te","en","nc","ce","e",""]
같은 결과가 된다.
그리고는 take 되어, filter 나름을 쓰면 기대하는 결과를 얻을 수 있다.
그래서 해답은 다음과 같습니다.
05.hsmodule Main where
import qualified Data.List as List
import qualified System.IO as IO
-- 解答その1
ngram :: Int -> [a] -> [[a]]
ngram n xs | n <= List.length xs = List.take n xs : ngram n (List.drop 1 xs)
| otherwise = []
-- 解答その2
ngram' :: Int -> [a] -> [[a]]
ngram' n = List.filter (\xs -> List.length xs == n) . List.map (List.take n) . List.tails
main :: IO()
main = do
let sentence = "I am an NLPer"
wbigram = Main.ngram 2 $ List.words sentence -- 単語bi-gram
cbigram = Main.ngram 2 sentence -- 文字bi-gram
IO.print wbigram
IO.print cbigram
출력[["I","am"],["am","an"],["an","NLPer"]]
["I "," a","am","m "," a","an","n "," N","NL","LP","Pe","er"]
Reference
이 문제에 관하여(Haskell에서 자연언어 처리 100개 노크의 제1장을 풀어본다. 【중편~bi-gram이란】), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/ayase/items/0deb22e34787ddcd3132
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
ngram :: Int -> [a] -> [[a]]
ngram n xs | n <= length xs = take n xs : ngram n (drop 1 xs)
| otherwise = []
map (take n) . tails
Prelude Data.List> tails "sentence"
["sentence","entence","ntence","tence","ence","nce","ce","e",""]
Prelude Data.List> map (take 2) . tails $ "sentence"
["se","en","nt","te","en","nc","ce","e",""]
module Main where
import qualified Data.List as List
import qualified System.IO as IO
-- 解答その1
ngram :: Int -> [a] -> [[a]]
ngram n xs | n <= List.length xs = List.take n xs : ngram n (List.drop 1 xs)
| otherwise = []
-- 解答その2
ngram' :: Int -> [a] -> [[a]]
ngram' n = List.filter (\xs -> List.length xs == n) . List.map (List.take n) . List.tails
main :: IO()
main = do
let sentence = "I am an NLPer"
wbigram = Main.ngram 2 $ List.words sentence -- 単語bi-gram
cbigram = Main.ngram 2 sentence -- 文字bi-gram
IO.print wbigram
IO.print cbigram
[["I","am"],["am","an"],["an","NLPer"]]
["I "," a","am","m "," a","an","n "," N","NL","LP","Pe","er"]
Reference
이 문제에 관하여(Haskell에서 자연언어 처리 100개 노크의 제1장을 풀어본다. 【중편~bi-gram이란】), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ayase/items/0deb22e34787ddcd3132텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)