Python奮闘記 目次

《 はじめに 》

 知財情報の分析に強力なツールになると思い、Pythonの勉強を始めました。きっかけになったのは、株式会社ライズの東智朗さんが開催してくださった「知財人のためのPython」です。初心者の私に初歩から丁寧に教えてくださいました。どうもありがとうございました。

 タイトルに「奮闘記」とあるように、勉強している過程をブログ風に記録したもので、みなさまに解説する意図はありません。紹介している「例」も一例に過ぎず、模範解答からはほど遠いものがたくさん含まれていると思います。

 同じようにPythonの勉強を始めたばかりの初心者の方々、これから始めようとされている方のご参考になれば嬉しいです。また、経験者の方々からのアドバイスも大歓迎です。

《 目 次 》

開発環境:Python開発環境の準備 Anacondaのインストール

基礎-1:入出力、データ型、演算、if文、whileループ、forループ

基礎-2:リスト、タプル、辞書 (「配列」に相当するデータ型)

基礎-3:def文(関数定義、サブルーチンに相当)

基礎-4:文字列処理

基礎-5:正規表現

基礎-6:csvファイルの読み込み

基礎-7:EXCELファイルの読み書き

基礎-8:pdfファイルの読み込み

圧縮されたファイルの解凍:csvダウンロードなどで入手した、zip形式で圧縮されたファイルを解凍

csvデータの前処理:EXCELファイルのシート(複数も可)に保存されているcsvダウンロードしたデータに対する、特許分析に適した前処理

ダウンロードしたcsvに対する発明者分析:ダウンロードしたcsvファイルの特許文献リストから、発明者ごとに出願年と件数を抽出

出願人名の名寄せ:csvファイルなどの特許文献リストに含まれる出願人名の名寄せ。(名寄せとは、社名変更などで複数の表記がある出願人名を1つにまとめる作業。)(対応表はマニュアルで作って、文字列処理だけpyhtonに任せる。)

正規表現を使ったFターム分析:特許に付与されているFタームに応じてフラグを立てる。事例研究「リチウムイオン電池の電極材料の特許マップ」で採用した前処理。

 

[Python] 基礎-8 pdfファイルの読み込み

1.準備

 “pypdf”モジュールのインストール
Anaconda Powershell Prompt >> pip install pypdf

2.複数のpdfファイルの連結(PdfMerger)

“””
import pypdf
#
merger = pypdf.PdfMerger()       👈オブジェクト作成
merger.append(‘source\\願書.pdf’)     👈pdfファイルを結合
merger.append(‘source\\明細書.pdf’)
merger.append(‘source\\特許請求の範囲.pdf’)
merger.append(‘source\\要約書.pdf’)
merger.append(‘source\\図面.pdf’)

merger.append(‘source\\受領書.pdf’)
#
merger.write(‘merged.pdf’)         👈pdfファイルを出力
merger.close()                👈オブジェクトを解放

 

[Python] 正規表現を使ったFターム分析

〘 背景 〙

日本の特許文献には、FIとFタームと呼ばれる特許分類が付与されている。FIは国際特許分類(IPC)と同じ階層構造で、日本の実情に合わせて細分化されている。Fタームは、テーマコードごとに種々の観点について付与された特許分類コードである。出願された特許文献の内容に応じて付与されるので、内容を読む代わりに付与されているFIやFタームを分析対象とすることで、特許文献の内容分析ができる。
以下の例は、事例研究「リチウムイオン電池の電極材料の特許マップ」で紹介した特許マップを作成するための前処理。

〘 課題 〙

1件の特許文献には複数の(多くの)特許分類コードが付与されている。前処理として、どのコードが付与されているかを表すフラグを立てる。分析対象の特許文献それぞれにフラグを立てる処理をしておけば、後段に分析目的に合わせた集計処理を行えば良い。
特許分類は、FIもFタームもIPCも階層構造をもつので、立てるフラグは階層関係を反映するように設計する。

〘 仕様 〙

処理対象:EXCELの特許文献リスト()
各特許文献に、FI, Fターム, IPCなどの項目が含まれていること

入力 「Fターム」カラム
例=“5H050 AA02;5H050 AA08;5H050 BA17;5H050 CA08;5H050 CA09;5H050 CB01;5H050 CB02;5H050 CB08;5H050 CB11;5H050 DA03;5H050 DA04;5H050 DA10;5H050 DA11;5H050 DA18;5H050 EA23;5H050 EA24;5H050 EA28;5H050 FA02;5H050 FA17;5H050 GA10;5H050 HA00;5H050 HA01;5H050 HA20
出力 フラグを立てる複数のカラム
特許文献のレコードに立てたフラグ(1/” “

注:フラグを立てる対象のFタームが上位階層なら、それに含まれる下位階層のFタームでもフラグが立つようにプログラミングする。但し、階層関係はプログラマーが解釈してソースコード内に正規表現で記述する。

〘 階層構造を考慮した正規表現〙

Fタームの階層構造の例は、以下のとおり。上述の「リチウムイオン電池の電極材料の特許マップ」で分析対象としたテーマコード「電池の電極および活物質」(5H050)の「正極活物質」(CA00)である。

フラグを立てたい範囲を緑の枠取りで示す。フラグを立てたい範囲を正規表現で表す(各正規マッチマッチオブジェクトを生成する)。

例1:CA03(Niを主体とするもの)の下位概念にはCA04(Coを固溶するもの)を下位に含むので、CA03 or CA04が付与されていればCA03のフラグ(CA01)を立てる。

CA01 = re.compile(‘5H050 (CA03|CA04)’) 

例2:CA19(有機化合物)の下位概念にはCA20(ポリマーまたは重合体)~CA27(ハロゲン原子を有するもの)を下位に含むので、CA19 ~ CA27が付与されていればCA19のフラグ(CA12)を立てる。

CA12 = re.compile(‘5H050 (CA19|CA2[0-7])’)

フラグを立てたいすべてのFタームについて、マッチオブジェクトを生成する。

〘 各レコード(特許文献)についてフラグを立てる 〙

searchメソッドを使って、マッチオブジェクトにマッチするパターンが、対象レコード(特許文献)のFタームカラムの文字列に含まれているかを判定し(if文)、EXCELの所定カラムに出力する。

〘 ソースコード 〙

# -*- coding: utf-8 -*-
"""
Fターム分析
 電池の電極および活物質(5H050)のLiイオン電池(BA17)にヒットする文献について、
 正極と負極の活物質材料として付与されているFタームのフラグを立てる
 入力: ダウンロード項目にFタームを含む特許文献リスト
 出力: 各文献について、付与されているFタームにフラグを立てる
 newly created                           2022.9.19 H. Kojima
"""
import openpyxl, re
path = "C:\\Users\\kojim\\Dropbox\\事例研究\\Liイオン電池の電極材料分析"
file_name  = "5H050_DB.xlsx"
workbook = openpyxl.load_workbook(path+"\\"+file_name)
# 特許文献シート
sheet_db = workbook.get_sheet_by_name('db')
col_Fterm = 17
# 正極活物質
CA01 = re.compile('5H050 (CA03|CA04)')
CA02 = re.compile('5H050 CA05')
CA03 = re.compile('5H050 CA06')
CA04 = re.compile('5H050 (CA07|CA08|CA09)')
CA05 = re.compile('5H050 CA10')
CA06 = re.compile('5H050 CA11')
CA07 = re.compile('5H050 CA12')
CA08 = re.compile('5H050 CA15')
CA09 = re.compile('5H050 CA16')
CA10 = re.compile('5H050 CA14')
CA11 = re.compile('5H050 CA17')
CA12 = re.compile('5H050 (CA19|CA2[0-7])')
CA13 = re.compile('5H050 (CA29|CA30)')
# 負極活物質
CB01 = re.compile('5H050 (CB02|CB03)')
CB02 = re.compile('5H050 CB04')
CB03 = re.compile('5H050 CB05')
CB04 = re.compile('5H050 CB08')
CB05 = re.compile('5H050 CB09')
CB06 = re.compile('5H050 CB07')
CB07 = re.compile('5H050 CB12')
CB08 = re.compile('5H050 CB13')
CB09 = re.compile('5H050 CB14')
CB10 = re.compile('5H050 CB15')
CB11 = re.compile('5H050 (CB16|CB17|CB18)')
CB12 = re.compile('5H050 (CB19|CB2[0-7])')
CB13 = re.compile('5H050 (CB29|CB30)')
#
#   Start processing
for line in range(2, sheet_db.max_row+1):
    Fterm = sheet_db.cell(row=line,column=col_Fterm).value
    if re.search(CA01, Fterm):
        sheet_db.cell(row=line,column=37).value = 1
    if re.search(CA02, Fterm):
        sheet_db.cell(row=line,column=38).value = 1
    if re.search(CA03, Fterm):
        sheet_db.cell(row=line,column=39).value = 1  
    if re.search(CA04, Fterm):
        sheet_db.cell(row=line,column=40).value = 1  
    if re.search(CA05, Fterm):
        sheet_db.cell(row=line,column=41).value = 1  
    if re.search(CA06, Fterm):
        sheet_db.cell(row=line,column=42).value = 1  
    if re.search(CA07, Fterm):
        sheet_db.cell(row=line,column=43).value = 1  
    if re.search(CA08, Fterm):
        sheet_db.cell(row=line,column=44).value = 1  
    if re.search(CA09, Fterm):
        sheet_db.cell(row=line,column=45).value = 1
    if re.search(CA10, Fterm):
        sheet_db.cell(row=line,column=46).value = 1
    if re.search(CA11, Fterm):
        sheet_db.cell(row=line,column=47).value = 1
    if re.search(CA12, Fterm):
        sheet_db.cell(row=line,column=48).value = 1
    if re.search(CA13, Fterm):
        sheet_db.cell(row=line,column=49).value = 1
    if re.search(CB01, Fterm):
        sheet_db.cell(row=line,column=51).value = 1
    if re.search(CB02, Fterm):
        sheet_db.cell(row=line,column=52).value = 1
    if re.search(CB03, Fterm):
        sheet_db.cell(row=line,column=53).value = 1 
    if re.search(CB04, Fterm):
        sheet_db.cell(row=line,column=54).value = 1 
    if re.search(CB05, Fterm):
        sheet_db.cell(row=line,column=55).value = 1 
    if re.search(CB06, Fterm):
        sheet_db.cell(row=line,column=56).value = 1 
    if re.search(CB07, Fterm):
        sheet_db.cell(row=line,column=57).value = 1 
    if re.search(CB08, Fterm):
        sheet_db.cell(row=line,column=58).value = 1 
    if re.search(CB09, Fterm):
        sheet_db.cell(row=line,column=59).value = 1 
    if re.search(CB10, Fterm):
        sheet_db.cell(row=line,column=60).value = 1
    if re.search(CB11, Fterm):
        sheet_db.cell(row=line,column=61).value = 1 
    if re.search(CB12, Fterm):
        sheet_db.cell(row=line,column=62).value = 1
    if re.search(CB13, Fterm):
        sheet_db.cell(row=line,column=63).value = 1 
workbook.save(path+"\\"+file_name)

〘 出力(フラグを出力したEXCELのカラム)〙

裁判所判例検索

「判決が出た」などの報道があると、詳しい情報を得るために判決文そのものにあたりたいことがある。

例えば、当ライブラリでも事例研究で紹介した「セルフレジ特許訴訟」にも判決が出た。「ファストリ、無人レジ特許訴訟で敗訴~知財高裁、商品識別巡り」(2021/5/21付け日経新聞)また、例えば、「LINE「ふるふる」機能、特許侵害で賠償命令(東京地裁)」(2021/5/20付け日経新聞)もある。

そんなときに使うのが「裁判所(COURT IN JAPAN)」である。

早速、原告名「アスタリスク」で検索してみた。

ところが、ヒットしたのは別件ばかり……

判決文の全文検索であるため、「アスタリスク」という語が使われていれば、会社名でなくてもヒットする。「株式会社アスタリスク」とすべきだった。

とは言え、やはりまだデータベースに収録されてはいないらいしい。

日付で検索してみると、

検索した2021/5/23時点で、最新は5/17付け最高裁判決、知財高裁の最新は5/13だった。判決から1~2週間でデータベースに収録されているようである。

(判決文が収録されたら、更新する予定)

[Python] 基礎-7 EXCELファイルの読み書き

1.一般的な流れ

“openpyxl”モジュールをインポート:import openpyxl
Workbookを開く:openpyxl.load_workbook(“ファイル名”)
シートオブジェクトを生成:sheet_obj = workbook.get_sheet_by_name(“シート名”)

2.セルの値の読み書き(cell(row=行番号, column=列番号).value)

〔 値の取り込み 〕
変数 = sheet_obj.cell(row=行番号, column=列番号).value

〔 値の書き込み 〕
sheet_obj.cell(row=行番号, column=列番号).value = 値

3.行/列 単位の扱い( iter_rows() / iter_cols() )

(iteration processにより)1行ごと(1列ごと)に、リストを生成する。

〔 使い方の例 〕

for row in sheet_obj.iter_rows():
for col in range(len(row)):
print(row[col])

4.フォントの指定

〔 流れ 〕
① Font関数をopenpyxlモジュールのstyleからインポート
  from openpyxl.styles import Font
② フォントの指定
  font = Font(name=’フォント名’, size=ポイント数, ・・・)
③ 指定したフォントをセルに指定
  sheet_obj.cell(row=line,column=col+1).font = font

パラメータ説明
nameフォント名/例:’游ゴシック’, ‘Arial’
sizeポイント数/例:「size=10」等整数値で指定
color色を16進6桁の文字列で指定
例:’FF0000’(赤), ’00FF00’(緑), ‘0000FF’(青)
underline下線を文字列で指定/例:’single’
bold太字/例:True, False
italic斜字/例:True, False

5.位置揃え

〔 流れ 〕
① Alignment関数をopenpyxlモジュールのstyleからインポート
  from openpyxl.styles import Alignment
② セルごとにAlignmentを指定
  sheet_obj.cell(row=line,column=col+1).alignment
  = Alignment(horizontal=’left’,
   vertical=’top’,
   wrapText=None)

〔 Alignment関数の引数とパラメータ 〕

    引数パラメータ説明
horizontal‘left’
‘center’
‘right’
左揃え
中央揃え
右揃え
vertical‘top’
‘center’
‘bottom’
上揃え
中央揃え
下揃え
textWrapTrue
None
セル内折り返しあり
指定せず

6.セルの表示形式

〔 流れ 〕
① numbersをopenpyxlモジュールのstyleからインポート
  from openpyxl.styles import numbers
② セルのフォーマットを指定
  sheet_obj.cell(row=line,column=col+1).number_format = 表示形式

    表示形式 説明
‘0.000’小数点以下3桁
#,##0′3桁ごとにカンマ区切り&小数点以下は非表示
‘yyyy/mm/dd’短い日付(西暦4桁/月/日)

7.セルの幅と高さ

〔 セル幅の指定 〕
sheet_obj.column_dimensions[’A’].width= セル幅

〔 セル高の指定 〕
sheet_obj.row_dimensions[1].height = セル高さ

[Python] 基礎-6 csvファイルの読み込み

1.一般的な流れ

(1) “csv”モジュールを使った読み込み
“csv”モジュールをインポート import csv
open関数を使ってcsvファイルオブジェクト(csv_obj)を生成
csv_obj.reader ⇒ 行単位(iteratorプロトコル対応)オブジェクトをリスト形式で生成
csv_obj.DictReader ⇒ 行単位(iteratorプロトコル対応)オブジェクトを辞書形式で生成

(2) “panda”モジュールを使った読み込み
“panda”モジュールをインポート import pandas
データ分析用のモジュール・・・いつか使ってみたい

2.”csv”モジュールを使った読み込み

open関数

使い方の例:

with open(path+’\’+csv_A, mode=’r’, encoding=’utf_8′) as csv_obj:

引数     説明
mode“r”: read only
“w”: 書き込み許可
“x”: 排他的。
“a”:ファイルがあるときは追記
encoding 文字コード
 ”utf-8″:日本語
newlineex.: None, ”, ‘\n’, ‘\r’, ‘\r\n’

reader

使い方の例:

with open(ファイル名, mode=’r’, encoding=’utf_8′) as csv_obj:
csv_reader = csv.reader(csv_obj)
header = next(csv_reader)
print(header) 👈 headerはリスト
for row in csv_reader:
print(row[0]) 👈 rowはリスト