Twitterでは日々幅広い話題に関するやり取りが行われています。
今回、日本代表の試合が行われた日の対話データを手に入れることができたので、このデータを使って日本代表についてのみ雑談ができる対話エージェントを作ってみます。
この記事ではどうやってデータを収集したのかを書いていきます。
環境
※MeCabをWindowsにインストールするには
https://www.pytry3g.com/entry/2018/04/24/143934#Windows
データを集める
今回、Twitterの対話データを集めるにあたって、こちらをー>(GitHub - higepon/twitter_conversation_crawler: Twitter Conversation Crawler)使わせて頂きました。
TwitterのAPIを利用するので、Twitter Application Managementでconsumer_key, consumer_secret, access_token, access_token_secretを取得します。これらの詳細について今回は割愛します。一応説明しているリンクを載せておきます。->(http://www.nltk.org/howto/twitter.html)英語で書かれていますが……
APIキーを用意し設定した後、crawler.pyを実行するとツイートを集めることができます。
データの前処理
crawler.pyで日本代表の試合が行われた6/19, 24, 28, 7/2のツイートを集めました。その後、textify.pyを使って対話データに成形しました。その際にURLやハッシュタグを含む対話データは取り除くようにします。
手に入れた対話データは以下のような3つのツイートから構成されています。
- ユーザAによるツイート -(1)
- (1)に対するユーザBのリプライ -(2)
- (2)に対するユーザAのリプライ -(3)
手に入れた対話データのほとんどはワールドカップとは関係のないものです。
そのため、ワールドカップに関するキーワードを含むツイートを探してきます。今回はワールドカップに関するキーワードが2つ以上のツイートに含まれていた場合、それらを対話データとして使うようにします。
そのために、textify.pyを少しいじります。
__init__の変更
import MeCab
import argparse
import re
import sqlite3
import sys
class Dumper:
def __init__(self, db):
self.db = db
self.url_regexp = re.compile(r"https?://")
self.name_regexp = re.compile(r"@([A-Za-z0-9_]+)")
self.tag_regexp = re.compile(r"#(\w+)")
self.cnt = 0
self.tagger = MeCab.Tagger("-Owakati")
self.keyword = ["本田", "香川", "川島", "大迫", "長友", "長谷部", "乾", "原口",
"昌子", "酒井", "柴崎", "西野", "ワールドカップ",
"日本", "コロンビア", "セネガル", "ポーランド", "ベルギー"]
is_valid_conversation
ハッシュタグを取り除くところを追加
def is_valid_conversation(self, text1, text2, text3):
if text1 is None or text2 is None or text3 is None:
return False
for text in [text1, text2, text3]:
if re.search(self.url_regexp, text):
return False
for text in [text1, text2, text3]:
if re.search(self.tag_regexp, text):
return False
return True
dump
キーワードを含むかどうかを調べるところを追加。
def dump(self):
conn = sqlite3.connect(self.db)
cursor = conn.cursor()
cursor.execute(
"select count(*) from conversation")
total_conversation = cursor.fetchall()[0][0]
cursor.execute(
"select sid1, sid2, sid3 from conversation")
for row in cursor:
sid1, sid2, sid3 = row
text1 = self.tweet_text(conn, sid1)
text2 = self.tweet_text(conn, sid2)
text3 = self.tweet_text(conn, sid3)
if self.is_valid_conversation(text1, text2, text3):
text1, text2, text3 = self.mapper(text1, text2, text3)
if self.is_valid_statement(text1, text2, text3):
self.cnt += 1
conn.close()
print("Number of total conversation: {}".format(total_conversation))
print("Number of valid conversation related to World Cup: {}".format(self.cnt))
mapperの変更
def mapper(self, text1, text2, text3):
text1 = text1.replace(">", ">").replace("<", "<")
text2 = text2.replace(">", ">").replace("<", "<")
text3 = text3.replace(">", ">").replace("<", "<")
text2 = re.sub(self.name_regexp, '', text2)[1:]
text3 = re.sub(self.name_regexp, '', text3)[1:]
return text1, text2, text3
is_valid_statement
新しく追加。
ワールドカップに関するキーワードが2つ以上のツイートに含まれる場合Trueを返す。
def tokenizer(self, text):
return self.tagger.parse(text).strip()
def is_valid_statement(self, text1, text2, text3):
text1 = self.tokenizer(text1)
text2 = self.tokenizer(text2)
text3 = self.tokenizer(text3)
flags = [0, 0, 0]
for word in self.keyword:
if word in text1.split():
flags[0] = 1
elif word in text2.split():
flags[1] = 1
elif word in text3.split():
flags[2] = 1
return 1 if sum(flags) >= 2 else 0
前処理の結果
3つのツイートから構成する対話データを1としてカウントします。
6/19 日本xコロンビア
手に入れた対話データは全部で11923。
前処理をすると、92。
手に入れた対話データは全部で13672。
前処理をすると、62。
手に入れた対話データは全部で12679。
前処理をすると、122。
7/2 日本xベルギー
手に入れた対話データは全部で8841。
前処理をすると、55。
サンプル
手に入れた対話データのサンプル
ユーザA:セネガルつええ、ボルト三体くらいいるわ笑笑
ユーザB:しょーみコロンビアより強い
ユーザA:それなまちがいないわ
続き
次回、PyTorchを使って対話エージェントを作る予定。