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

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

ただいまの
回答率

88.63%

mecab解析の後, 欲しい品詞のみの抽出

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 858

rrrrrrrry

score 20

 前提・実現したいこと

N-gram解析をすることには成功したのですが, その中からさらに自立語のみを抽出したいと考え, コードを書いたところ以下のようなエラーが出ました. wordsをどのように定義したらいいのでしょうか?

もしくは, これよりも効率の良い方法はありますでしょうか?

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

Traceback (most recent call last):
  File "ngram.py", line 72, in <module>
    main()
  File "ngram.py", line 61, in main
    bow = text2bow(argvs[2],mod="file")
  File "ngram.py", line 26, in text2bow
    words = words.replace('\n', '')
UnboundLocalError: local variable 'words' referenced before assignment

 該当のソースコード

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Qiita: Pythonで単語N-gramを生成するモジュール <https://qiita.com/takumi_TKHS/items/942492b72aaf7b6a6213>

import sys
import subprocess as cmd

# テキスト -> 単語(形態素)集合
def text2bow(obj,mod):

    # input: ファイルの場合はmod="file", input: 文字列の場合はmod="str"
    if mod == "file":
        morp = cmd.getstatusoutput("cat " + obj + " | mecab -Owakati")
    elif mod == "str":
        morp = cmd.getstatusoutput("echo " + obj.encode('utf-8') + " | mecab -Owakati")
    else:
        print("error!!")
        sys.exit(0)

    morp = list(morp)

    key = ('名詞', '動詞', '形容詞', '形容動詞')
    global words

    if morp[1] in key:
        words = morp[0]

    words = words.replace('\n', '')

    bow = words.split(' ')

    return bow

# N-gramの生成
def gen_Ngram(words,N):

    ngram = []

    for i in range(len(words)):
        cw = ""

        if i >= N-1:
            for j in reversed(list(range(N))):
                cw += words[i-j]
        else:
            continue

        ngram.append(cw)

    return ngram

# 出力
def output_Ngram(ngram):

    for i in range(len(ngram)):
        print(ngram[i])

def main():

    argvs = sys.argv

    # input: ファイルの場合
    bow = text2bow(argvs[2],mod="file")

    # input: 文字列の場合
    #bow = text2bow(obj=u"これはN-gramを生成するプログラムです.",mod="str")

    ngram = gen_Ngram(bow,int(argvs[1]))

    output_Ngram(ngram)

if __name__ == "__main__":

    main()

 試したこと

global words
というように定義しているところは, それを入れないとlocal扱いされてしまうエラーが出たからです.

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

-Owakatiオプションは分かち書きのフォーマットで出力するというオプションなので、そもそも品詞を扱えません。

参考にしているqiitaのプログラムをそのまま適用するのは無理ですし、やるとしたら書き直しに近いことが必要になるので、どのみち書き直した方が良いです。

公式のpythonバインディングをインストールして使うのがおすすめです。解説記事は幾らでも転がっていると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/26 13:00

    out of rangeになるようなものがmorpに入るようなケースがあるのでしょう。どういうケースでそうなるのかはわからないので実際に確認してみてください

    キャンセル

  • 2018/10/26 13:01

    コメントが編集されたので訂正。もともと、more[1] in keyがTrueにならなければwordsに何も入らないコードですよね。なのでelse節でその場合の処理を何かしら書いてあげてください

    キャンセル

  • 2018/10/26 13:04

    あと、私の回答は最初から「公式バインディングでも使って書き直した方が良い」です。コメントが来たのでなんとなく返信しましたが、あくまでも元のコードを大事に修正していきたいというのであればこの先はご自身でどうぞ。私はフォローできません

    キャンセル

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

  • ただいまの回答率 88.63%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る