/
partial.Rmd
73 lines (54 loc) · 4.42 KB
/
partial.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
---
title: "How to Use Partial Parsing Mode"
description: "制約付き解析(部分解析)について"
author: "paithiov909"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{How to Use Partial Parsing Mode}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(
tidy = "styler",
collapse = TRUE,
comment = "#>"
)
set.seed(3013)
```
## 制約付き解析(部分解析)について
MeCabのやや発展的な使い方のひとつとして、[制約付き解析](https://taku910.github.io/mecab/partial.html)があります。
> 入力文の一部の形態素情報が既知である、あるいは境界がわかっているときに、 それを満たすように解析する機能です。
>
> たとえば、「にわにはにわにわとりがいる。」という文に対して、 「はにわ」の部分が名詞であるとか、「にわとり」の部分が一つの形態素 であるというように指定した上で解析することができます。このとき、 制約に反する4文字目の「は」が単独で形態素となったり、「にわとり」が「にわ」と「とり」 に分割されるような解析候補は排除されます。
制約付き解析を利用するには、解析させたい文を「文断片」や「形態素断片」に分けながら与えます。
それぞれの文断片や形態素断片は、改行(`\n`)によって分けられます。文断片については通常と同じように形態素解析がおこなわれますが、文断片や形態素断片の間をまたぐような解析結果は抑制されます。また、形態素断片は`表層形\t素性パターン`のようなかたちで与えることができます。形態素断片についてはそれ以上分割されず、与えられた断片がそのままのかたちで出力されます。
## IPA辞書による素の解析の場合
一例として、ここではIPA辞書を使って、「月ノ美兎」という語彙を含む文を解析してみます。`posDebugRcpp`は、与えられた文字列について、MeCabの`-a`オプションに相当する解析結果(解析結果になりえるすべての形態素の組み合わせ)を出力する関数です。ここでの最適解(`is_best == "01"`)である結果について確認すると、「月ノ美兎」という語彙は次のように複数の形態素に分割されてしまっていることがわかります。
```{r}
gibasa::posDebugRcpp("月ノ美兎は箱の中") |>
dplyr::filter(is_best == "01")
```
## 制約付き解析(部分解析)の場合
そこで、「月ノ美兎」という語彙を形態素断片として与えてみます。なお、`posDebugRcpp`では、`partial=TRUE`にすると`-a`に相当するオプションは無効になり、最適解のみが出力されます。
```{r}
gibasa::posDebugRcpp("月ノ美兎\t名詞,固有名詞,人名,*,*,*\nは箱の中", partial = TRUE)
```
これでひとまず期待どおりに解析することができました。こうした使い方のほかに、形態素断片の素性パターンにワイルドカード(`*`)を使うと、その単語を切り出しながら品詞については適当なものを付与させることができます。以下では「月ノ美兎」については常に単語として切り出しながら、品詞は適当なものを付与させています。
```{r}
gibasa::posDebugRcpp("月ノ美兎\t*\nは箱の中", partial = TRUE)
```
## 具体的な使用例
`partial`引数は`tokenize`にも実装されています。実用的には、たとえば次のように使えるかもしれません。
```{r}
sentences <- c(
"証券コードは4桁の銘柄識別コードです。",
"たとえば、7777です。あるいは7777 JPや7777.Tというのもあります。",
"また「7777JP」のような全角文字を使う表し方もあるかもしれません。"
)
sentences |>
stringi::stri_replace_all_regex("(?<codes>[0-9\uFF10-\uFF19]{4}((\\s|\\.)+[a-zA-Z]{1,2}|[\uFF21-\uFF3A]{2}))", "\n${codes}\t*\n") |>
gibasa::tokenize(partial = TRUE, mode = "wakati")
```
なお、この機能を利用時に、文断片や形態素断片の先頭や末尾に半角スペースが含まれていると、MeCab側でエラーが発生し、解析に失敗する場合があるので注意してください。