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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

666閲覧

音声認識の結果をテキスト化して、マルコフ連鎖の辞書に登録する方法

KOBETA

総合スコア6

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2018/09/01 15:23

編集2018/09/01 15:42

解決したいこと

音声とテキストでの擬似会話のプログラムを作成しています。
具体的には、音声認識で入力したデータをテキスト化して、マルコフ連鎖を使って、形態素解析 → 辞書の作成 → 文章生成。再度、音声認識と繰り返すプログラムを作りたいです。
音声認識の結果をテキスト化して保存するところまではできているようなのですが、形態素解析がうまくいかなくて悩んでおります。
ご教授よろしくお願いいたします。

発生している問題・エラーメッセージ

エラーメッセージ TypeError Traceback (most recent call last) <ipython-input-******> in <module>() 180 tagger = MeCab.Tagger("/Users/****/mecab-ipadic-neologd") 181 tagger.parse("") --> 182 node = tagger.parseToNode(text) 183 184 # 形態素解析の結果から、単語と品詞情報を抽出 ~/.pyenv/versions/anaconda3-5.0.0/envs/py35/lib/python3.5/site-packages/MeCab.py in parseToNode(self, *args) 280 __repr__ = _swig_repr 281 def parse(self, *args): return _MeCab.Tagger_parse(self, *args) --> 282 def parseToNode(self, *args): return _MeCab.Tagger_parseToNode(self, *args) 283 def parseNBest(self, *args): return _MeCab.Tagger_parseNBest(self, *args) 284 def parseNBestInit(self, *args): return _MeCab.Tagger_parseNBestInit(self, *args) TypeError: in method 'Tagger_parseToNode', argument 2 of type 'char const *'

該当のソースコード

python

1#coding:utf8 2import base64 3from googleapiclient import discovery 4import httplib2 5 6import pyaudio #録音機能を使うためのライブラリ 7import wave #wavファイルを扱うためのライブラリ 8 9#APIキーを設定 10key = "*******" 11 12#音声を保存するファイル名 13WAVE_OUTPUT_FILENAME = "sample10.wav" 14 15#録音に関する基本情報 16RECORD_SECONDS = 4 #録音する時間の長さ(秒) 17iDeviceIndex = 0 #録音デバイスのインデックス番号 18 19#APIのURL情報 20DISCOVERY_URL = ('https://{api}.googleapis.com/$discovery/rest?' 21 'version={apiVersion}') 22 23def record(): 24 #基本情報の設定 25 FORMAT = pyaudio.paInt16 #音声のフォーマット 26 CHANNELS = 1 #モノラル 27 RATE = 44100 #サンプルレート 28 CHUNK = 2**11 #データ点数 29 audio = pyaudio.PyAudio() 30 31 stream = audio.open(format=FORMAT, channels=CHANNELS, 32 rate=RATE, input=True, 33 input_device_index = iDeviceIndex, #録音デバイスのインデックス番号 34 frames_per_buffer=CHUNK) 35 36 #--------------録音開始--------------- 37 38 print ("recording...") 39 frames = [] 40 for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)): 41 data = stream.read(CHUNK) 42 frames.append(data) 43 44 45 print ("finished recording") 46 47 #--------------録音終了--------------- 48 49 stream.stop_stream() 50 stream.close() 51 audio.terminate() 52 53 waveFile = wave.open(WAVE_OUTPUT_FILENAME, 'wb') 54 waveFile.setnchannels(CHANNELS) 55 waveFile.setsampwidth(audio.get_sample_size(FORMAT)) 56 waveFile.setframerate(RATE) 57 waveFile.writeframes(b''.join(frames)) 58 waveFile.close() 59 60 61 62#APIの情報を返す関数 63def get_speech_service(): 64 http = httplib2.Http() 65 return discovery.build( 66 'speech', 'v1', http=http, discoveryServiceUrl=DISCOVERY_URL, developerKey=key) 67 68def SpeechAPI(): 69 #音声ファイルを開く 70 with open(WAVE_OUTPUT_FILENAME, 'rb') as speech: 71 speech_content = base64.b64encode(speech.read()) 72 73 #APIの情報を取得して、音声認識を行う 74 service = get_speech_service() 75 service_request = service.speech().recognize( 76 body={ 77 'config': { 78 'encoding': 'LINEAR16', 79 'sampleRateHertz': 44100, 80 'languageCode': 'ja-JP', #日本語に設定 81 'enableWordTimeOffsets': 'false', 82 }, 83 'audio': { 84 'content': speech_content.decode('UTF-8') 85 } 86 }) 87 88 #SpeechAPIによる認識結果を保存 89 response = service_request.execute() 90 91 #見やすいようにコンソール画面で出力 92 for i in response["results"]: 93 print(i["alternatives"][0]["transcript"]) 94 test_file = open('test.text','w') 95 test_file.write(str(i)) 96 97import MeCab 98import os,json,random 99 100dict_file = "markov_dict.json" 101dic = {} 102 103# 辞書への登録 104def regist_dic(wordlist): 105 global dic 106 w1 = "" 107 w2 = "" 108 109 # 要素が3未満の場合は、何もしない 110 if len(wordlist) < 3 : return 111 112 for w in wordlist : 113 word = w[0] 114 if word == "" or word == "\r\n" or word == "\n" : continue 115 # 辞書に単語を設定 116 if w1 and w2 : 117 set_dic(dic,w1, w2, word) 118 # 文末を表す語のの場合、連鎖をクリアする 119 if word == "の" or word == "か" or word == "よ" : 120 w1 = "" 121 w2 = "" 122 continue 123 # 次の前後関係を登録するために、単語をスライド 124 w1, w2 = w2, word 125 126 # 辞書を保存 127 json.dump(dic, open(dict_file,"w", encoding="utf-8")) 128 129# 辞書に単語を設定 130def set_dic(dic, w1, w2, w3): 131 # 新しい単語の場合は、新しい辞書オブジェクトを作成 132 if w1 not in dic : dic[w1] = {} 133 if w2 not in dic[w1] : dic[w1][w2] = {} 134 if w3 not in dic[w1][w2]: dic[w1][w2][w3] = 0 135 # 単語の出現数をインクリメントする 136 dic[w1][w2][w3] += 1 137 138# 応答文の作成 139def make_response(word): 140 res = [] 141 142 # 「名詞」/「形容詞」/「動詞」は、文章の意図を示していることが多いと想定し、始点の単語とする。 143 w1 = word 144 res.append(w1) 145 w2 = word_choice(dic[w1]) 146 res.append(w2) 147 while True: 148 # w1,w2の組み合わせから予想される、単語を選択 149 if w1 in dic and w2 in dic[w1] : w3 = word_choice(dic[w1][w2]) 150 else : w3 = "" 151 res.append(w3) 152 # 文末を表す語の場合、作文を終了 153 if w3 == "。" or w3 == "?" or w3 == "?" or w3 == "" : break 154 # 次の単語を選択するために、単語をスライド 155 w1, w2 = w2, w3 156 return "".join(res) 157 158def word_choice(candidate): 159 keys = candidate.keys() 160 return random.choice(list(keys)) 161 162# メイン処理 163 164# 辞書がすでに存在する場合は、最初に読み込む 165if os.path.exists(dict_file): 166 dic = json.load(open(dict_file,"r")) 167 168while True: 169 record() 170 SpeechAPI() 171 # test.textから入力を受け付け、「さようなら」が入力されるまで続ける 172 text_file = open('test.text','r') 173 text = text_file 174 if text == "" or text == "さようなら" : 175 print("A -> さようなら") 176 break 177 178 179 # 形態素解析 180 tagger = MeCab.Tagger("/Users/******/mecab-ipadic-neologd") 181 tagger.parse("") 182 node = tagger.parseToNode(text) 183 184 # 形態素解析の結果から、単語と品詞情報を抽出 185 wordlist = [] 186 while node is not None: 187 hinshi = node.feature.split(",")[0] 188 if hinshi not in ["BOS/EOS"]: 189 wordlist.append([node.surface,hinshi]) 190 node = node.next 191 192 # マルコフ連鎖の辞書に登録 193 regist_dic(wordlist) 194 195 # 応答文の作成 196 for w in wordlist: 197 word = w[0] 198 hinshi = w[1] 199 # 品詞が「感動詞」の場合は、単語をそのまま返す 200 if hinshi in [ "感動詞"] : 201 print("A -> 何に"+word) 202 break 203 # 品詞が「名詞」「形容詞」「動詞」の場合で、かつ、辞書に単語が存在する場合は、作文して返す 204 elif (hinshi in [ "名詞" ,"形容詞","動詞"]) and (word in dic): 205 print("A -> " + make_response(word)) 206 break

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

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

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

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

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

guest

回答1

0

Python

標準入力から入力を受け付け、「さようなら」が入力されるまで続ける

text_file = open('test.text','r')
text = text_file
if text == "" or text == "さようなら" :
print("A -> さようなら")
break

とても『標準入力から入力を受け付け』ているようには見えません。

投稿2018/09/01 15:26

LouiS0616

総合スコア35660

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

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

KOBETA

2018/09/01 15:44 編集

失礼しました。 #test.textから入力を受け付け、「さようなら」が入力されるまで続ける です。標準入力ではなく、test.textに保存された音声認識の結果から入力したいと考えています。
LouiS0616

2018/09/01 15:56

text_fileは文字列ではなくファイルオブジェクトですから、 text = text_file.read().strip() とかする必要がありますね。
KOBETA

2018/09/02 13:30

ご回答ありがとうございます。なんとか動かすことができましたが、 以下のように、返答の文章作成部分に”alternatives”"transcript"が毎回表示されます。 A -> {'alternatives':[{'transcript':'この後に作成した文章が続く・・・ 毎回ではないのですが、2回に1回程度の頻度で文章の最後に ','confidence':0.9326681}]} とSpeechAPIの認識結果の正確さの数値が表示されます。 文章以外表示されないようにしたいのですが、何が原因なのでしょうか。 ご教授よろしくお願いします。
LouiS0616

2018/09/02 14:18

make_responseに想定どおりの型の変数が渡っているか調べた方が良いですね。
KOBETA

2018/09/02 15:24

make_responseには、<class 'function'>が渡っているようです。 make_responseを文字列型に make_responseの定義の後にstr(make_response)を書き加えて変換しても 返答の文章作成部分には、 {'alternatives':[{'transcript':' が表示されたままになります。 text_fileファイルを確認したところ、書き込まれている段階で {'alternatives': [{'transcript': 'ここに音声認識結果のテキストが入る', 'confidence': 0.86364347}]} と文章以外の余分な情報が入ってしまっているようです。
LouiS0616

2018/09/02 15:41

もともとがjson形式で書き込まれる仕様なのでは?
KOBETA

2018/09/06 13:44

Speech APIはjson形式で書き込まれているようです。 辞書型の'transcript'に対応する文字列部分(音声認識結果)を test_file = [d.get('transcript') for d in i] を使って取り出そうとしましたが、AttributeError: 'str' object has no attribute 'get'とエラーが出ました。 iの型を調べると辞書型なのですが・・・。
LouiS0616

2018/09/06 13:53 編集

辞書型の変数を単純に巡回すると、キーのリストが渡されますので。 import json with open('test.text') as fin: __read_dict = json.load(fin) text = read_dict['alternatives'][0]['transcript'] こんなふうに読み取れるんじゃないですかね。 註:空白をアンダースコアで代替しています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問