はじめに
Amazonで欲しいものを探しまわっていたら、最近は怪しい商品の日本語説明文のレベルアップがしてきたなと感じまして、日本語難しいのに勉強熱心だなと感心していました。そこで日本語を弱らせるプログラムをつくろうと思いました。
使ったもの
使ったものは以下です。
- python 3.6.8
- Mecab 0.996
- mecab-ipadic-2.7.0-20070801.tar.gz: Mecabの辞書
- wnjpn.db.gz: WordNetのデータベース
問題設定
外国の方が間違いそうなまたは微妙なニュアンスの違いを判断できなそうな日本語のパターンを以下のように設定してみました。
- 助詞を間違える
- 過去形にすべき箇所を現在形で書いてしまう
- 単語を別の同音類義語で書いてしまう
1. 助詞を間違える
私 **が** 3ヶ月に一回記事を書きます。/今日も面白そうな記事がトレンド **で** 並んでいます。/JavaScript **から** Pythonの方が個人的に好きです。どれも違和感ありますよね。
ここでは助詞の間違いや選択ミスが発生する条件は以下のようにしました。
・ 一つ前の単語の品詞が"名詞"の場合のみ適用
・ 間違いのパターンは、以下とする。
"が" <=> "は" "で" <=> "に" "から" <=> "より"
コードはこんな感じ。
def mistake_ppp(ppp):
substitute_ppp = ppp
mistake_set = np.array([["が", "は"],["で", "に"]["から", "より"]])
target_pattern = mistake_set[np.any(mistake_set == ppp, axis = 1)]
if len(target_pattern) > 0:
the_other = target_pattern[np.where(target_pattern != ppp)]
substitute_ppp = the_other[0]
return substitute_ppp
2. 過去形にすべき箇所を現在形で書いてしまう
英語で長文を書いていると後半の方で時制の一致をし忘れたりすることがあって、それと同じ感じだと思ってます。
このミスが発生する条件と処理内容は以下のようにしました。
・ 助動詞 "た" が出現した場合、その前の単語を現在形に置換する
コード(抜粋)はこんな感じ。
elif pos == "助動詞" and word == "た":
# 前の単語を現在形に置換する
word_list[word_idx - 1] = basic_list[word_idx - 1]
xfmd_basic = basic
xfmd_word = ""
元の単語のリスト(word_list)とその標準形のリスト(basic_list)を保存しておいてる感じです。あとは、助動詞 "た" を空文字に置き換えることで取り除いてます。
3. 単語を別の同音類義語でかいてしまう
面白そうな記事を **捜す**。/ストーブをつけたので部屋が **温かい**。/記事に対する質問に **解答する**。この間違い処理の発生条件は以下としました。
・ 変換対象は、動詞・形容詞・名詞のみとする。
・ 動詞 "する" は変換しない。
・ 同音類義語とは、品詞および基本形が元と同じものを指すものとし、かつ日本語のみとする。
また、具体的な処理は以下の通りです。
- WordNetを用いて、対象の単語の類義語リストを取得する
- 類義語リストの中から同音類義語を選択する
- 活用形を元の単語と同じものに変換し、もとの単語と置き換える
WordNetはこちらの Japanese Wordnet and English WordNet in an sqlite3 database をダウンロードして使いました。
2のコードはこんな感じです。
def choose_synonym(word):
synonym = word
pos, basic = analyze_pos(word)
synonyms = search_synonyms(word)
idxs = np.arange(0, len(synonyms), 1)
np.random.shuffle(idxs)
for idx in idxs:
synonym_pos, synonym_basic = analyze_pos(synonyms[idx])
if synonym_pos == pos and synonym_basic == basic:
synonym = synonyms[idx]
break
return synonym
1をおこなうsearch_synonyms(word)
の処理内容とコードは、ここに書くと長くなりそうなのでWordNetの構造と類義語検索に書きました。詳細はそちらを参照ください。
3では、Mecabの標準機能では実現できなかったので、Mecabで使われている辞書データ(mecab-ipadic-2.7.0-20070801.tar.gz)に含まれている各品詞ごとの活用形データを用いてみました。
def transform(pos, basic, conjugate):
target_word = None
dict_file = None
if pos == "動詞":
dict_file = "Verb"
elif pos == "形容詞":
dict_file = "Adj"
elif pos == "名詞":
dict_file = "Noun"
with open("../dict/pos/" + dict_file + ".csv", "rb") as f:
words = f.readlines()
for w in words:
winfo = w.decode('euc_jp',errors ='ignore').split(",")
conj = winfo[9]
basicform = winfo[10]
if basicform == basic and conj == conjugate:
target_word = winfo[0]
break
return target_word
csvの読取時の文字コード問題に少し悩まされました。まだまだ発展途上です(elseないけどそこにはいかないのでみなかったことに)
まとめ
処理の流れを整理すると以下の通りです。サブ処理の名称は短縮しちゃっていますが対応はわかるかと。
試してみる
最近購入したAirPods Proの説明文(Amazon)に適用しました。
\begin{align*}
&{\Large 雑音を音に消します。}\\
&{\small 耳の外側と内側のノイズをマイクロフォンは検知。その音と釣合うアンチノイズ機能は、あなたは聴く前でノイズを消し去ります。}\\
\\
&{\Large 訊きたい物だけ、訊こう。}\\
&{\small 周囲の容子を聴いて対応したいときが、外部音取込みモードで切換えましょう。感圧センサーを長押しするだけです。}\\
\\
&{\Large 装着感をカスタマイズ。}\\
&{\small 快適で装着できるシリコーン製イヤーチップを3つのサイズに用意。イヤーチップの通気穴はイヤーバッドの両側の圧力を均一でします。}\\
\\
&{\Large 初めて耳でする体験を。}\\
&{\small 専用のスピーカードライバ、ハイダイナミックレンジアンプ、H1チップは連繋。コンパクトなボディよりは想像もできないような上質なサウンドを生みだします。}\\
\\
&{\Large 設定も、Siriも。全てはシンプル。}\\
&{\small iPhoneとの接続がとても簡単。2組みのAirPodsに曲を共有する事も、届くメッセージをSiriで読み上げさせる事もできます。}\\
\\
&{\Large 充電がワイヤレス。愉しさがエンドレス。}\\
&{\small Wireless ChargingCaseを遣えば、AirPodsProと一緒でどこへでも出掛けられます。Qi規格の充電器で対応しています。}
\end{align*}
若干のあやしさが出ました。これだったら買わなかったかも。
さいごに
このプログラム自体が役に立ちませんが、弱い日本語の特徴を攫む事が今後の日本語教育で有用ではと想います。日本語を勉強中の外国ヒトたちは書く日本語の文章の傾向を学習しクラスタリングする事に間違え易い日本語のパターンは明らかで成って、そのそれぞれである日本語教育カリキュラムは作れたりしそうですね。