テキストファイルから特定の文字列を除去した後,形態素解析によりストップワードを含まない2文字以上の名詞の単語を抽出し.それらのtf-idfを表示,あるいはtf-idfの値が大きい順に単語を並べ替えようと考えています.
(Tf-idfVectorizerを使わないものとします)
Tf-idfを表示するにあたり,辞書型で各単語のtf, df, idfを表示させるようにしました.
最終的にtfとidfの積を算出する為に,辞書入りのリストに格納した単語毎のtf値を出そうとした際,以下の写真のようになりました.
この件に関しまして,解決策がご存知の方に是非ご教示頂きたいです.
宜しくお願いします.
写真
テキスト
protein.txt
1全ゲノム配列決定が容易になった結果,多くの新規遺伝子(タンパク質)の存在や機能を配列情報から予測することはかなり容易になった. 2とはいえ,どの生物種でも全遺伝子の1/3~1/2はその配列からだけでは機能を予測できない「機能未知タンパク質」をコードしている. 3生命現象の全体像を分子レベルから理解するためには,それら機能未知タンパク質の機能の解明も必要である. 4又,タンパク質配列のうち全くもって未知なものもあれば,多くの種で保存されている既知の機能部位を持つものもある. 5更に,タンパク質が持つ活性(分子機能)と細胞における働き(細胞内機能)は往々にして別の文脈で語られることが多く,これらを実験的に検証する系は未だ存在しない. 6本研究では,モデル生物である出芽酵母を用いて,関心のある機能未知タンパク質の機能部位の同定と機能解析をランダム変異導入法を用いて,安価かつ簡素に行う系を確立することを目的とする.
エラー
Traceback (most recent call last): File "renshu3.py", line 89, in <module> tf_val = [num.get(doc) for num in tfs] #単語毎にtfの数字を取り出したい(問題の箇所) File "renshu3.py", line 89, in <listcomp> tf_val = [num.get(doc) for num in tfs] #単語毎にtfの数字を取り出したい(問題の箇所) TypeError: unhashable type: 'numpy.ndarray'
コード
renshu.py
1#!/usr/bin/python 2# -*- coding: utf-8 -*- 3import redis 4import MeCab 5import codecs 6import re 7import numpy as np 8 9with codecs.open("protein.txt", "r", "utf-8") as f: 10 corpus = f.read() 11N = sum(1 for line in open("protein.txt"))#総文書数 12 13mecab = MeCab.Tagger('-d /usr/local/lib/mecab/dic/mecab-ipadic-neologd') 14mecab.parse('') 15m = mecab.parseToNode(corpus) 16 17#除外したい単語リスト 18rm_list = ["RT","https","co","さん","フォロー","本日","応募","今日","プレゼント","お金","FGO","無料","本人","投稿","動画","ツイート","リツイート","Twitter","ローソン","Peing","http","Amazonギフト券","bot","発売中","Youtube","www","WWW","質問箱","コラボ","フォロワー","DM","いいね","RT","lawson","://","!","peing","youtube","抽選","jp","リプ","キャンペーン","チケット","期間限定","DHC","日本","amp","人間","チャンネル","配信中","YouTube","WEB","楽しみ","イラスト","くじ","@","__"] 19 20#ストップワード 21stop_words = [] 22path = 'stop_words.txt' 23with open(path) as g: 24 stop_words = g.readlines() 25 26#url, 返信, RT, 絵文字の除去 27corpus = re.sub(r"http\S+", "", corpus) 28corpus = re.sub(r"@(\w+) ", "", corpus) 29corpus = re.sub(r"(^RT.*)", "", corpus, flags=re.MULTILINE | re.DOTALL) 30emoji_pattern = re.compile("[" 31u"\U0001F600-\U0001F64F" 32u"\U0001F300-\U0001F5FF" 33u"\U0001F680-\U0001F6FF" 34u"\U0001F1E0-\U0001F1FF" 35"]+", flags=re.UNICODE) 36corpus = emoji_pattern.sub("", corpus) 37 38keywords = [] 39#単語のスクリーニング 40while m: 41 if m.feature.split(',')[0] == '名詞': 42 if m.surface not in rm_list: 43 if len(m.surface) >= 2: 44 keywords.append(m.surface) 45 #r.zincrby('words', 1.0, m.surface) 46 m = m.next 47 48#名詞の重複を消す 49nouns = [] 50for line in keywords: 51 if line not in nouns: 52 nouns.append(line) 53array1 = np.array(nouns) 54nouns = array1.reshape(1,len(nouns)) 55 56#tf, idfの計算 57tfs = [] # 記事毎のリスト。リスト要素は記事内の単語毎のtf値 58dfs = {} # 単語毎のdf値 59for idx,doc in enumerate(nouns): # idx=記事番号 60 tf = {} 61 for term in doc: 62 TERM_CNT = len(doc) # 記事内の単語数 63 64 # (記事内の)単語毎のtf値 65 if term not in tf: 66 tf[term] = 0 67 tf[term] += 1 / TERM_CNT # コード短縮のため、割り込むと同時に足す 68 69 # 単語毎のdf値 70 if term not in dfs: 71 dfs[term] = set() 72 dfs[term].add(idx) # 集合(set)で記事番号(idx)を保持 73 74 tfs.append(tf) 75 76# 記事番号の集合の大きさ=出現数 77for term,doc_set in dfs.items(): 78 dfs[term] = len(doc_set) 79 80# 単語毎のidf値 81idfs = {k:np.log(1/v) + 1 for k, v in dfs.items()} 82 83tf_val = [num.get(doc[0]) for num in tfs] #単語毎にtf値を取り出したい(問題の箇所) 84 85print('nouns:',nouns) 86print('tf:',tf_val) 87#print('dfs:',dfs) 88#print('idfs:',idfs)
補足情報(FW/ツールのバージョンなど)
iOS 10.15, Python 3.7.4, Atom
あなたの回答
tips
プレビュー