def extract_relation(doc_id: str) -> Tuple[str, Dict[str, Any]]: # doc_id から該当する文書を取得 text = datastore.get(doc_id, fl=["content"])["content"] annotation_id = 0 # 文を 1つずつ取得し, 正規表現に合致する箇所を抽出する # 抽出したものは relation に格納 for sentence in datastore.get_annotation(doc_id, "sentence"): for m in pattern.finditer(text[sentence["begin"]:sentence["end"]]): relation = { "cause": { "begin": m.start("cause") + sentence["begin"], "end": m.end("cause") + sentence["begin"], "link": ("effect", annotation_id) }, "effect": { "begin": m.start("effect") + sentence["begin"], "end": m.end("effect") + sentence["begin"], } } annotation_id += 1 yield sentence, relation return
def main(): datastore.connect() data = [] for doc_id in datastore.get_all_ids(limit=-1): row = datastore.get(doc_id, ["id", "content", "meta_info"]) # Solr へ登録するデータ構造へ変換 meta_info = json.loads(row["meta_info"]) data.append({ "id": str(row["id"]), "doc_id_i": row["id"], "content_txt_ja": row["content"], "title_txt_ja": meta_info["title"], "url_s": meta_info["url"] }) # Solr への登録を実行 indexer.put("doc", data) datastore.close() return
def main(): datastore.connect() sentences = [] # :TODO 書籍と異なる方法で記載. 後ほど変更する # **** ここから **** for doc_id, in datastore.get_all_ids(limit=20): for sentence in datastore.get_annotation(doc_id, "sentence"): tokens = find_xs_in_y( datastore.get_annotation(doc_id, "token"), sentence ) sentences.append((doc_id, sentence, tokens)) # **** ここまで **** rule = ruleclassifier.get_rule() # 分類 feature = ruleclassifier.convert_into_feature_using_rules(sentences, rule) predict = ruleclassifier.classify(feature, rule) for predicted, (doc_id, sentence, tokens) in zip(predict, sentences): if predicted == 1: text = datastore.get(doc_id, ["content"])["content"] print(predicted, text[sentence["begin"]: sentence["end"]]) datastore.close() return
def main(): datastore.connect() print("Success connecting 'sample.db'") # SQLite より id の一覧を取得 # 1つずつ処理を進める for doc_id in datastore.get_all_ids(limit=-1): # SQLite より文章を取得 row = datastore.get(doc_id=doc_id, fl=["content"]) text = row["content"] # 取得した文章を CaboCha で係り受け構造の解析を行い, # 文, 文節, 単語に分割されたデータを取得 sentences, chunks, tokens = parser.parse(text) print(f"parsed: doc_id={doc_id}") # SQLite に解析結果を保存 datastore.put_annotation(doc_id, "sentence", sentences) datastore.put_annotation(doc_id, "chunk", chunks) datastore.put_annotation(doc_id, "token", tokens) datastore.close() return
def create_annotation(doc_id, pattern): # doc_id に対応する 1レコードを取得 row = datastore.get(doc_id=doc_id, fl=["content"]) text = row["content"] # 付与したアノテーションを格納する list annotations = [] # 1文節ごと( == chunk )ごとに正規表現を用いて, 該当する単語を抽出 # 該当するものがあれば, それをアノテーションとして, 付与する for chunk in datastore.get_annotation(doc_id, "chunk"): chunk_str = text[chunk["begin"]: chunk["end"]] m = pattern.search(chunk_str) if not m: continue annotation = { "begin": chunk["begin"] + m.start(), "end": chunk["end"] + m.end() } print(text[annotation["begin"]: annotation["end"]]) annotations.append(annotation) return annotations
def main(): datastore.connect() for doc_id in datastore.get_all_ids(limit=10): row = datastore.get(doc_id, ["id", "content", "meta_info"]) print(f"{row['id']}\n" f"{row['meta_info']}\n" f"{row['content']}\n" f"********") datastore.close() return
def main(): client = datastore.connect() # アノテーションを格納するための column を作成(該当するテーブルがない場合のみ, 作成) columns = [i[1] for i in client.execute(f"PRAGMA table_info(docs)")] new_columns = [ "cause", "effect" ] for new_column in new_columns: if new_column not in columns: client.execute( f"ALTER TABLE docs ADD COLUMN '{new_column}' 'BLOB'" ) client.commit() print(f"Create new column: {new_column}") else: print(f"Already exist table column: {new_column}") # - SQLite より全ての doc_id を取得 # - doc_id に対応する文書を取得 # - 正規表現を用いて, 関係性を抽出 for doc_id in datastore.get_all_ids(limit=-1): text = datastore.get(doc_id, fl=["content"])["content"] annotations = {} for sentence, relation in extract_relation(doc_id): print(f"文書 {doc_id} {text[sentence['begin']: sentence['end']]}") for annotation_name, annotation in relation.items(): print(f"{annotation_name} {text[annotation['begin']: annotation['end']]}\n") annotations.setdefault(annotation_name, []).append(annotation) for annotation_name, annotation in annotations.items(): datastore.put_annotation(doc_id, annotation_name, annotation) datastore.close() return
def main(): datastore.connect() # SQLite より id の一覧を取得 # 1つずつ処理を進める for doc_id in datastore.get_all_ids(limit=-1): # SQLite より文章を取得 row = datastore.get(doc_id=doc_id, fl=["content"]) text = row["content"] # token を取得し, それらを出力 print("token:") tokens = datastore.get_annotation(doc_id, "token") for token in tokens: print( f" {token['POS']} {text[token['begin']: token['end']]}") # chunk を取得し, それらを出力 print("chunks:") chunks = datastore.get_annotation(doc_id, "chunk") for chunk in chunks: _, link = chunk["link"] print(f" {text[chunk['begin']: chunk['end']]}") if link != -1: parent = chunks[link] print(f" --> {text[parent['begin']: parent['end']]}") else: print(f" --> {None}") print("sentences:") sentences = datastore.get_annotation(doc_id, "sentence") for sentence in sentences: print(f" --> {text[sentence['begin']: sentence['end']]}") datastore.close() return
def main(): # SQLite に接続 datastore.connect() data = [] doc_ids = [] # doc_id を 1つずつ取得し, それに含まれている単語の原形を取得 for doc_id in datastore.get_all_ids(limit=-1): lemmas = [ token["lemma"] for token in datastore.get_annotation(doc_id, "token") ] data.append(" ".join(lemmas)) doc_ids.append(doc_id) # TF-IDF を算出 vectorizer = TfidfVectorizer(analyzer="word", max_df=0.9) vectors = vectorizer.fit_transform(data) # doc_id ごとに TF-IDF の値が高い単語を表示 # まずは, doc_id に紐づく meta データを取得 for doc_id, vec in zip(doc_ids, vectors.toarray()): # meta データから doc_id に紐づく title を取得 meta_info = json.loads( datastore.get(doc_id, ["meta_info"])["meta_info"]) title = meta_info["title"] print(doc_id, title) # TF-IDF を出力 for w_id, tf_idf in sorted(enumerate(vec), key=lambda x: x[1], reverse=True)[:10]: lemma = vectorizer.get_feature_names()[w_id] print(f"\t{lemma}: {tf_idf}") datastore.close() return
def main(): # SQLite に接続 datastore.connect() data = [] doc_ids = [] # doc_id を 1つずつ取得し, それに含まれている単語の原形を取得 for doc_id in datastore.get_all_ids(limit=-1): lemmas = [ token["lemma"] for token in datastore.get_annotation(doc_id, "token") ] data.append(" ".join(lemmas)) doc_ids.append(doc_id) # TF-IDF を算出 vectorizer = TfidfVectorizer(analyzer="word", max_df=0.9) vectors = vectorizer.fit_transform(data) # コサイン類似度を算出 sim = cosine_similarity(vectors) # doc_id と, それに対するコサイン類似度の算出結果を紐づけ docs = zip(doc_ids, sim[0]) # doc_id ごとに コサイン類似度にもとづく類似度の高い文書を表示 # まずは, doc_id に紐づく meta データを取得 for doc_id, similarity in sorted(docs, key=lambda x: x[1], reverse=True): meta_info = json.loads( datastore.get(doc_id, ["meta_info"])["meta_info"] ) title = meta_info["title"] # doc_id とコサイン類似度にもとづく類似度の高い文書, その値を出力 print(doc_id, title, similarity) datastore.close() return
def main(): # SQLite に接続 datastore.connect() annotation_name = "affiliation" # 全てのレコードを取得し, 1レコードずつ, 格納されているアノテーションを出力 for doc_id in datastore.get_all_ids(limit=-1): row = datastore.get(doc_id=doc_id, fl=["content"]) text = row["content"] annotations = datastore.get_annotation(doc_id, annotation_name) for annotation in annotations: print( f"{annotation_name.upper()}: {text[annotation['begin']: annotation['end']]}" ) datastore.close() return
def main() -> None: datastore.connect() # - SQLite より全ての doc_id を取得 # - doc_id に対応する文書を取得 # - 正規表現を用いて, 関係性を抽出 for doc_id in datastore.get_all_ids(limit=-1): text = datastore.get(doc_id, fl=["content"])["content"] for sentence, relation in extract_relation(doc_id): print(f"文書: {doc_id} {text[sentence['begin']: sentence['end']]}") for annotation_name, annotation in relation.items(): print( f"{annotation_name} {text[annotation['begin']: annotation['end']]}" ) print("\n ******** \n") datastore.close() return
def get(): doc_id = bottle.request.params.id names = bottle.request.params.name.split() row = datastore.get(doc_id, fl=["content"]) text = row["content"] data = { "collection": { "entity_types": [] }, "annotation": { "text": text, "entities": [], "relations": [] } } mapping = {} for name in names: annos = datastore.get_annotation(doc_id, name) for i, anno in enumerate(annos): data["collection"]["entity_types"].append({ "type": name, "bgColor": "#7fa2ff", "borderColor": "darken" }) ti = f"T{len(data['annotation']['entities']) + 1}" data["annotation"]["entities"].append( [ti, name, [[anno["begin"], anno["end"]]]]) mapping[(name, i)] = ti return
def extract_relation(doc_id: str): # 文章, 文, 文節, 単語を取得 text = datastore.get(doc_id, fl=["content"])["content"] all_chunks = datastore.get_annotation(doc_id, "chunk") all_tokens = datastore.get_annotation(doc_id, "token") annotation_id = 0 # 1文ずつ loop で処理を行う for sentence in datastore.get_annotation(doc_id, "sentence"): # 文中に出現する文節, 単語を取得 chunks = find_xs_in_y(all_chunks, sentence) tokens = find_xs_in_y(all_tokens, sentence) # 1文節ずつ loop で処理を行う for chunk in chunks: # 文節中に出現する単語を取得 chunk_tokens = find_xs_in_y(tokens, chunk) # 単語の原型が動詞の「与える」であるものを取得 # 該当するものがない場合は, 次の文節の処理へ check = [ chunk_token["lemma"] == "与える" for chunk_token in chunk_tokens ] if not any(check): continue # 「与える」の文節を「影響を」の文節が修飾しているか否かを探索する # 該当するものがない場合は, 次の文節の処理へ affect, affect_token = find_child( parent=chunk, chunks_in_sentence=chunks, tokens_in_sentence=tokens, text=text, all_chunks=all_chunks, child_cond={"text": ["影響を"]} ) if affect is None: continue # 影響元を取得 # 該当するものがない場合は, 次の文節の処理へ cause, cause_token = find_child( parent=chunk, chunks_in_sentence=chunks, tokens_in_sentence=tokens, text=text, all_chunks=all_chunks, child_cond={ "pos1": ["助詞"], "lemma1": ["は", "も", "が"], "pos2_ng": ["助詞"] } ) if cause is None: continue # 影響先を取得 # 該当するものがない場合は, 次の文節の処理へ effect, effect_token = find_child( parent=chunk, chunks_in_sentence=chunks, tokens_in_sentence=tokens, text=text, all_chunks=all_chunks, child_cond={ "pos1": ["助詞"], "lemma1": ["に"], "pos2_ng": ["助詞"] } ) if effect is None: continue # 影響元, 影響先を relation 変数に格納 # 該当する文とともに yield で呼び出し元に値を返す relation = { "cause": { "begin": cause["begin"], "end": cause["end"], "link": ("effect", annotation_id) }, "effect": { "begin": effect["begin"], "end": effect["end"] } } annotation_id += 1 yield sentence, relation return
def main(): # SQLite に接続 datastore.connect() # dic_id を1つずつ取得し, その doc_id 内の文章ごとに含まれる単語の原形を sentences に格納 sentences = [] for doc_id in datastore.get_all_ids(limit=-1): all_tokens = datastore.get_annotation(doc_id, "token") for sentence in datastore.get_annotation(doc_id, "sentence"): tokens = find_xs_in_y(all_tokens, sentence) sentences.append( [token["lemma"] for token in tokens if token.get("NE") == "O"]) # 分析に使用する記事が少ないため, 20文を 1つの文書として扱うように sentence を結合 n_sent = 20 docs = [ list(itertools.chain.from_iterable(sentences[i:i + n_sent])) for i in range(0, len(sentences), n_sent) ] # LDA の計算に使用する単語を選定 # - 出現頻度が 2つ未満の文書の場合, その単語は計算に使用しない( no_below=2 ) # - 出現頻度が 3割以上の文書の場合, その単語は計算に使用しない( no_above=0.3 ) dictionary = Dictionary(docs) dictionary.filter_extremes(no_below=2, no_above=0.3) # 単語の集まりを doc2bow method を用いて, 所定のデータ型に変換 corpus = [dictionary.doc2bow(doc) for doc in docs] # LDA モデルを作成 lda = LdaModel(corpus, num_topics=10, id2word=dictionary, passes=10) # 主題の確認 # Topic の一覧を出力 # Topic の一覧と合わせて, その Topic の中で確率値の大きい単語上位 10個を出力 for topic in lda.show_topics(num_topics=-1, num_words=10): print(f"Topic id: {topic[0]} Word: {topic[1]}") # 記事の主題分布の推定 # doc_id ごとに確率値の大きい Topic を出力 for doc_id in datastore.get_all_ids(limit=-1): meta_info = json.loads( datastore.get(doc_id=doc_id, fl=["meta_info"])["meta_info"]) title = meta_info["title"] print(title) doc = [ token["lemma"] for token in datastore.get_annotation(doc_id, "token") if token.get("NE") == "O" ] topics = sorted(lda.get_document_topics(dictionary.doc2bow(doc)), key=lambda x: x[1], reverse=True) for topic in topics: print(f" Topic id: {topic[0]} Prob: {topic[1]}") datastore.close() return