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
手を動かしてみる
こんなデータをいじる。
とりあえず参考にした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から始まる言葉がたくさん☆そしてこれをみるとanalyzer
をcharter_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)