知財のあれこれをPythonで何とかする

### マルチマルチクレームを何とかする
今回はマルチマルチクレームをチェックするプログラムを作ってみました。

```python:Program1.py
#part1 請求項と従属先のセットを作成

import re
import unicodedata
import copy

meisai = []
ms_base = []
f = open('meisai.txt', 'r')#ANSIで保存すること
ms_base = f.read()
f.close()
ms_base=unicodedata.normalize("NFKC", ms_base)#請求項数の数値を半角にする
meisai = re.split("【",ms_base)#請求項ごとに分割する
meisai.pop(0)

clm_gr_base=[]
clm_item=[]
for ms_part in meisai:
    clm_item.append(re.findall(r'請求項(\d+)', ms_part))

clm_gr_base = [[int(x) for x in sublist] for sublist in clm_item]

result_list=[]
for elm in clm_gr_base:
    if len(elm)==1:#末尾に０をたす
        elm.append(0)
        result_list.append(elm)
        
    elif len(elm)==2:
        result_list.append(elm)
        
    elif len(elm)>2:#最初の要素と2番目以降の要素がセットになったリストに変換する
        first_element = elm[0]
        result_list.extend([[first_element, x] for x in elm[1:]])

clm_gr = sorted(result_list)

#part2 マルチクレーム判定

from itertools import groupby
#clm_grの[]を、先頭の要素でグループ化する
clm_gr.sort(key=lambda x: x[0])
grouped_clm_gr = [list(group) for key, group in groupby(clm_gr, key=lambda x: x[0])]
print("grouped_clm_gr",grouped_clm_gr)

# grouped_clm_grの[]を先頭の要素でカウントする
counted_data = [[sublist[0][0], len(sublist)] for sublist in grouped_clm_gr]
print("counted_data",counted_data)

#part3 マルチマルチ判定
with open('multi_multi.txt', 'w') as f:#ツリーの書込み先ファイルをクリアする
     print("", file=f)

flag=0
mu_mu=[]
for elm in counted_data:
    if elm[1]>1:
        for clm in clm_gr:
            if clm[0]==elm[0]:
                for elm2 in counted_data:
                    if elm2[0]==clm[1] and elm2[1]>1:
                        mu_mu.append(elm2[0])
        if len(mu_mu)>0:
            flag=1
            with open('multi_multi.txt', 'a') as f:
                print("請求項",elm[0],"は、マルチクレーム",mu_mu,"に従属するマルチマルチクレームです！", file=f)
            mu_mu=[]
if flag==0:
    with open('multi_multi.txt', 'w') as f:
     print("マルチマルチクレームはありませんでした。", file=f)
```
以下のサンプルをファイル名「meisai.txt」としてANSI形式で保存します。
<details><summary>サンプルデータ</summary>

```rb
【請求項１】
○○手段を有する情報処理装置。
【請求項２】
前記情報処理装置であって××手段を有する請求項１記載の情報処理装置。
【請求項３】
前記情報処理装置であって△△手段を有する請求項２記載の情報処理装置。
【請求項４】
前記情報処理装置であって◇◇手段を有する請求項２および請求項３記載の情報処理装置。
【請求項５】
前記情報処理装置であって□□手段を有する請求項２および請求項３および請求項４記載の情報処理装置。
```
</details>
program1を実行すると以下のようにマルチマルチクレームの判定結果を作成しmulti_multi.txtに書き込み保存します。

```
請求項 5 は、マルチクレーム [4] に従属するマルチマルチクレームです！
```

### プログラムのポイント
 - (part1)
 ここでのポイントは「【請求項４】・・有する請求項２および請求項３・・」となっているのを取り込んで[4, 2, 3]としてリスト化したものを[4, 2], [4, 3]に変換する部分です。以前投稿したプログラム[（クレームツリーを何とかする（その1））](https://qiita.com/nop_z80/items/7fc4405ff4b35747912d)と同じプログラムを流用しています。

- (part2)
請求項ごとに従属先をカウントしてリストにします。

```python:
#clm_grの[]を、先頭の要素でグループ化する
clm_gr.sort(key=lambda x: x[0])
grouped_clm_gr = [list(group) for key, group in groupby(clm_gr, key=lambda x: x[0])]
print("grouped_clm_gr",grouped_clm_gr)
```
上記処理によりgrouped_clm_grが以下のように作成されます。請求項1だけに従属する請求項2だと[[2, 1]]、請求項2と請求項3に従属する請求項４だと [[4, 2], [4, 3]]として１つ深い階層にグループ化されます。
```
[[[1, 0]], [[2, 1]], [[3, 2]], [[4, 2], [4, 3]], [[5, 2], [5, 3], [5, 4]]]
```

```python:
# grouped_clm_grの[]を先頭の要素でカウントする
counted_data = [[sublist[0][0], len(sublist)] for sublist in grouped_clm_gr]
print("counted_data",counted_data)
```
次に上記の処理によりcounted_dataが以下のように作成されます。請求項1だけに従属する請求項2だと従属先が1つなので[2, 1]、請求項2と3に従属する請求項4だと従属先が2つなので[4,2]請求項2と3と4に従属する請求項5だと従属先が3つなので[5,3]  となります。
```
 [[1, 1], [2, 1], [3, 1], [4, 2], [5, 3]]
```
- (part3)
マルチクレームの従属先がマルチクレームかどうかを判定し、マルチマルチクレームと判定したらmulti_multi.txtに追記します。
```python:
for elm in counted_data:
    if elm[1]>1:
        for clm in clm_gr:
            if clm[0]==elm[0]:
                for elm2 in counted_data:
                    if elm2[0]==clm[1] and elm2[1]>1:
                        mu_mu.append(elm2[0])
```
counted_dataでループ処理しelm[1]（従属先の数）が1より大きい(マルチクレーム)で（if elm[1]>1:）、clm_grでループ処理してclm[0]がelm[0]であれば、再度counted_dataでループ処理しelm2[0]==clm[1] かつ elm2[1]>1であればリストmu_muにelm2[0]を追加します。
例えば請求項5だとelm[]は[5,3],elm[1]は3なのでelm[1]>1となりclm_grでループ処理してclm[0]=5、elm[0]=5の時に再度counted_dataでループ処理しelm2[]=[4,2]、clm[]=[5,4]の時elm2[0]=4、clm[1]=4となりelm2[0]==clm[1]となりかつelm2[1]が1より大きい(マルチクレーム)のためelm2[0]の値4をリストmu_muに追加します。
その後はmulti_multi.txtにelm[0]の値5(=マルチマルチクレーム)、mu_muの値4(=マルチクレーム)を書き込みます。

### 注意点１
請求項の記載が「請求項ｎまたはｍ」や「請求項ｎないしｍ」といった記載ではうまく動作しませんので、以前投稿したmeisai.txtを書き換えるプログラム（[クレームツリーを何とかする（その2）](https://qiita.com/nop_z80/items/b387b6fa85aa9cf69c1d)）を利用ください。

### 注意点２
以下の処理で【請求項】の「【」を手掛かりにリストの分割をしているので、想定しない場所に「【」が存在すると動作がおかしくなる可能性があります。
```python:
meisai = re.split("【",ms_base)#請求項ごとに分割する
```
【】は必ず【請求項】の書式として使用されるようお願いします。

### 最後に
少し前に日本の特許庁もマルチマルチクレームが禁止になりましたので、マルチマルチクレームで出願すると記載不備となります。目視でチェックするのは大変なので、自動化できれば効率化のメリットが大きいと思います。
今回の記事がお役に立てれば幸いです。