Jigsaw Rate Severity of Toxic Comments(TF-IDF)

sklearnでTF-IDF。用意された文書の集まりから語彙リストのようなものを作成して、頻度が低いほど点数高くする(IDF)。各文書について語彙ごとの出現頻度も出す(TF)。それを掛け合わせることで、各文書ごとに語彙のベクトル的なものを作成。

sklearn.feature_extraction.text.TfidfVectorizer — scikit-learn 1.0.2 documentation

https://www.takapy.work/entry/2019/01/14/141423

https://gotutiyan.hatenablog.com/entry/2020/09/10/181919

手を動かしてみる

こんなデータをいじる。 f:id:iiiiikamirin:20220117211920p:plain

とりあえず参考にしたNotebookの通りのパラメータとかでやってみる。termsを最初の10個ほどみてみたけど、単語がばらされすぎてこれでうまく特徴づけられるのか??という感じ。analyzerは分析上は意図をもってchar_wbにしているみたいではあるけど。。とにもかくにもワードごとのベクトルとしたところでその要素数が43448個もあるのではなにが特徴づけているのかもよくわからない。。ということで、次元削減したい→PCAしてみる。

from sklearn.feature_extraction.text import TfidfVectorizer  # for convert a collection of raw documents to a matrix of TF-IDF features

# TF-IDFの計算
tfidf_vectorizer = TfidfVectorizer(
#     use_idf=True,
#     lowercase=False,
#     max_features= 20000,
    analyzer= "char_wb",
    min_df= 3, # 語彙構築の際にこれより頻度が低いワード削除
    max_df= 0.5, # 語彙構築の際にこれより頻度が高いワード削除
    ngram_range= (3,5),
)
# ("vect3", TfidfVectorizer(min_df= 3, max_df=0.5, analyzer = 'char_wb', ngram_range = (3,5))),

# 文章内の全単語のTfidf値を取得
tfidf_matrix = tfidf_vectorizer.fit_transform(df['text'])

# index 順の単語リスト
terms = tfidf_vectorizer.get_feature_names()

# 単語毎のtfidf値配列:TF-IDF 行列 (numpy の ndarray 形式で取得される)
# 1つ目の文書に対する、各単語のベクトル値
# 2つ目の文書に対する、各単語のベクトル値
# ・・・
# が取得できる(文書の数 * 全単語数)の配列になる。(toarray()で密行列に変換)
tfidfs = tfidf_matrix.toarray()

print(f"term length: {len(terms)}")
print(f"tfidfs shape: {tfidfs.shape}")
terms[:10]
term length: 43448
tfidfs shape: (5000, 43448)
[' ! ', ' !!', ' !! ', ' !!!', ' !!! ', ' !!!!', ' " ', ' ""', ' "" ', ' """']

PCAして主成分の大きい要素をみるとたしかにfから始まる言葉がたくさん☆そしてこれをみるとanalyzercharter_wbとすることで単語の中でngramに分けたり可能→1つのfuckからfuc, uck,,,,とカウントを増やしてfuckの存在感を高められているのかもしれないと思うようになった。あと!が多いやつは攻撃的に見えるのでしょうね。!の数はよい情報かもしれん。

from sklearn.decomposition import PCA

pca = PCA(n_components=2)
pca.fit(tfidfs)

comp = pd.DataFrame(pca.components_, columns= terms, index= ["PCA1", "PCA2"])
comp1 = comp.loc["PCA1",:]
comp1.abs().sort_values(ascending= False).head(15)

comp2 = comp.loc["PCA2",:]
comp2.abs().sort_values(ascending= False).head(15)

f:id:iiiiikamirin:20220117214719p:plain

f:id:iiiiikamirin:20220117214732p:plain