データの導入
import pandas as pd
df0 = pd.read_excel('ethical_tweets_original.xlsx')
df0 = df0.drop(df0['Unnamed: 0'], axis=1)
df0
リツイートと広告ツイートの排除
df1 = df0.drop(df0[df0['retweet']].index)
df2 = df1.drop(df1[df1['advertise']].index)
df2
キーワードとツイート内容の列だけのデータフレームにする
df3 = df2[['keyword', 'tweet']]
df3
{ キーワード,ツイート内容 } の dict に変換する
tweets = df3.to_dict(orient='records')
tweets
センチメント分析の下準備(1)
!pip install transformers
!pip install transformers['ja']
!pip install sentencepiece
!pip install ipadic
センチメント分析の下準備(2)
from transformers import pipeline, AutoModelForSequenceClassification
from transformers import BertJapaneseTokenizer, BertTokenizer, BertForSequenceClassification
# パイプラインの準備
model = AutoModelForSequenceClassification.from_pretrained('koheiduck/bert-japanese-finetuned-sentiment')
tokenizer = BertJapaneseTokenizer.from_pretrained('cl-tohoku/bert-base-japanese-whole-word-masking')
classifier = pipeline("sentiment-analysis",model=model,tokenizer=tokenizer)
センチメント分析をして極性とスコアを返す関数を定義し,取得したツイートに適用する
def classify(tw):
result = classifier(tw)[0]
return (result['label'], round(result['score'], 4))
col_names = ['label','score','keyword','tweet']
df = pd.DataFrame(columns=col_names)
for tw in tweets:
(label, score) = classify(tw['tweet'])
new_row = pd.DataFrame([[label,score,tw['keyword'],tw['tweet']]],
columns=col_names)
df = pd.concat([df,new_row],axis=0)
df
インデクスが全部0でおかしいので,それを修正
df = df.reset_index().drop('index', axis=1)
df
簡単なテキストマイニングをしてみる.その準備(1)
#GiNZAのインストール
!pip install ginza
!pip install ja_ginza
#Matplotlib日本語化のインストール
!pip install japanize-matplotlib
#GraphViz関連のインストール
!apt install libgraphviz-dev
!pip install pygraphviz
#日本語フォントのインストール
!apt-get -y install fonts-ipafont-gothic
!rm ~/.cache/matplotlib/fontlist-v310.json
簡単なテキストマイニングをしてみる.その準備(2)
import pandas as pd
import spacy
import ginza
import math
import matplotlib.pyplot as plt
from itertools import combinations, dropwhile
from collections import Counter, OrderedDict
import numpy as np
from networkx.drawing import nx_agraph
import networkx as nx
import japanize_matplotlib
STOPWORDS = ['\n', 'o', '\u3000', '\n\u3000','\u3000\n',
'お','す','り','ご','いる','ある','ない','こと',
'なる','ござる','する','いう','言う','思う']
nlp = spacy.load('ja_ginza')
ginza.set_split_mode(nlp, 'C')
@によるメンションを削除する関数を定義
def remove_at_mention(text):
words = text.split()
return ' '.join([ x for x in words if x[0] != '@' ])
単語を抽出する関数の定義
def extract(s):
text = list(s)[0]
text = remove_at_mention(text) # @xxx... を取り除く
doc = nlp(text)
retvar = []
for sent in doc.sents:
noun = ''
for token in sent:
if token.lemma_ in STOPWORDS: continue
if token.pos_ in ['NOUN', 'PROPN', 'NUM']:
noun = noun + token.lemma_
elif noun != '':
retvar.append(noun)
noun = ''
if token.pos_ in ['ADJ', 'INTJ', 'ADV', 'VERB']:
retvar.append(token.lemma_)
if len(noun) > 0: retvar.append(noun)
return retvar
単語に分割した結果を新たな列として追加されたデータフレームを作成
df['words'] = df[['tweet']].apply(extract, axis=1)
df
共起ネットワーク図を書くコードの定義
def conet(df, outfile, min_count=3, edge_th=0.12):
# jaccard係数を計算する(回答の単語登場数:3以上、jaccard係数:0.12以上)
jaccard_coef = []
pair_all = []
words_array = [ set(x) for x in list(df['words']) ]
for chunk in words_array:
tmp_pair = list(combinations(chunk, 2))
for i, pair in enumerate(tmp_pair): tmp_pair[i] = tuple(sorted(pair))
pair_all += tmp_pair
pair_count = {x: count for x, count in Counter(pair_all).items() if count >= min_count}
word_count = Counter()
for chunk in words_array: word_count += Counter(chunk)
for pair, count in pair_count.items():
jaccard_coef.append(count / (word_count[pair[0]] + word_count[pair[1]] - count))
jaccard_dict = OrderedDict()
for (pair, count), coef in zip(pair_count.items(), jaccard_coef):
if coef >= edge_th: jaccard_dict[pair] = coef
# グラフの描画
G = nx.Graph()
G.add_nodes_from(sorted(set([j for pair in jaccard_dict.keys() for j in pair])))
for pair, coef in jaccard_dict.items(): G.add_edge(pair[0], pair[1], weight=coef)
plt.figure(figsize=(15, 15))
seed = 0
np.random.seed(seed)
pos = nx_agraph.graphviz_layout(G, prog='neato',
args='-Goverlap="scalexy" -Gsep="+6" -Gnodesep=0.8 -Gsplines="polyline" -GpackMode="graph" -Gstart={}'.format(seed))
values = nx.pagerank(G).values()
nx.draw_networkx_nodes(G, pos, node_color=list(values), cmap=plt.cm.terrain, alpha=1.0, node_size=[100000*v for v in values],
edgecolors='black')
nx.draw_networkx_labels(G, pos, font_family='IPAexGothic', font_size=24)
nx.draw_networkx_edges(G, pos, alpha=0.7, edge_color='black', width=[d['weight'] * 8 for (u, v, d) in G.edges(data=True)])
plt.axis('off')
plt.tight_layout()
plt.savefig(outfile, bbox_inches='tight')
クラス分けする
df_nega = df[df['label'] == 'NEGATIVE']
df_posi = df[df['label'] == 'POSITIVE']
df_neut = df[df['label'] == 'NEUTRAL']
共起ネットワーク図を描く(ネガティブ群)
conet(df_nega, 'nega.png')
共起ネットワーク図を描く(ポジティブ群)
conet(df_posi, 'posi.png')
ワードクラウドを作ってみる
import wordcloud
path_to_font='/usr/share/fonts/truetype/fonts-japanese-gothic.ttf'
def mk_wc(word_array):
wc = wordcloud.WordCloud(width=1000, height=600,
background_color='white', font_path=path_to_font)
wc.generate(' '.join(word_array))
plt.imshow(wc)
plt.axis('off')
import itertools
def mk_wc_from_df(df):
mk_wc(list(itertools.chain.from_iterable(df['words'])))
ワードクラウドを描く(ネガティブ群)
mk_wc_from_df(df_nega)
ワードクラウドを描く(ポジティブ群)
mk_wc_from_df(df_posi)
0 件のコメント:
コメントを投稿