Vim script의 마르코프 체인

개시하다


이 글은 Vim Advent Calendar 2020의 글이 아닙니다.
갑자기 Vim script로 마르코프를 잠그면 재밌을 것 같아서 살짝 해봤어요.

마르코프 체인


글에 나오는 문구와 연결된 문구로 나무를 구성하는 경우 나뭇가지가 빈번하게 나타난다.예를 들어'우리도'라는 두 문장에서 한 편의'우리도'라는 말은'우리도'에서'화'까지의 확률이'우리'에서'도'까지의 확률보다 높다.위에서 말한 바와 같이 현재의 상태(우리)의 다음 상태는 이전의 문장에 의존하지 않고 결정되는 상태를 마르코프성이라고 하고 일련의 확립 변수를 마르코프 연쇄라고 한다.
P(X_{t+1}∣X_{t},X_{t−1},…,X_{1})=P(X_{t+1}∣X_{t})
그림에서 보듯이 아래와 같다.

참조: 조개 스크립트로 트위터 봇 만들기 입문

저는 쉬웠지만.


나는 매우 간단하다고 생각한다. 자세히 생각해 보면, Vim script로 구분해서 쓰는 것은 매우 어렵다.창고도 없고.채팅방을 원해요...
어쩔 수 없기 때문에 유니코드 문자 클래스로 구분합니다.
let s:classes = [
\ [0x037e, 0x037e, 1],
\ [0x0387, 0x0387, 1],
\ [0x055a, 0x055f, 1],
  ......
\ [0xff1a, 0xff20, 1],
\ [0xff3b, 0xff40, 1],
\ [0xff5b, 0xff65, 1],
\ [0x20000, 0x2a6df, 0x4e00],
\ [0x2a700, 0x2b73f, 0x4e00],
\ [0x2b740, 0x2b81f, 0x4e00],
\ [0x2f800, 0x2fa1f, 0x4e00],
\]

let s:emoji = [
\ [0x203c, 0x203c],
\ [0x2049, 0x2049],
\ [0x2122, 0x2122],
  ......
\ [0x1f5fb, 0x1f640],
\ [0x1f645, 0x1f64f],
\ [0x1f680, 0x1f6c5],
\]

function! s:is(r) abort
  if a:r < 0x100
    if index([0x20, 0x14, 0x00, 0xa0], a:r) != -1
      return 0
    endif
    return index([0x2c, 0x3001, 0x3002], a:r) != -1 ? 1 : 2
  endif
  for l:v in s:classes
    if l:v[0] <= a:r && a:r <= l:v[1]
      return l:v[2]
    endif
  endfor
  for l:v in s:emoji
    if l:v[0] <= a:r && a:r <= l:v[1]
      return 3
    endif
  endfor
  return 2
endfunction

function! s:split(s) abort
  let l:result = []
  let [l:pos, l:cur, l:old] = [0, 0, 0]
  let l:rs = split(a:s, '\zs')
  for l:r in map(copy(l:rs), 'char2nr(v:val)')
    let l:new = s:is(l:r)
    if l:cur != 0 && l:new != l:old
      call add(l:result, join(l:rs[l:pos : l:cur - 1], ''))
      let l:pos = l:cur
    endif
    let l:old = l:new
    let l:cur += 1 
  endfor
  call add(l:result, join(l:rs[l:pos :], ''))
  return l:result
endfunction
s:split를 해당 私の名前は中野です에게 전달한 후
['私', 'の', '名前', 'は', '中野', 'です']
되돌아오다.정확한 형태소 해석의 담화 형식은 아니지만 얼렁뚱땅 넘어갈 수 있다.

본제의 마르코프 체인


업데이트용 update 방법
let s:markov = {'tbl': {}}

function markov#new() abort
  return s:markov
endfunction

function! s:markov.update(s) abort
  let l:words = s:split(a:s)
  call filter(l:words, {_, v -> (char2nr(v) < 255 && v =~ '\w') || index(['、', '。'], v) ==# -1})
  let l:size = len(words)

  if l:size ==# 1
    if !has_key(self.tbl, l:words[0])
      let self.tbl[l:words[0]] = []
    endif
    return
  endif
  let l:last = ''
  for l:i in range(0, l:size - 2)
    if !has_key(self.tbl, l:words[l:i])
      let l:second = []
      let self.tbl[l:words[l:i]] = l:second
    else
      let l:second = self.tbl[l:words[l:i]]
    endif
    let l:last = l:words[i+1]
    call add(l:second, l:last)
  endfor
  if has_key(self.tbl, l:last)
    let self.tbl[l:last] += repeat([''], len(l:words))
  endif
endfunction
생성 시작first
let s:bad = ['し', 'が', 'の', 'を', 'に', 'へ', 'と', 'から', 'より', 'やら', 'か', 'で', 'なり', 'だの', 'する', 'であり', 'く', 'において', 'う', 'い', 'え']

function! s:markov.first() abort
  let l:keys = keys(self.tbl)
  if len(l:keys) == 0
    return ''
  endif
  while 1
    let l:first = s:randi(l:keys)
    if index(s:bad, l:first) ==# -1
      return l:first
    endif
  endwhile
endfunction
우선 유사한 조사의 용법을 피한다.(고통)
그리고 체인chain을 만듭니다.
function! s:markov.chain(s) abort
  let l:first = a:s
  let l:text = l:first
  while l:first != ''
    let l:size = len(get(self.tbl, l:first, []))
    if l:size == 0
      break
    endif
    let l:next = s:randi(self.tbl[l:first])
    let l:text .= l:next
    let l:first = l:next
  endwhile
  return l:text
endfunction
빈 물건에 update의 엉덩이로 몇 가지 요소를 덧붙이는 데 신경을 썼다."행동하는 모습"과 같이 "행동하는 모습"으로 끝나는 문장과 "행동하는 모습"처럼 "행동하는 모습"으로 끝나는 문장은 "말미에"를 사라지게 하기 때문에 높은 확률의 내용을 의식적으로, 의식적으로 추가한다.

시험해 보다


Vim이 플러그인화되었습니다.
https://github.com/mattn/vim-markov
이 플러그인을 가져오면 일본어가 많이 쓴 문장:Markov을 열면 요약 문장을 완성할 수 있습니다.다음은 일본 헌법 전문이 완충구 내에서 여러 차례 실험을 한 결과이다
나는 전제가 영원히 땅에서 전국의 자유가 가져온 혜택을 따르는 것이 자기 나라의 책임과 의무라고 믿는다
결심했어
한 지위를 지배하다
정부 관계를 유지하고 우리와 우리의 자손을 위해 각국 국민의 관계를 통해 행동하는 이 헌법은 국가의 공정과 평등 관계를 없애기 위해 노력하는 국제 사회에서 모든 대가를 아끼지 않고 숭고한 이상을 사랑한다
잘 모르는 글을 많이 썼다.

끝말


또 심심한 짓을 했다.2020년 25일에 기사를 쓰기 시작하지도, 소재를 고려하지도 않았지만 좀 더 좋은 기사를 쓰고 싶다는 계획을 세웠다.

좋은 웹페이지 즐겨찾기