(検索:英語ver.)Pythonの言語処理ライブラリを使って「いいね」されやすい語句や傾向を調べる
はじめに
前回のブログ投稿ではtwitter APIを使用して、検索範囲を日本語に絞ってツイートを抽出し、 いいねのされやすい語句や傾向の調査を行いましたが、 今回の検索範囲は英語で行います。言語を変えると文化圏が変わりますので、傾向も変わってくると思います。 その傾向の違いなども比較していきます。
最後にはツイートをポジティブ/ネガティブなものであるかを数値化して、いいねとの関係を見ます。
英語は日本語とは文法が違うので形態素解析のしかたも変わってきます。 日本語ではMeCabを使用しましたが、今回はnltkライブラリを使用します。
ツイートの取得
日本語と同じくtwitter APIを使用してツイートを取得しますが、検索条件が異なります。 具体的には"lang: ja"の部分を"lang: en"に変更します。 取得内容はツイートID・本文・いいね数・リツイート数・引用数・ハッシュタグになります。 取得データは扱いやすいようにPandas DateFrameに変換します。 今回も検対象の語句は"Python"です。
word = "Python"
lang = "en" #ja -> en
df = get_tweet_by_word(f"{word} {f'lang: {lang}' if lang else ''} -RT OR @a -@a", num=5000)
df.to_csv(f"./{word}_en.csv")
いいね数・リツイート数・引用数・ハッシュタグ数
ツイートごとにそれぞれのデータのカウント行い図示しました。 データの見やすさのため、y軸はlogスケール、x軸は100までとしています。
日本語バージョンで検索したときと比較して、リツイート数とハッシュタグ数が多くなる傾向にありました。 20個以上ものハッシュタグをつけているツイートも少なくありませんでした。ハッシュタグ数がいいねの数に影響するのかどうかを確認しました。
散布図からはハッシュタグ数といいねの数に相関などはないようには見えます。 インプレッション数を稼ぐなどの宣伝効果を狙った物かもしれません。 取得した英語のツイートを実際に見てみると、日本語の時と比較して宣伝らしきツイートが多くみられる傾向にあったように感じました。
ツイートの文字数といいね数の関係
日本語の時と同じくツイートの長さは短すぎても、長すぎてもいいねが得られにくい傾向にあるようでした。
いいね数の多いツイートで使われる語句を調査
前回の日本語の時と同じく、 いいね数でツイートのクラス分けを行いました。 クラスごとに語句の使用傾向を調べて比較することでいいねされやすい語句の候補を見つけることができます。 クラスはいいね数ごとに3つ(low, mid, high)に分けました。
- low : いいね数 0-1
- mid : いいね数 2-19
- high : いいね数 20-
まず「ハッシュタグ別」のいいねの数を調べました。
low | mid | high |
---|---|---|
python : 1956 | python : 564 | python : 41 |
javascript : 866 | 100daysofcode : 446 | 100daysofcode : 27 |
100daysofcode : 804 | javascript : 329 | datascience : 21 |
coding : 328 | ai : 253 | ai : 21 |
ai : 327 | coding : 223 | iot : 17 |
programming : 303 | datascience : 210 | javascript : 17 |
homework : 288 | programming : 208 | machinelearning : 16 |
essay : 257 | machinelearning : 194 | bigdata : 15 |
machinelearning : 247 | iot : 151 | coding : 14 |
follow4follow : 240 | bigdata : 131 | tensorflow : 13 |
followme : 240 | java : 129 | programming : 11 |
datascience : 218 | flutter : 125 | rstats : 11 |
womenwhocode : 214 | tensorflow : 111 | flutter : 10 |
essaypay : 186 | reactjs : 111 | linux : 10 |
data : 183 | nodejs : 110 | serverless : 10 |
case : 180 | linux : 104 | java : 9 |
onlineclass : 174 | cybersecurity : 95 | reactjs : 9 |
nodejs : 163 | serverless : 90 | iiot : 8 |
philosophy : 157 | womenwhocode : 89 | technology : 8 |
paper : 153 | rstats : 88 | tech : 8 |
econometrics : 143 | iiot : 75 | cybersecurity : 7 |
crypto : 134 | analytics : 72 | artificialintelligence : 7 |
java : 131 | artificialintelligence : 70 | nlp : 7 |
r : 115 | tech : 69 | cloudcomputing : 6 |
essaywrite : 110 | cloudcomputing : 65 | datascientist : 6 |
ondemand : 108 | nft : 62 | blockchain : 6 |
math : 105 | css : 61 | fintech : 5 |
chemistry : 104 | opensource : 56 | ml : 5 |
business : 96 | html : 53 | analytics : 5 |
assignment : 94 | codenewbie : 53 | data : 4 |
日本語の時と比べて、かなり傾向が違いました。 日本語検索のときはどちらかというとコミュニケーションを求める語句や「プログラミング」や「エンジニア」など漠然とした語句が多かったのですが、 英語検索の場合はほとんどが具体的なIT関連語句やデータサイエンス関連の語句で埋まっていました。 また、「100daysofcode」というものが流行っているようです。これは毎日プログラムを書く習慣をつけようというハッシュタグのようです。 いいねの数が少ないlowでは「essay」「homework」「follow」などが上位に目立ちますが、いいね数が多くなる(mid/high)に従ってPythonに関連するような用語が上位に上がってきているようでした。 英語圏では積極的に関連の深い情報を発信するようなツイートが好まれるような傾向にあるようです。 また、ハッシュタグの絶対数が大きいので積極的にハッシュタグが使用されているようです。
次にツイートに使用された「語句別」のいいねの数を調べました。 語句の抽出にはnltkライブラリを使用しました。 語句は名詞・形容詞・動詞のみをカウントするようにして、数字やURLは除去するようにしました。 英語の場合はさらにstopwordsリストから文脈にあまり意味のない一般的な語句を除去処理をする必要があります(is, the, don'tなど)。
コードの流れとしてはnltk.pos_tagを用いてWordNetLemmatizerによってtoken化された文章から品詞を取得し、不要な記号を除去した後、lemmatizerで見出し語に変換します。 lemmatizerは(betterをgood、複数形を単数に変換するなど標準形に変換するようなものです)。 最後にアルファベットの大文字と小文字でカウントが別々になるのを防ぐために、全て小文字にしました。
import re
from nltk.corpus import stopwords
import nltk
from nltk.stem.wordnet import WordNetLemmatizer
import string
nltk.download('punkt')
nltk.download('stopwords')
nltk.download('averaged_perceptron_tagger')
nltk.download('wordnet')
nltk.download('omw-1.4')
STOPWORDS = frozenset(stopwords.words('english'))
def pick_words(df):
wnl = WordNetLemmatizer()
punct = str.maketrans("", "", string.punctuation+'’')
words = []
for id, item in df.iterrows():
tokens = nltk.word_tokenize(item["text"])
base = []
for token, tag in nltk.pos_tag(tokens):
token = re.sub(r'http\S+', '', token)
token = re.sub(r'#', '', token)
token = re.sub(r'@[\w\d_]*', '', token)
token = token.translate(punct)
if token == '' or token.isdigit():
continue
if tag.startswith("NN"):
pos = 'n'
elif tag.startswith('JJ'):
pos = 'a'
elif tag.startswith('VB'):
pos = 'v'
else:
continue
token = wnl.lemmatize(token, pos=pos)
token = token.lower()
if token not in STOPWORDS and token not in string.punctuation+'’':
base.append(token)
words.append(base)
return words
low | mid | high |
---|---|---|
python : 4197 | python : 861 | python : 86 |
essay : 1265 | javascript : 345 | gt : 22 |
pay : 1159 | ai : 263 | ai : 22 |
javascript : 1003 | datascience : 212 | datascience : 21 |
due : 779 | machinelearning : 194 | javascript : 19 |
paper : 774 | program : 174 | iot : 17 |
data : 575 | cod : 156 | machinelearning : 16 |
assignment : 571 | iot : 151 | bigdata : 15 |
homework : 526 | java : 142 | tensorflow : 13 |
write : 516 | bigdata : 129 | rstats : 11 |
help : 482 | tensorflow : 116 | data : 11 |
math : 451 | reactjs : 111 | use : 11 |
class : 401 | nodejs : 110 | cod : 10 |
dm : 362 | data : 108 | amp : 10 |
ai : 350 | linux : 105 | serverless : 10 |
program : 324 | cybersecurity : 96 | linux : 10 |
chemistry : 300 | learn : 91 | java : 9 |
cod : 291 | serverless : 90 | reactjs : 9 |
learn : 277 | womenwhocode : 89 | monty : 9 |
use : 276 | rstats : 88 | nlp : 8 |
java : 273 | coding : 85 | flutter : 8 |
time : 272 | day : 79 | tech : 8 |
research : 267 | flutter : 76 | learn : 8 |
business : 266 | analytics : 76 | program : 8 |
monty : 254 | iiot : 76 | technology : 8 |
case : 252 | css : 73 | iiot : 8 |
hmu : 250 | tech : 73 | programming : 7 |
someone : 249 | programming : 73 | cybersecurity : 7 |
machinelearning : 247 | artificialintelligence : 72 | see : 7 |
anatomy : 246 | use : 71 | analytics : 7 |
語句の方でもハッシュタグ時と同じのように関連性が深い用語を使用したほうが、いいねが得られやすいようです。 いいねの数が少ないlowの上位には「essay」「pay」「assignment」「homework」がありますが、検索語句とは関連性の薄いように感じます。 上位語句の中に"gt"がありますが、これは">"HTML特殊文字の記号のことで矢印に使用されていることが多いようです。 全角の矢印を使わない英語圏ならではないかと思います。 ハッシュタグだけではなく語句の方でも日本語とは違った傾向が見られtwitter文化が違うことが分かりました。
語彙分析
最後に語彙分析として、ツイートをポジティブ・ネガティブなものにスコアとして数値化しいいねの数と比較を行います。 この数値化に関してはVADER(https://github.com/cjhutto/vaderSentiment)を使用しました。 VADERはソーシャルメディア上の感情に特化した語彙とルールベースの感情分析を行うツールです。 スコアが1.0に近ければポジティブ、-1.0に近づけばネガティブとなります。 ソースコードは以下のようにシンプルなものになります。
ツイートテキストからURLや引用、タグの#、数字、stopwordsの除去を行って不要なものを除去した後、 SentimentIntensityAnalyzerを使用します。
STOPWORDS = set(stopwords.words('english'))
def get_clean_tweet(df):
clean_tweet = []
for id, item in df.iterrows():
text = item["text"]
text = re.sub(r'http\S+', '', text)
text = re.sub(r'#', '', text)
text = re.sub(r'@[\w\d_]*', '', text)
text = nltk.word_tokenize(text)
new_text = []
for wi in text:
if wi not in STOPWORDS or not wi.isdigit():
new_text.append(wi)
clean_tweet.append(" ".join(new_text))
return clean_tweet
clean_tweet = get_clean_tweet(df)
df["clean_text"] = clean_tweet
nltk.download("vader_lexicon")
from nltk.sentiment.vader import SentimentIntensityAnalyzer
analyzer = SentimentIntensityAnalyzer()
scores = [analyzer.polarity_scores(tweet)['compound'] for tweet in df['clean_text']]
df["scores"] = scores
検索語句が"Python"の場合はポジティブなツイートの方がいいねが得られやすい傾向にあるようです。 (logスケールなので見た目以上に差はあります)。 別の検索語句を使用すれば、また違った傾向が得られるかもしれません。
まとめ
今回は英語を検索条件として、Python + nltkを使用してツイートからタグと語句を抽出し、日本語の検索結果との比較を行いました。 文化圏が違うと、ウケがいい(いいねの数が多い)ツイートの傾向も大きく変化するようです。 自分と相性のよさそうな領域を探してみて、 合ったところがあればそれに合わせたツイートをするようなことをしてみてもよいかもしれません。