Python法律實務——利用批量裁判文書內容制作行業白皮書(也可用于訴訟可視化實踐)
前面的文章介紹了裁判文書中數據信息的提取,裁判文書目前作為學術研究、案件指引最重要的大數據源,受到了越來越多的重視。在實際工作中,許多律所或者律師,出于學術研究、業務宣傳、品牌宣傳等目的,會在自己的公號或者私有媒體對一些行業案件進行歸納整理分析。根據這些數據的指引,我們不僅能了解到學習法律知識,同樣可以參照來作為案件的辦理指引。
接下來,筆者就以幫助專做勞動法的同事陳律師制作某個行業白皮書(餐飲行業的勞動法領域)的過程為例,來做深入的介紹。
實踐難度 :高
知識點涉及:正則表達式、python-docx庫處理docx文檔、pandas庫處理excel文檔、文件夾的遍歷、Pyecharts制作圖表
面向對象:掌握了Python初、中級別知識,熟悉了Python上述幾個模塊的基本使用方法的讀者。
第一步 數據準備
由于絕大部分讀者,不具備自建裁判文書數據庫的能力,所以需要提前到裁判文書、或者類似網站進行檢索,將檢索到的裁判文書進行批量下載。
筆者當然是有自己的數據庫的,但是為了演示,這里下載了2019年100多份相關的裁判文書。
第二步 設計編程思路
設計正則表達式,從文書中提取仲裁的請求
遍歷所有docx文檔,再利用python-docx庫遍歷文檔中的每一段進行正則匹配
將匹配結果導出excel表格中
處理和分析excel表格
將excel表格數據轉化為可視化圖表
第三步 編程與調試
pattern=".*?申請仲裁.{1,5}[請要]求" _re =re.compile(pattern,re.M|re.S|re.I) result=[] unmatched=[] files=[] for parent, dirnames, filenames in os.walk(r'餐飲大數據分析', followlinks=True): for filename in filenames: file_path = os.path.join(parent, filename) if '.docx' in file_path: _i={'fileName':filename,'filePath':file_path} files.append(_i) print(files) print('files length:',len(files))
正則表達式
為了提取到我們的目標段落,我們先要找一個樣本出來:
我們需要從判決書中找出雙方的仲裁請求的那一段,并提取出來,通過這一段樣本,我初步的正則表示為:
pattern=".*?申請仲裁.{1,5}[請要]求"
接下來我們要找出所有的docx文件,這個很簡單,之前的文章已經介紹過文件夾的遍歷:
files=[] for parent, dirnames, filenames in os.walk(r'餐飲大數據分析', followlinks=True): for filename in filenames: file_path = os.path.join(parent, filename) if '.docx' in file_path: _i={'fileName':filename,'filePath':file_path} files.append(_i) print(files) print('files length:',len(files)) ------------------------------------- [{'fileName': '10-上海廣增餐飲管理有限公司與雷楠勞動合同糾紛一審民事判決書.docx', 'filePath': '餐飲大數據分析\20200523004507\10-上海廣增餐飲管理有限公司與雷楠勞動合同糾紛一審民事判決書.docx'}, {'fileName': '11-宏葡(上海)餐飲有限公司與顏丹丹勞動合同糾紛一審民事判決書.docx', 'filePath': '餐飲大數據分析\20200523004507\11-宏葡(上海)餐飲有限公司與顏丹丹勞動合同糾紛一審民事判決書.docx'} …………] files length: 117
接下來,我們需要遍歷每一個word文件,并將word文檔按照段落進行匹配:
pattern=".*?申請仲裁.{1,5}[請要]求" _re =re.compile(pattern,re.M|re.S|re.I) result=[] unmatched=[] files=[] for parent, dirnames, filenames in os.walk(r'餐飲大數據分析', followlinks=True): # dirnames 子文件夾 for filename in filenames: file_path = os.path.join(parent, filename) if '.docx' in file_path: _i={'fileName':filename,'filePath':file_path} files.append(_i) for i in files: document = Document(i['filePath']) sig=0 for paragraph in document.paragraphs: res=_re.search(paragraph.text) if res is not None: _o={'fileName':i['fileName'],'filePath':i['filePath'],'paragraph':paragraph.text} result.append(_o) sig=1 break #匹配一次后,后面的段落就不再匹配 if sig==0: _o = {'fileName': i['fileName'], 'filePath': i['filePath']} unmatched.append(_o) print('result:',result) print('result length:',len(result)) print('unmatched:',unmatched) print('unmatched length:',len(unmatched)) ---------------------------------------- result: [{'fileName': '11-宏葡(上海)餐飲有限公司與顏丹丹勞動合同糾紛一審民事判決書.docx',…………] result length: 61 unmatched: [{'fileName': '10-上海廣增餐飲管理有限公司與雷楠勞動合同糾紛一審民事判決書.docx', ……] unmatched length: 56
_re =re.compile(pattern,re.M|re.S|re.I)
由于同一個正則表達式要多次重復使用,為了提升匹配效率,可以使用re.compile()來編譯正則表達式,生成一個正則表達式對象,從而提升效率。
document = Document(i['filePath'])
先實例化一個docx對象
for paragraph in document.paragraphs
依次遍歷這個docx對象中所有的段落
我們將匹配到的結果放入到result這個別表中,沒匹配到的放到unmatched中,上面的結果可以看到result的長度只有61個,說明只匹配到了61個文檔,顯然這個正則表達式,匹配成功率不高。
為了作進一步處理,以及復查數據,我們將結果存儲為excel表格:
data={'段落':[],'文件名稱':[],'文件相對路徑':[]} unmatched_data={'文件名稱':[],'文件相對路徑':[]} for p in result: data['段落'].append(p['paragraph']) data['文件名稱'].append(p['fileName']) data['文件相對路徑'].append(p['filePath']) for q in unmatched: unmatched_data['文件名稱'].append(q['fileName']) unmatched_data['文件相對路徑'].append(q['filePath']) df = pd.DataFrame(data) df.to_csv('result.csv', index=True,encoding="utf_8_sig") df = pd.DataFrame(unmatched_data) df.to_csv('noresult.csv', index=True,encoding="utf_8_sig")
通過上述代碼,我們就將匹配到的結果列表result和未匹配到的結果列表unmatched,保存為名為"result.csv"和"noresult.csv"的兩個表格。當然也可以將這兩個數據合并到一個excel表格里。通過沒匹配到的列表中的word文檔查看,進一步修改了正則表達式:
pattern=".*?(?:申請|提起).*?(?:仲裁|申訴)"
以這種方式匹配出來104個,還有13個沒有匹配到,這個時候,再去完善正則意義似乎不太大,畢竟只剩13個,人工匹配一下段落也很快。
result.csv表格內容截圖:
到這一步,我們已經把所有的文書,都提取了我們想要的段落,并進行了保存。
我們下一步,需要提取段落中的爭議重點,這一步并非不是不能通過Python處理,只是難度和前期時間成本非常大,這里我建議暫時通過人工的方式處理。在精選的字段中提取關鍵信息,由于已經給人工處理排除掉了許多無關信息,時間成本尚可接受。
筆者在上述表格的E列增加一個字段“案件焦點”,當然增加到其他列也可以,然后陳律師讓助理在該列依次填入了歸納的焦點。
第四步 數據可視化展現
這里數據可視化,一樣要用到pandas庫來處理csv文件,同時也會利用到pyecharts模塊,
讀取csv文件,做先行處理:
import pandas df=pd.read_csv('result.csv') result={} for index, row in df.iterrows(): key=row[4] if key not in result: result[key]=1 else: result[key]+=1 print('result:',result) --------------------------------------------- result={'支付工資_無需支付工資': 38, '加班工資': 28, '賠償金': 31, '補償金': 1, '補貼': 1,'返還設備':1, '返還私自承接業務的收益_提成':2, '工資差額_加班工資差額':39,'工作墊付款_預付款':3,'工傷認定':2,'經濟損失':2 ,'應休未休年休假折算工資':10,'刑事判決書':7,'押金':1,'一次性工傷、傷殘補助金、醫療費':3}
轉換為pyecharts要求的參數的數據格式:
_list=[] for k in result: p=(k,result[k]) _list.append(p) print(_list) ------------------------------- [('支付工資_無需支付工資', 38), ('加班工資', 28), ('賠償金', 31), ('補償金', 1), ('補貼', 1), ('返還設備', 1), ('返還私自承接業務的收益_提成', 2), ('工資差額_加班工資差額', 39), ('工作墊付款_預付款', 3), ('工傷認定', 2), ('經濟損失', 2), ('應休未休年休假折算工資', 10), ('刑事判決書', 7), ('押金', 1), ('一次性工傷、傷殘補助金、醫療費', 3)]
轉換為圖表
pie = Pie() pie.add("", _list) pie.set_global_opts(title_opts=opts.TitleOpts(title="Pie-爭議點分布"),legend_opts=opts.LegendOpts(is_show = False)) pie.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}")) pie.render("pie.html")
轉換為餅圖:
我們也可以根據需要,轉換為其他的柱狀圖、折線圖等等其他圖表。這里不做更多介紹。
總結
本文涉及的知識點比較多,難點主要在于正則表達式的書寫,需要盡可能多的滿足大部分文檔的要求,否則剩余的文檔越多,手工處理的工作會越多,正則表達式的書寫,需要反復查詢未匹配到的文檔,進行修正。
其他的知識點,還涉及到文件夾文件遍歷和篩選、word文檔處理、excel文檔處理,數據可視化操作等知識點,但總體而言,處理的方式還是中規中矩的,前面的文章也全都介紹過。
另外,我們也發現,Python并不能代替所有工作,爭議點的篩查提取,還是需要人工來處理。不過實際上,通過機器學習等技術,也是完全可以實現自動化的。但是對于普通使用者來說,學習門檻和時間成本都太高,得不償失。得益于前期的段落提取,這一步的工作量相對已經簡單了很多。另外,本文呈現的最終結果,也并不完美,要得到更完美的報告,還需要不少潤色和處理。
從另一個視角來看,本文的方法不僅可以用來做行業的白皮書,也可以用于訴訟領域,將類案查詢結果,利用Python數據處理分析后,轉化為可視化圖表,會得到更好的庭審展示效果。
Python 大數據
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。