寝坊検知&遅刻の言い訳提案システム #2
お疲れ様です。高橋です。
昨日作った遅刻の言い訳提案システムですが、Tweetの採取(search)と言い訳の提案(reply)、提案内容のA/Bテスト、寝坊した人の反応(ネガ/ポジ)を踏まえ、色々な知見を得ることが出来ました。
わかった事
- 土日の寝坊者は、遊び関連イベントへの遅刻が多い
- 個人に対するピンポイントなReplyなので、面白系の提案が来たらリツイートする率が高い
- いかにも自動的に生成した風なReplyのほうがポジ反応
- 10分前以上の「寝坊した」に提案するとネガ反応
- まるっきり的外れな提案するとネガ反応
- ドンピシャな提案するとポジ反応
対応した事
- 土日は完全対象外としました。
- 面白系をもっと増やそうと思います。
- もう少し「人間っぽい」パターンと「機械っぽい」パターンを継続し、ネガポジを見極めます。
- 毎分、1分以内の物にしか提案させないようにしました。
- これはもう、面白系の率を増やすしか無いかと思います。
- その人の過去Tweetの内容やTweet時間帯、プロフィール内容、Follower/Followの人たちを自動分析した上で出せれば究極。いつか、余力があったら。
コード
テーブル構造は最終的に下記の通り。
+------------+----------+------+-----+---------+-------+ | Field | +------------+----------+------+-----+---------+-------+ | tweet_id | TwitterのStatusID | user_id | TwitterのuserのID | user_name | Twitterのscreen_name | tweet_date | 寝坊Tweetの日時 | reply_date | 言い訳提案Replyの日時 | tweet | 寝坊Tweetの文言 | reply | 言い訳提案Replyの文言 +------------+----------+------+-----+---------+-------+
cron的に 「* 7-8 * * 1-5」(月曜~金曜 7時~8時 毎分)として動かすコードは下記の通り。
<?php // initialize require 'twitteroauth/autoload.php'; use Abraham\TwitterOAuth\TwitterOAuth; // configure $consumerKey = 'consumer keyを入れて下さい'; $consumerSecret = 'consumer secretを入れて下さい'; $accessToken = 'access tokenを入れて下さい'; $accessTokenSecret = 'access token secretを入れて下さい'; $db_host = 'dbのhost'; $db_user = 'dbのuser'; $db_pass = 'dbのpass'; $db_name = 'dbのname'; //$reply_tweet = 'もしかして寝坊しましたか?相手が納得出来る遅刻の言い訳を作るAndroidアプリは http://curious4dev.mydns.jp/ewake/redirect.php?tid='; $reply_tweet = array('寝坊を検知しました。遅刻の言い訳を提案します。','もしかして寝坊しましたか?勝手に遅刻の言い訳を考えました!'); $sql_select = 'select count(1) as count from ewakeLog where date_add(reply_date, interval 24 hour) > now() and user_id = :user_id;'; $sql_insert = 'insert into ewakeLog (tweet_id, user_id, user_name, tweet, reply, tweet_date, reply_date) values(:tweet_id, :user_id, :user_name, :tweet, :reply, :tweet_date, now());'; // load file $ewake_text = file('ewake.txt'); // conenct to mysql $pdo = new PDO("mysql:dbname=" . $db_name, $db_user, $db_pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET CHARACTER SET `utf8`")); // create Twitter object and search from tweets $twObj = new TwitterOAuth($consumerKey, $consumerSecret, $accessToken, $accessTokenSecret); $search_key = "寝坊した"; $options = array('q' => $search_key, 'count' => '100', 'lang' => 'ja'); $json = $twObj->get('search/tweets', $options); // check tweets foreach ($json->statuses as $result) { // get parameters from tweet $tweet_id = $result->id_str; $user_id = $result->user->id_str; $tweet = $result->text; $user_name = $result->user->screen_name; $created_at = $result->created_at; // delete \n $tweet = str_replace("\r\n", '', $tweet); $tweet = str_replace("\n", '', $tweet); // is Reply? if (mb_substr_count($tweet, '@') > 0 ) { $isReply = true; } else { $isReply = false; } // is RT? if (strpos($tweet, "RT") ==false) { $isRT = false; } else { $isRT = true; } // is寝坊した? if (mb_strpos($tweet, $search_key) ==false) { $isNebou = false; } else { $isNebou = tue; } // with HashTag? if (strpos($tweet, "#") == false) { $isHashTag = false; } else { $isHashTag = true; } // is Fresh Tweet?(less than 1 minute) $now = strtotime("-1 min"); $check = strtotime($created_at); if($now <= $check) { $isFresh = true; } else { $isFresh = false; } // check already send last 24 hour $statement = $pdo->prepare($sql_select); $statement->bindValue(':user_id', $user_id, PDO::PARAM_INT); $statement->execute(); $count = 0; if ($row = $statement->fetch()) $count = $row['count']; if ($count == 0) { $isAlreadySend = false; } else { $isAlreadySend = true; } // send reply when not reply and not RT and not send if ($isReply == false && $isRT == false && $isAlreadySend == false && $isHashTag == false && $isFresh == true && $isNebou == true) { // send reply $tmp_text = $ewake_text[mt_rand(0,count($ewake_text)-1)]; $tmp_text = str_replace("\r",'',$tmp_text); $tmp_text = str_replace("\n",'',$tmp_text); $tmp_text = str_replace("\r\n",'',$tmp_text); $ewake = $reply_tweet[mt_rand(0,1)] . '「' . $tmp_text .'」'; $reply = '@' . $user_name. ' '. $ewake; $reply_json = $twObj -> post('statuses/update', ['status'=>$reply, 'in_reply_to_status_id'=>$tweet_id]); // insert to log when success $created_at = date('Y-m-d H:i:s', strtotime($created_at)); $statement = $pdo->prepare($sql_insert); $statement->bindParam(':tweet_id', $tweet_id, PDO::PARAM_STR); $statement->bindParam(':user_id', $user_id, PDO::PARAM_STR); $statement->bindParam(':tweet', $tweet, PDO::PARAM_STR); $statement->bindParam(':reply', $reply, PDO::PARAM_STR); $statement->bindParam(':tweet_date', $created_at, PDO::PARAM_STR); $statement->bindParam(':user_name', $user_name, PDO::PARAM_STR); $statement->execute(); } } ?>
コードの中で、A/Bテスト用パラメータとして、人間っぽいのと機械っぽいのを設定しているのが下記の部分で、
$reply_tweet = array('寝坊を検知しました。遅刻の言い訳を提案します。','もしかして寝坊しましたか?勝手に遅刻の言い訳を考えました!');
↑の2つのどっちかをランダムに冒頭部分で使い、reply文言を生成してます。
$ewake = $reply_tweet[mt_rand(0,1)] . '「' . $tmp_text .'」';
あとは、
- 寝坊ツイートの中に @ が入っていたら提案しない
- 寝坊ツイートの中に # が入っていても提案しない
- RTされた寝坊ツイートにも提案しない
- 本当に「寝坊した」が含まれていないと提案しない
- 取得時点から1分以内のものにしか提案しない
- 24時間以内に同一寝坊者に再提案しない
という条件を定めています。
採用事例
採用してくれると、ちょっと嬉しい。
しかし、たまに「本当に人が送ってくれている」と誤認されている方がいらっしゃるようです。丁寧な御礼のリプライを頂いた事例が3例あり、いずれも年齢層若いような感じでした。
ネガにしろポジにしろ、反応がすぐに返ってくるから楽しいです。
もう、アプリじゃなくても良いんじゃないか?という考えが一瞬だけ頭をよぎりましたが、それは考えちゃダメだな、と。
明日の朝7:00~08:59がいよいよ平日の本番となります。
以上、よろしくお願い致します。
関連記事
-
-
遅刻の言い訳提案システムとウコンの力
お疲れ様です。高橋です。 現在稼働を続けている遅刻の言い訳提案システムは、改めて …
-
-
遅刻の言い訳提案システム 稼働初日
お疲れ様です。高橋です。 先日まで微調整を重ねてきた「遅刻の言い訳提案システム」 …
-
-
合理的な遅刻の言い訳生成アプリ。
お疲れ様です。高橋です。 寝坊と遅刻連絡について 平日の朝。iPhoneのアラー …
-
-
androidアプリの作り方
お疲れ様です。高橋です。 androidアプリの作り方は、ググったところ大体下記 …
-
-
SurfaceViewを使って絵を書き動かすサンプルをコピペして動かしてみた
お疲れ様です。高橋です。 本日はcocos2d-xの3.3rc0を導入しようと試 …
-
-
歌詞生成アプリ「カナかな?」の動詞をチューニングしてみた。
お疲れ様です。高橋です。 昨日はサーバ周りに熱中してしまってクライアント側を全く …
-
-
遅刻の言い訳アプリをリリースしてみた。
お疲れ様です。高橋です。 2/20あたりから、「合理的な遅刻の言い訳生成アプリ。 …
-
-
Win7(64bit)+Unity4.5.5f1で作った物をAndroidエミュで動かしてみた
お疲れ様です。高橋です。 先ほどはcocosを使ったサンプルをエミュで動かす所ま …
-
-
アプリDL状況と言い訳システムの効果について
お疲れ様です。高橋です。 リリースしたアプリのDL状況 3/20(Fri)時点で …
-
-
街頭インタビュー生成アプリ
お疲れ様です。高橋です。 街頭インタビューっぽいアプリ 街頭インタビューっぽい画 …