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

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

ただいまの
回答率

90.34%

  • Python

    9197questions

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

  • Python 3.x

    7398questions

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

  • CSV

    709questions

    CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

  • Jupyter

    295questions

csvファイルを読み込み、データを処理する時のエラーについて

解決済

回答 1

投稿 編集

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

tenjin

score 216

 前提・実現したいこと

Pythonで単語が1列に書いてあるcsvファイルを読み込み、
各単語間の類似度を計算してその数値を表示するプログラムを書いています。
類似度が一定数以上の組み合わせを出力したいです。

sample.csv

りんご
いぬ
いちご
くま
みかん
ねこ

出力したい結果(数値は仮)

りんご - いちご 0.3
...

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

前回の質問に対するご回答を受けて、
修正したのですが、以下のようなエラーが出てしまい、どのように修正したら良いかわからず困っています。

IndexError                                Traceback (most recent call last)
<ipython-input-15-f5997b50ec24> in <module>()
      4     for j in range(1, len(lines)-1):
      5         w1_word = lines[i]
----> 6         w1_syn = wn.synsets(w1_word, lang='jpn')[0]
      7         w2_word = lines[j]
      8         w2_syn = wn.synsets(w2_syn, lang='jpn')[0]

IndexError: list index out of range

 該当のソースコード

import csv
f = open("sample.csv", encoding='utf-8' )
lines = f.readlines()

#行の長さを確認する
import pandas as pd
import numpy as np
print(len(lines))

dataset1= pd.read_csv('sample.csv', header=None)
dataset1

#1行目からlen(lines)まで比較、2行目からlen(lines)まで比較を繰り返す
from nltk.corpus import wordnet as wn
for i in range(0, len(lines)-2):
    for j in range(1, len(lines)-1):
        w1_word = lines[i]
        w1_syn = wn.synsets(w1_word, lang='jpn')[0]
        w2_word = lines[j]
        w2_syn = wn.synsets(w2_syn, lang='jpn')[0]
        similarity = w1_syn.path_similarity(w2_syn)
        if similarity > 0.3:
            print( lines[i] + '-' + lines[j] + similarity)

 補足情報(FW/ツールのバージョンなど)

Python 3.6.3
Mac OS High Sierra
Jupyter notebook 5.0.

ご回答を受けて試したこと

①csvから読み込んだデータでもできるかどうか試しましたが、以下の結果が出てしまいました、

from nltk.corpus import wordnet as wn
from jaconv import hira2kata
data = open('sample.csv', 'r').readlines()
data_with_syn = []

print(data)

#結果 ['\ufeffりんご\n', 'いぬ\n', 'いちご\n', 'くま\n', 'みかん\n', 'ねこ']

for datum in data:
    ret = wn.synsets(datum, lang='jpn')
    if ret:
        data_with_syn.append((datum, ret[0]))
        continue

    datum = hira2kata(datum)
    ret = wn.synsets(datum, lang='jpn')
    if ret:
        data_with_syn.append((datum, ret[0]))
        continue

    print(f'Unknown word: {datum}.')

print(*data_with_syn, sep='\n')

結果

Unknown word: リンゴ
.
Unknown word: イヌ
.
Unknown word: イチゴ
.
Unknown word: クマ
.
Unknown word: ミカン
.
('ネコ', Synset('cat.n.01'))

②単語を英語にした場合、jaconvは使えないため、エラー処理に困る

from nltk.corpus import wordnet as wn
#from jaconv import hira2kata

data = ['apple', 'dog', "strawberry", 'bear', 'orange', 'cats']
data_with_syn = []

for datum in data:
    ret = wn.synsets(datum, lang='en')
    if ret:
        data_with_syn.append((datum, ret[0]))
        continue

    #datum = hira2kata(datum)
    #ret = wn.synsets(datum, lang='en')
    #if ret:
        #data_with_syn.append((datum, ret[0]))
       # continue

    print(f'Unknown word: {datum}.')

print(*data_with_syn, sep='\n')


エラー文

---------------------------------------------------------------------------
WordNetError                              Traceback (most recent call last)
<ipython-input-29-f740c715a42a> in <module>()
      1 for datum in data:
----> 2     ret = wn.synsets(datum, lang='en')
      3     if ret:
      4         data_with_syn.append((datum, ret[0]))
      5         continue

~/.pyenv/versions/anaconda3-5.0.1/lib/python3.6/site-packages/nltk/corpus/reader/wordnet.py in synsets(self, lemma, pos, lang, check_exceptions)
   1494 
   1495         else:
-> 1496             self._load_lang_data(lang)
   1497             synset_list = []
   1498             for l in self._lang_data[lang][1][lemma]:

~/.pyenv/versions/anaconda3-5.0.1/lib/python3.6/site-packages/nltk/corpus/reader/wordnet.py in _load_lang_data(self, lang)
   1135 
   1136         if lang not in self.langs():
-> 1137             raise WordNetError("Language is not supported.")
   1138 
   1139         f = self._omw_reader.open('{0:}/wn-data-{0:}.tab'.format(lang))

WordNetError: Language is not supported.
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

『リンゴ』は登録されているけれど、『りんご』は未登録のようです。

>>> from nltk.corpus import wordnet as wn
>>> wn.synsets('りんご', lang='jpn')
[]
>>> wn.synsets('リンゴ', lang='jpn')
[Synset('apple.n.01'), Synset('apple.n.02')]

返り値を見て、未登録の場合は別フローに入るべきかと。

data = ['りんご', 'いぬ', 'いちご', 'くま', 'みかん', 'ねこ']
data_with_syn = []

for datum in data:
    ret = wn.synsets(datum, lang='jpn')
    if ret:
        data_with_syn.append((datum, ret[0]))
    else:
        pass

print(data_with_syn)  # [('いぬ', Synset('spy.n.01'))]

『いぬ』しかないですね。

追記

jaconvという良さげなモジュールがあったので、使ってみました。

from nltk.corpus import wordnet as wn
from jaconv import hira2kata

data = ['りんご', 'いぬ', 'いちご', 'くま', 'みかん', 'ねこ']
data_with_syn = []

for datum in data:
    ret = wn.synsets(datum, lang='jpn')
    if ret:
        data_with_syn.append((datum, ret[0]))
        continue

    datum = hira2kata(datum)
    ret = wn.synsets(datum, lang='jpn')
    if ret:
        data_with_syn.append((datum, ret[0]))
        continue

    print(f'Unknown word: {datum}.')

print(*data_with_syn, sep='\n')

標準出力

('リンゴ', Synset('apple.n.01'))
('いぬ', Synset('spy.n.01'))
('イチゴ', Synset('strawberry.n.01'))
('クマ', Synset('bear.n.01'))
('ミカン', Synset('orange.n.01'))
('ネコ', Synset('cat.n.01'))

良い感じですね。

追記2

これ、『政府の犬』とかそっちの方の『いぬ』ですね...

>>> wn.synsets('いぬ', lang='jpn')
[Synset('spy.n.01')]
>>> wn.synsets('spy')
[Synset('spy.n.01'), Synset('spy.n.02'), Synset('descry.v.01'), Synset('spy.v.02'), Synset('spy.v.03'), Synset('spy.v.04')]
>>>
>>> wn.synsets('イヌ', lang='jpn')
[Synset('dog.n.01')]

質問追記を受けて

csvから読み込んだデータでもできるかどうか試しましたが、以下のようにエラーが出てしまいました。

pandasのオブジェクトをそのまま渡しているからですね。
個人的にはpandasどころかcsvもいらないと思います。テキストファイルで良いのでは。

単語を英語にした場合、jaconvは使えないため、エラー処理に困る

str.isalphaを使えば...

>>> 'いぬ'.isalpha()
True
>>> 'dog'.isalpha()
True

えっ?
Qiita - [修正] Python 文字列の英数字判定でハマった

こう書かねばならないようです。

>>> 'いぬ'.encode('utf-8').isalpha()
False
>>> 'dog'.encode('utf-8').isalpha()
True

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/06/18 14:09

    ご回答いただきましてありがとうございます。
    追記2に関して、ひらがなの「いぬ」だと'spy.n.01'となるので、今回の場合は jaconvのhira2kataを使って全部カタカナにした方がよいということになりますでしょうか。

    キャンセル

  • 2018/06/18 14:12

    今回の例に関して言えばそうなりますね。

    キャンセル

  • 2018/06/18 15:22

    お返事ありがとうございます。
    試したことにcsvファイルからデータを読み込む方法について追記しました。
    可能でしたらこちらもアドバイスいただけますと幸いです。
    よろしくお願いいたします。

    キャンセル

  • 2018/06/18 18:31

    ご回答の追記をいただきましてありがとうございます。
    試したこと①に関しまして、テキストファイルで読み込んだところ、1文字ずつ扱われてしまいました。
    別質問をした方が良いでしょうか。

    キャンセル

  • 2018/06/18 18:34

    data = open('sample.csv', 'r').readlines() で読み取れると思いますよ。

    キャンセル

  • 2018/06/18 18:40

    修正しましたが、引きつづき、csvから読み取ろうとするとうまくいかないようです。

    キャンセル

  • 2018/06/18 18:46

    改行文字を消すのを忘れてました。
    data = [line.strip() for line in open('sample.csv', 'r').readlines()] ですかね。

    ---
    先頭の変な文字『\ufeff』は、BOMです。
    csvをBOMなしのutf-8で保存しなおしてください。

    BOMなしで保存する方法はググるといろいろ出てくるはず。

    キャンセル

  • 2018/06/18 18:51 編集

    あるいは読み取り時にBOMを消すのもアリですね。
    data = [line.strip() for line in open(略).readlines()]
    data[0] = data[0].lstrip('\ufeff')

    キャンセル

  • 2018/06/18 19:14

    ありがとうございました。

    キャンセル

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

  • Python

    9197questions

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

  • Python 3.x

    7398questions

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

  • CSV

    709questions

    CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

  • Jupyter

    295questions