def make_follower_text(): """ 一人当たり0~200件の フォロワーのツイートをテキストファイルに吐き出す """ follower_ids = ta.get_follower_ids(C.ANALYSYS_USER_ID) followers = ta.improved_create_users_from_ids(user_ids=follower_ids) # 非公開アカウントを弾き, # フォロー数の多い順で並べる followers = filter(lambda obj:obj.created_at.year <= C.VALID_USER_MAX_CREATED_AT , followers) followers = filter(lambda obj:obj.is_protected == False, followers) followers = sorted(followers, key=lambda obj: obj.friends_count, reverse=True) texts = [] for index, follower in enumerate(followers): utils.print_step_log("CreateText", index, len(followers)) try: follower_tweets = tg.get_user_timeline(user_id=follower.id, tweets_count=C.TWEETS_COUNT_FOR_MAKE_TEXT, include_rts=False) if follower_tweets is not None: for tweet in follower_tweets: texts.append(tweet['text']) except: traceback.print_exc() sleep(1) with open('tweets.csv', 'w') as f: writer = csv.writer(f, lineterminator='\n') header = ["tweet", "label"] writer.writerow(header) for text in texts: row = [unicode(text).encode('utf-8'), 1] writer.writerow(row)
def create_friend_ids_from_users(users): """ UsersたちのフォロイーのID(重複可)のリストを生成 """ friend_ids = [] for index, user in enumerate(users): utils.print_step_log("CreateFriendID", index, len(users)) cursor = -1 # 一回のフォロイーID取得上限が5000件なので、5000件以上あればループ for i in range(10): try: ids_cursor = tg.get_friend_ids(user.id, 5000, cursor) except: traceback.print_exc() sleep(60) break if ids_cursor == None or ids_cursor == []: sleep(60) break friend_ids.extend(ids_cursor[0]) cursor = ids_cursor[1] if cursor == 0: sleep(60) break print "Friend count over 5000 creating..." sleep(60) return friend_ids
def create_users_from_ids(user_ids): """ ユーザIDのリストからUserオブジェクトリストを生成 """ users = [] for index, user_id in enumerate(user_ids): utils.print_step_log("CreateUsersList", index, len(user_ids)) try: prof = tg.get_user_profile(user_id) except: traceback.print_exc() sleep(1) continue if prof == None or prof == []: sleep(1) continue user = User(id=prof['id'], name=prof['name'], description=prof['description'], friends_count=prof['friends_count'], created_at=dt.strptime(prof['created_at'], "%a %b %d %H:%M:%S +0000 %Y"), is_protected=prof['protected']) users.append(user) sleep(1) return users
def improved_create_users_from_ids(user_ids): """ create_users_from_idsの改善版 時間が100分の1になったやつ(プロフィールのクエリだけまとめてIDを飛ばせることに気づいた) """ users = [] user_ids_list = utils.split_list(user_ids, 100) for index, ids in enumerate(user_ids_list): utils.print_step_log("CreateUsersList", index, len(user_ids_list)) try: profs = tg.get_user_profiles(ids) except: traceback.print_exc() sleep(1) continue if profs == None or profs == []: continue for prof in profs: user = User(id=prof['id'], name=prof['name'], description=prof['description'], friends_count=prof['friends_count'], created_at=dt.strptime(prof['created_at'], "%a %b %d %H:%M:%S +0000 %Y"), is_protected=prof['protected']) users.append(user) sleep(1) return users
def analysys_follower_favorite(): """ フォロワーの共通ファボ分析 Tweetオブジェクトのリストを返す """ follower_ids = get_follower_ids(user_id=C.ANALYSYS_USER_ID) followers = improved_create_users_from_ids(user_ids=follower_ids) # 2016年以前のユーザで絞り込み, # 非公開アカウントを弾き, # フォロー数の多い順で並べる followers = filter( lambda obj: obj.created_at.year <= C.VALID_USER_MAX_CREATED_AT, followers) followers = filter(lambda obj: obj.is_protected == False, followers) followers = sorted(followers, key=lambda obj: obj.friends_count, reverse=False) followers = followers[0:C.REQUIRE_FOLLOWER_COUNT] favorites = get_favorites_from_users(followers) # ファボツイートのIDをキーにして、ファボツイートが何人にファボされているかを格納 favorites_counter_dict = collections.Counter(favorites) favorites = [] step = 0 for key, value in favorites_counter_dict.items(): utils.print_step_log("GetFavosTweet", step, len(favorites_counter_dict)) step += 1 if value < C.MIN_FAVORITE_COUNT_LIMIT: continue try: tweet = tg.get_tweet(key) except: traceback.print_exc() sleep(1) continue if tweet == None or tweet == []: sleep(1) continue favorite = Favorite(tweet_id=key, count=value, text=tweet['text'], tweet_user_name=tweet['user']['name']) favorites.append(favorite) sleep(1) favorites = sorted(favorites, key=lambda u: u.count, reverse=True) return favorites
def search_follower_tweets(word): """ wordを含むフォロワーのツイート抽出 Tweetオブジェクトのリストを返す """ follower_ids = get_follower_ids(user_id=C.ANALYSYS_USER_ID) followers = improved_create_users_from_ids(user_ids=follower_ids) # 2016年以前のユーザで絞り込み, # 非公開アカウントを弾き, # フォロー数の多い順で並べる followers = filter( lambda obj: obj.created_at.year <= C.VALID_USER_MAX_CREATED_AT, followers) followers = filter(lambda obj: obj.is_protected == False, followers) followers = sorted(followers, key=lambda obj: obj.friends_count, reverse=False) followers = followers[0:C.REQUIRE_FOLLOWER_COUNT] follower_tweets = [] for index, follower in enumerate(followers): utils.print_step_log("CreateTweetList", index, len(followers)) try: tweets = tg.get_user_timeline( user_id=follower.id, tweets_count=C.TWEETS_COUNT_PER_USER_RA, include_rts=True) tweets = filter(lambda obj: obj['text'].count(wosrd) > 0, follower_tweets) except: traceback.print_exc() sleep(1) continue for tweet in tweets: follower_tweets.append( Tweet(tweet_id=tweet['id'], text=tweet['text'], count=1)) sleep(1) return follower_tweets
def get_favorites_from_users(users): """ Userオブジェクトリストから そのユーザのファボツイート(200件/人)を返す """ favorite_tweet_ids = [] for index, user in enumerate(users): utils.print_step_log("CreateFavoritesList", index, len(users)) try: favs = tg.get_favorite_tweets(user.id, 200) except: traceback.print_exc() sleep(12) continue if favs == None or favs == []: sleep(12) continue for fav in favs: favorite_tweet_ids.append(fav['id']) sleep(12) return favorite_tweet_ids
def analysys_follower_retweet(): """ 共通リツイート分析 Tweetオブジェクトのリストを返す """ follower_ids = get_follower_ids(user_id=C.ANALYSYS_USER_ID) followers = improved_create_users_from_ids(user_ids=follower_ids) # 2016年以前のユーザで絞り込み, # 非公開アカウントを弾き, # フォロー数の多い順で並べる followers = filter( lambda obj: obj.created_at.year <= C.VALID_USER_MAX_CREATED_AT, followers) followers = filter(lambda obj: obj.is_protected == False, followers) followers = sorted(followers, key=lambda obj: obj.friends_count, reverse=False) followers = followers[0:C.REQUIRE_FOLLOWER_COUNT] retweet_ids = [] for index, follower in enumerate(followers): utils.print_step_log("CreateRetweetList", index, len(followers)) try: follower_tweets = tg.get_user_timeline( user_id=follower.id, tweets_count=C.TWEETS_COUNT_PER_USER_RA, include_rts=True) follower_retweets = filter( lambda obj: obj.has_key("retweeted_status"), follower_tweets) retweet_tweets = [ retweet["retweeted_status"] for retweet in follower_retweets ] except: traceback.print_exc() sleep(1) continue if retweet_tweets == None or retweet_tweets == []: sleep(1) continue ids = [retweet['id'] for retweet in retweet_tweets] retweet_ids.extend(ids) sleep(1) retweet_counter_dict = collections.Counter(retweet_ids) retweets = [] step = 0 for key, value in retweet_counter_dict.items(): utils.print_step_log("GetTweet", step, len(retweet_counter_dict)) step += 1 if value < C.MIN_RETWEET_COUNT_LIMIT: continue try: tweet = tg.get_tweet(key) except: traceback.print_exc() sleep(1) continue if tweet == None or tweet == []: sleep(1) continue tweet = Tweet(tweet_id=key, count=value, text=tweet['text']) retweets.append(tweet) sleep(1) retweets = sorted(retweets, key=lambda obj: obj.count, reverse=True) return retweets
def analysys_follower_morpheme(): """ フォロワーのツイートを形態素解析して、 単語の多い順のMorpheme(形態素)オブジェクトで返す """ follower_ids = get_follower_ids(C.ANALYSYS_USER_ID) followers = improved_create_users_from_ids(user_ids=follower_ids) # 2016年以前のユーザで絞り込み, # 非公開アカウントを弾き, # フォロー数の多い順で並べる followers = filter( lambda obj: obj.created_at.year <= C.VALID_USER_MAX_CREATED_AT, followers) followers = filter(lambda obj: obj.is_protected == False, followers) followers = sorted(followers, key=lambda obj: obj.friends_count, reverse=True) followers = followers[0:C.REQUIRE_FOLLOWER_COUNT] # 全followersの指定した数のツイートを形態素解析して重複考えずに全部word_listにぶち込む。対応する品詞もhinshi_listにぶち込む word_list = [] hinshi_list = [] username_list = [] for index, follower in enumerate(followers): utils.print_step_log("CreateWordList", index, len(followers)) try: follower_tweets = tg.get_user_timeline( user_id=follower.id, tweets_count=C.TWEETS_COUNT_PER_USER, include_rts=False) except: traceback.print_exc() sleep(1) continue if follower_tweets == None or follower_tweets == []: sleep(1) continue tweet_texts = [tweet['text'] for tweet in follower_tweets] # followerのツイートを形態素解析してword_listに入れる try: for text in tweet_texts: text = text.encode('utf-8').replace('\n', '').replace('\r', '').strip() keitaiso_list = utils.get_keitaiso_list_from_juman(text) word_list.extend(keitaiso_list[0]) hinshi_list.extend(keitaiso_list[1]) username_list.extend([follower.name] * len(keitaiso_list[0])) except: pass sleep(1) # 形態素と品詞を紐づけたまま単語数を数えたいので"形態素/品詞"の文字列で1単語とする word_hinshi_list = [] # 一つの単語を”単語/品詞/ユーザID”の形にする for word, hinshi, username in zip(word_list, hinshi_list, username_list): word_hinshi_list.append(word + "/" + hinshi + "/" + unicode(username).encode("utf-8")) # 単語をキーにして、単語が何回登場したかを辞書に格納 word_counter_dict = collections.Counter(word_hinshi_list) morphemes = [] for key, value in word_counter_dict.items(): if value < C.MIN_WORD_COUNT: continue # 形態素と品詞とuser_idを分ける # rsplitにすることで、もし"htt:///名詞"みたいな文字列があってもちゃんと分けられる splited_key = key.rsplit("/", 2) morphemes.append( Morpheme(username=splited_key[2], word=splited_key[0], hinshi=splited_key[1], count=value)) # ユーザ毎にまとめ、単語出現回数の多い順に並べて返す morphemes = sorted(morphemes, key=lambda u: (u.username, u.count), reverse=True) return morphemes
def analysys_follower_friends(): """ フォロワーの中でVALID_USER_MAX_CREATED_AT年以前の登録ユーザをフォロー数の降順に並べて 分析したアカウントをFriendオブジェクトにしてリストで返す """ follower_ids = get_follower_ids(user_id=C.ANALYSYS_USER_ID) followers = improved_create_users_from_ids(user_ids=follower_ids) # VALID_USER_MAX_CREATED_AT年以前のユーザで絞り込み, # 非公開アカウントを弾き, # フォロー数の多い順で並べる followers = filter( lambda obj: obj.created_at.year <= C.VALID_USER_MAX_CREATED_AT, followers) followers = filter(lambda obj: obj.is_protected == False, followers) followers = sorted(followers, key=lambda obj: obj.friends_count, reverse=True) followers = followers[0:C.REQUIRE_FOLLOWER_COUNT] # フォロワーがフォローしている人 friend_ids = create_friend_ids_from_users(users=followers) # 一応メモリ解放 del follower_ids del followers gc.collect() # フォロイーのIDをキーにして、フォロイーが何人にフォローされているかを格納 friends_counter_dict = collections.Counter(friend_ids) del friend_ids gc.collect() # 自分をFriendオブジェクトに登録するのは係数計算の部分で情報が必要なため my_prof = tg.get_user_profile(C.ANALYSYS_USER_ID) me_as_friend_obj = Friend(id=C.ANALYSYS_USER_ID, name=my_prof['name'], count=friends_counter_dict[C.ANALYSYS_USER_ID], followers_count=my_prof['followers_count'], bio=my_prof['description'].replace('\n', '').replace( '\r', ''), follow_rate=100.00, follow_ratio=1.0, factor=C.FACTOR_CONST) sleep(1) # フレンドのクラスの配列を作る # FIXME:ここも関数にしたかったが関数にしたらcountとidの挙動がおかしくなったので直書き friends = [] step = 0 # FIXME:辞書のループ用インデックス。friends_counter_dict.keys().index(key)で取りたかったが何故か無限ループするようになってしまったのでstepでやってる for key, value in friends_counter_dict.items(): step += 1 utils.print_step_log("CreateFriendList", step, len(friends_counter_dict)) # 何人以上のアカウントをとってくるか if value <= C.MIN_COUNT_LIMIT: continue try: prof = tg.get_user_profile(key) except: traceback.print_exc() sleep(1) continue if prof == None or prof == []: sleep(1) continue # フォロー率、フォロー比、係数を計算 if me_as_friend_obj.count != 0: follow_rate = float(value) / float(me_as_friend_obj.count) else: follow_rate = 0 if me_as_friend_obj.followers_count != 0: follow_ratio = float(prof['followers_count']) / float( me_as_friend_obj.followers_count) else: follow_ratio = 0 if follow_ratio != 0: factor = follow_rate / follow_ratio * C.FACTOR_CONST else: factor = 0 friend = Friend(id=key, name=prof['name'], count=value, followers_count=prof['followers_count'], bio=prof['description'].replace('\n', '').replace('\r', ''), follow_rate=round(follow_rate * 100, 2), follow_ratio=round(follow_ratio, 1), factor=round(factor, 1)) friends.append(friend) sleep(1) # フォローされている数の降順に並び替え friends = sorted(friends, key=lambda u: u.count, reverse=True) return friends