Ejemplo n.º 1
0
def create_language_model(doc_ids: List[str, ], n: int = 3) -> MLE:
    sentences = []

    # doc_id を 1つず処理していく
    for doc_id in doc_ids:
        # doc_id に紐づく単語を取得
        all_tokens = datastore.get_annotation(doc_id, "token")

        # doc_id に紐づく文を取得
        # find_xs_in_y を使用し, 文に含まれている単語のみを抽出し, sentences に格納
        for sentence in datastore.get_annotation(doc_id, "sentence"):
            tokens = find_xs_in_y(all_tokens, sentence)

            sentences.append(["__BOS__"] +
                             [token['lemma']
                              for token in tokens] + ["__EOS__"])

    # ボキャブラリを作成
    vocab = Vocabulary([word for sentence in sentences for word in sentence])

    # n-gram を利用して, 1組 n 個の単語の組み合わせ作成
    ngram = [ngrams(sentence, n) for sentence in sentences]

    # MLE というモデルを用いて, 言語モデルを作成
    lm = MLE(order=n, vocabulary=vocab)
    lm.fit(ngram)

    return lm
Ejemplo n.º 2
0
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 find_child(
		parent,
		chunks_in_sentence,
		tokens_in_sentence,
		text,
		all_chunks,
		child_cond
) -> Tuple:
	for child in chunks_in_sentence:
		_, link = child["link"]

		if (link == -1 or
			all_chunks[link] != parent):
			continue

		child_tokens = find_xs_in_y(tokens_in_sentence, child)

		if text[child["begin"]: child["end"]] in child_cond.get("text", []):
			return child, child_tokens

		if (child_tokens[-1]["POS"] in child_cond.get("pos1", []) and
			child_tokens[-1]["lemma"] in child_cond.get("lemma1", []) and
			child_tokens[-2]["POS"] not in child_cond.get("pos2_ng", [])):
			return child, child_tokens

	return None, None
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
Ejemplo n.º 5
0
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