質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

1回答

2877閲覧

janomeによる形態素解析で、簡略辞書が結果に反映されません。

SKIYO

総合スコア15

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2018/07/19 16:33

編集2018/07/19 16:36

janomeで形態素解析を行っています。

utf-8対応の文章に対して、
utf-8の簡略辞書(csvファイル)を同コード内で作成し、それを形態素解析に反映させたいのですが、
なぜか上手くいきません。
(実行時にエラーが出るわけではなく、t = Tokenizer() と同じ結果しか得られない。)

どうすれば簡略辞書が反映されるのか、ご教授いただけたら幸甚です。

バージョン
Python 3.6.5
Janome 0.3.6
pandas 0.23.1

以下、コードです。
(なお、プライバシーに関係しそうな箇所を---にしています。)

Python

1import pandas as pd 2import codecs as cd 3import numpy as np 4import math 5import re 6import xlrd 7import xlsxwriter 8from collections import Counter 9from itertools import chain 10from janome.tokenizer import Tokenizer 11import os 12import csv 13 14 15 16with cd.open(r"\---\---.csv", "r", "utf-8") as file: 17 df = pd.read_csv(file, index_col=0) 18 19## 行drop 20df.dropna(how='any', inplace=True) 21#how='any':一つでもNaN(Not a Number)がある行/列(,axis=1)をdrop なお、how='all'は全てがNaNをdrop 22#inplace=True:元のdfが変更される。 23 24## 昇順ソート 25df.sort_index(inplace=True) #axis=1:列方向にソート ascending=False:降順でソート by='列名':その列内の値がソート基準になる 26 27## Create User dictionary in UTF-8 28#http://akiyoko.hatenablog.jp/entry/2017/12/09/010411 29def main(): 30 rows = [['展示会', 'カスタム名詞', 'テンジカイ'], ['中国市場', 'カスタム名詞', 'チュウゴクシジョウ'], ['可能性', 'カスタム名詞', 'カノウセイ']] 31 with open('dict_simple_utf8.csv', 'w', newline='', encoding='utf-8-sig') as f: 32 w = csv.writer(f, quoting=csv.QUOTE_ALL) 33 w.writerows(rows) 34 35if __name__ == '__main__': 36 main() 37 38 39## User dictionary 40t = Tokenizer(r"dict_simple_utf8.csv", udic_type="simpledic", udic_enc="utf8")#Tokenizer初期化 41 42data = [] 43each_data = [] 44c = 0 45for i in range(len(df.index)): 46 value = df.iat[i, 0] #.iat[行番号, 列番号] なお、.at['行ラベル', '列ラベル']も可能 47 tokens = t.tokenize(value) 48 for token in tokens: 49 partOfSpeech = token.part_of_speech.split(',')[0] #.part_of_speech.split(',')[0]:品詞 50 #なお、[1]~[3]は品詞細分類1~3 51 #その他、.infl_type:活用型、.infl_form:活用形、.base_form:原形、.reading:読み、.phonetic:発音 52 if partOfSpeech == u'名詞': #名詞を抽出する 53 each_data.append(token.surface) #.surface:表層形(tokenそのもの) 54 data.append(each_data) 55 each_data = [] 56 c += 1 57 if c == 2: 58 break 59 60##エクセル作成 61#ファイル作成 62output_Exl = xlsxwriter.Workbook(r"result_pd\morphology.xlsx") 63#シート作成 64output_sht = output_Exl.add_worksheet('tokens') 65 66 67for row in range(len(data)): 68 for i in range(len(data[row])): 69 output_sht.write(row, i, data[row][i]) # (行, 列, 追加するデータ) 70 71 72##data(リストのリスト)内のすべてのtokensを同じリストに格納 73#print(chain.from_iterable(data)) #<itertools.chain object at 0x000001B42F87D748> 74chain_data = list(chain.from_iterable(data)) #chain(.from_iterable)():iterableなオブジェクトを一つのオブジェクトにまとめる 75#http://coolpythontips.blogspot.com/2016/02/itertoolschain.html 76 77c = Counter(chain_data) #Counterは、keyに要素、valueに出現回数の、辞書型のサブクラス 78result_ranking = c.most_common(100) #(要素, 出現回数)という形のタプルを出現回数が多い順に並べたリストを返す。引数にnを入力すると、上位n位までを対象にする。 79#https://note.nkmk.me/python-collections-counter/ 80 81ranking = output_Exl.add_worksheet('count') 82for row in range(len(result_ranking)): 83 for i in range(len(result_ranking[row])): 84 ranking.write(row, i, result_ranking[row][i]) 85 86output_Exl.close() #エクセル保存 87

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

簡略辞書フォーマット (v0.2.7 以上)を参考に

Python

1# -*- coding: utf-8 -*- 2from janome.tokenizer import Tokenizer 3import csv 4 5 6def main(): 7 rows = [['展示会', 'カスタム名詞', 'テンジカイ'], ['中国市場', 'カスタム名詞', 'チュウゴクシジョウ'], ['可能性', 'カスタム名詞', 'カノウセイ']] 8 with open('dict_simple_utf8.csv', 'w', newline='', encoding='utf-8-sig') as f: 9 # quoting=csv.QUOTE_ALLを削除 10 w = csv.writer(f) 11 w.writerows(rows) 12 13if __name__ == '__main__': 14 main() 15 16# udic_encをutf-8-sigに 17t = Tokenizer(r"dict_simple_utf8.csv", udic_type="simpledic", udic_enc="utf-8-sig") 18tokens = t.tokenize('展示会') 19for token in tokens: 20 print(token)

○出力結果

展示会 カスタム名詞,*,*,*,*,*,展示会,テンジカイ,テンジカイ

◇参考情報
tests#user_simpledic.csv

あと適度に関数分割されることをお勧め致します。


「udic_encをutf-8-sigに」したのは、簡略辞書のdict_simple_utf8.csvと、encodingを一緒にしなくてはならなかったからでしょうか。

はい、そうです。

関数化に関して

関数の分け方は一つの纏まり「入力→加工→出力」この形を一つとして分けると良いです。

質問文のコードが行っていることは、
0. pandasを使って、csvの内容を読み取り。
0. janome用のカスタム辞書を作成。
0. 1で読み取った内容に対して、janomeで形態解析。
0. エクセル作成

この4つの処理です。以下は書き換えたソースコードです、ご参考まで。

Python

1# -*- coding: utf-8 -*- 2import pandas as pd 3import numpy as np 4import math 5import re 6import xlrd 7import xlsxwriter 8from collections import Counter 9from itertools import chain 10from janome.tokenizer import Tokenizer 11import os 12import csv 13 14 15def create_user_dic_file(file_name: str='dict_simple_utf8.csv', encoding: str='utf-8-sig'): 16 """ 17 janomeのカスタム辞書を作成 18 :param file_name 出力辞書ファイル名 csv形式 19 :param encoding ファイルのエンコーディング形式 20 ## Create User dictionary in UTF-8 21 # http://akiyoko.hatenablog.jp/entry/2017/12/09/010411 22 """ 23 rows = [['展示会', 'カスタム名詞', 'テンジカイ'], ['中国市場', 'カスタム名詞', 'チュウゴクシジョウ'], ['可能性', 'カスタム名詞', 'カノウセイ']] 24 with open(file_name, 'w', newline='', encoding=encoding) as f: 25 w = csv.writer(f) 26 w.writerows(rows) 27 28 29def read_data(file_name: str, encoding: str='utf-8'): 30 """ 31 :param file_name 入力ファイル csv形式 32 :param encoding ファイルのエンコーディング形式 33 """ 34 # ※ openはencodingオプションでエンコード指定を行えるためcodecsを使用しないように変更 35 with open(file_name, "r", encoding=encoding) as file: 36 df = pd.read_csv(file, index_col=0) 37 38 ## 行drop 39 df.dropna(how='any', inplace=True) 40 # how='any':一つでもNaN(Not a Number)がある行/列(,axis=1)をdrop なお、how='all'は全てがNaNをdrop 41 # inplace=True:元のdfが変更される。 42 43 ## 昇順ソート 44 df.sort_index(inplace=True) # axis=1:列方向にソート ascending=False:降順でソート by='列名':その列内の値がソート基準になる 45 46 for i in range(len(df.index)): 47 # ※ yieldを使う 48 yield df.iat[i, 0] # .iat[行番号, 列番号] なお、.at['行ラベル', '列ラベル']も可能 49 50 51def parse(file_name: str): 52 """ 53 :param file_name 入力ファイル csv形式 54 """ 55 ## User dictionary 56 t = Tokenizer(r"dict_simple_utf8.csv", udic_type="simpledic", udic_enc="utf-8-sig") # Tokenizer初期化 57 data = [] 58 each_data = [] 59 c = 0 60 for value in read_data(file_name): 61 for token in t.tokenize(value): 62 partOfSpeech = token.part_of_speech.split(',')[0] # .part_of_speech.split(',')[0]:品詞 63 # なお、[1]~[3]は品詞細分類1~3 64 # その他、.infl_type:活用型、.infl_form:活用形、.base_form:原形、.reading:読み、.phonetic:発音 65 if partOfSpeech == u'名詞': # 名詞を抽出する 66 each_data.append(token.surface) # .surface:表層形(tokenそのもの) 67 data.append(each_data) 68 each_data = [] 69 c += 1 70 if c == 2: 71 break 72 return data 73 74 75def create_excel(file_name: str, data=None): 76 """ 77 エクセル作成 78 :param file_name 出力ファイル名 79 :data 80 """ 81 from contextlib import closing 82 # ※ contextlib#closingを使用 83 # ファイル作成 84 with closing(xlsxwriter.Workbook(file_name)) as output_Exl: 85 # シート作成 86 output_sht = output_Exl.add_worksheet('tokens') 87 88 for row in range(len(data)): 89 for i in range(len(data[row])): 90 output_sht.write(row, i, data[row][i]) # (行, 列, 追加するデータ) 91 92 ##data(リストのリスト)内のすべてのtokensを同じリストに格納 93 # print(chain.from_iterable(data)) #<itertools.chain object at 0x000001B42F87D748> 94 chain_data = list(chain.from_iterable(data)) # chain(.from_iterable)():iterableなオブジェクトを一つのオブジェクトにまとめる 95 # http://coolpythontips.blogspot.com/2016/02/itertoolschain.html 96 97 c = Counter(chain_data) # Counterは、keyに要素、valueに出現回数の、辞書型のサブクラス 98 result_ranking = c.most_common(100) # (要素, 出現回数)という形のタプルを出現回数が多い順に並べたリストを返す。引数にnを入力すると、上位n位までを対象にする。 99 # https://note.nkmk.me/python-collections-counter/ 100 101 ranking = output_Exl.add_worksheet('count') 102 for row in range(len(result_ranking)): 103 for i in range(len(result_ranking[row])): 104 ranking.write(row, i, result_ranking[row][i]) 105 106 107def parse_args(): 108 """ 109 コマンドライン引数の解析 110 """ 111 input_file = r"./input_csv.csv" 112 from argparse import ArgumentParser 113 parser = ArgumentParser() 114 parser.add_argument('input_file', metavar=None, nargs='?', default=input_file) 115 116 return parser.parse_args() 117 118 119def main(): 120 args = parse_args() 121 create_user_dic_file() 122 data = parse(args.input_file) 123 create_excel(r"result_pd\morphology.xlsx", data) 124 125 126if __name__ == '__main__': 127 main() 128

投稿2018/07/19 17:01

編集2018/07/19 20:20
umyu

総合スコア5846

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SKIYO

2018/07/19 17:31

回答ありがとうございます。 無事に、簡略辞書を反映させることができました。 なお、 ①なぜ「quoting=csv.QUOTE_ALLを削除」したのかは、自分で調べるとして、 ②「udic_encをutf-8-sigに」したのは、簡略辞書のdict_simple_utf8.csvと、encodingを一緒にしなくてはならなかったからでしょうか。 また、 ③「適度に関数化」するとは、たとえば私のコーディングに対して、umyuさんのような上級の方たちは、主にどこを、どのように関数化するのでしょうか。 周りにPythonを習熟している者がおらず、上級プログラマーの方たちの一般的な動作がわかりません。。 なお、最後の③の質問は、元々の質問から逸れますので、もしお時間があれば回答いただければと思います。
SKIYO

2018/07/20 00:35

ありがとうございました。 とても参考に、そして勉強になります! これから、書き換えてくださったソースコードをきちんと理解してみます。 その際、質問等あると思いますので、このページで改めて質問させてください。。そして、もし可能でしたら、ごく簡単で構いませんので、ご回答いただけたら幸いです。。 ひとまず、この度は本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問