はじめに
レビュー数の高さの識別に役立つ単語を洗い出せば、ユーザーがサイトのどんな商品特徴に満足していて、もしくは逆に商品特徴で不満を感じているのかを可視化・特定することができ、キャンペーンなどのマーケティング施策立案や、出品者へのアドバイス提供(「XXXだと消費者に好かれないですよ!」など)など、ビジネスインパクトのあるアクションに繋がる。
もちろん、ある変数に寄与する単語の可視化・特定する手法は、ビジネスの世界だけでなく、私の専門である政治学・国際政治学や経済学などの社会科学でも、例えばアメリカの民主党と共和党の言葉のチョイスの違いの分析や
(オープンアクセスではない)
金融指標の変化の予測に寄与する単語の洗い出し
(オープンアクセスではない)
などでも使える。
そこで、本記事では、こちらの記事を参考に、
https://qiita.com/10shimizu10/items/1f44e479917e9a94ae9d
とサイト
https://s3.amazonaws.com/amazon-reviews-pds/readme.html
Amazonが公開しているレビューのデータセットを使って、統計学(計量経済学?)の世界で考案された逆回帰という手法で、レビュー数の高さを識別する単語の洗い出しに挑む。
(オープンアクセスなのでぜひ読んでみてください)
手法紹介
逆回帰というのは、言葉で説明すると、普通の人がある変数に対する単語の効果を測るときにやりそうな、単語を独立変数(X)に、目的変数を従属変数(Y)にする発想とは真逆である。逆回帰では、単語を超多次元な従属変数に、目的変数を「逆」に独立変数にする。
こうすることによって、尤度関数を少し変形すれば、単語ごとに計算を分散させて、並列処理によって計算を高速化することができることが、上で紹介したTaddy(2015)が指摘した。要は、単語ごとに、単語の出現回数を目的変数で予測することである。
この考えは正直私も最初あまり理解できなかったが、Taddy(2013)を読み返してよくよく考えたら、単語の出現頻度を従属変数にするのは、LDAやSTMなどのトピックモデルでは一般的で、逆回帰も同じ思想で考案されたのかなと勝手に理解している。
分析
まずは、必要なパッケージをインポートして、
https://qiita.com/10shimizu10/items/1f44e479917e9a94ae9d
を参考にAmazonのレビューデータをダウンロードする。
library(RMeCab)
library(tidyverse)
library(quanteda)
library(distrom)
url <- 'https://s3.amazonaws.com/amazon-reviews-pds/tsv/amazon_reviews_multilingual_JP_v1_00.tsv.gz'
amazon_df <- read_tsv(url)
ただ、Macユーザーの場合、RMeCabのインポートがうまくいかない場合もある。詳細は別記事で書くが、単純にいうと、Macのターミナルではなく、RStudioのターミナルを使えば問題なくインストール・インポートできる可能性もある。
続いて、MeCabを使ってレビューデータの前処理を行う。MeCabに入れる前は、stringrを使って正規表現で漢字・ひらがな・カタカナ・ローマ字以外の文字と記号を除去する。また、自然言語処理が専門の同僚から頂いた意見で、名詞だけ残せば良い。最後に、RのQuantedaという便利なパッケージに我々が指定した単語分割結果を伝えるために、単語同士は空白で区切って結合する。
review_mecabbed <- c()
for (i in 1:nrow(amazon_df)){
this_review <- str_replace_all(amazon_df$review_body[i], "[^一-龠ぁ-んーァ-ヶーa-zA-Z]", " ")
mecab_output <- unlist(RMeCabC(this_review, 1))
review_mecabbed[i] <- str_c(mecab_output[which(names(mecab_output) == "名詞")], collapse = " ")
}
次に、MeCabで処理したレビューをRのQuantedaで文書行列を作成する。ここで重要なのは、トークン化する前に、phrase()という関数を一回噛ませることで、なぜかというと、phrase()を噛ませないと、tokens()関数が勝手にこちらがMeCabで綺麗に分割した単語をもう一回分割するからである。
最後の前処理として、レビュー点数などを入れた行列を作成する(逆回帰の関数が勝手に切片を作ってくれるから-1を入れた)。ここで商品種類(product_category)と役に立った数(helpful_vote)を入れるのは、前者に関して欠落変数の問題を回避するためで、要するに、レビュー数の高さを識別する単語と高人気商品のカテゴリーを識別する単語を区別することである。後者に関しては同じくビジネス示唆が得られそうなのでモデルに投入した。
review_dfm <- review_mecabbed %>%
phrase() %>%
tokens() %>%
dfm() %>%
dfm_trim(min_termfreq = 500, max_termfreq = 100000)
covars <- model.matrix(
~ - 1 + product_category + star_rating + helpful_votes, data = amazon_df
)
最後に、本記事では予測精度系の話は割愛するが、念の為学習データと訓練データに分けた後に、Taddy(2015)を参照に、あまり関心のない変数(商品種類)の比重を1/20にした。分散処理を活用したモデル推定を行う。
set.seed(12345)
train_id <- sample(
1:nrow(amazon_df),
round(nrow(amazon_df) * 0.7),
replace = FALSE
)
cl <- makeCluster(16)
fits <- dmr(cl,
counts = review_dfm[train_id,],
covars = covars[train_id,],
varweight = c(
rep(1/20, sum(str_detect(colnames(covars), "product_category"))),
rep(1, 2)
),
verb = 1
)
stopCluster(cl)
B <- coef(fits)
推定が完了したら、高レビュー数を識別する単語を100個抽出してみよう。
sort(B["star_rating",], decreasing = TRUE) %>%
head(100)
結果は以下の通りである:
感激 是非 虜 マリア 圧倒 モーツァルト 幸福
0.5406372 0.5163661 0.4814276 0.4213427 0.4143028 0.3981358 0.3914794
鳥肌 最高 敬遠 涙 最高峰 毎日 一生
0.3826645 0.3751838 0.3693088 0.3625509 0.3609174 0.3603915 0.3587694
この世 素敵 金字塔 圧巻 奇跡 絶妙 永遠
0.3519965 0.3467851 0.3366198 0.3359813 0.3280291 0.3223982 0.3219789
必見 お買い得 存分 お気に入り 脱帽 ススメ 情熱
0.3199689 0.3190991 0.3140149 0.3087858 0.3087270 0.3034923 0.2965678
たっぷり 完璧 豊か 誇り 胸 傑作 生涯
0.2952778 0.2853408 0.2811559 0.2789832 0.2747554 0.2732554 0.2730598
前向き 一線 鮮明 晴 教会 生まれ 拍手
0.2724707 0.2682710 0.2675764 0.2660892 0.2643827 0.2621610 0.2583445
信念 ロンドン 勇気 さりげ 感謝 天才 人生
0.2581960 0.2577575 0.2557189 0.2535280 0.2528456 0.2527878 0.2522612
アンディ 秀逸 見事 堪能 鮮やか 抜群 マイケル
0.2495437 0.2463400 0.2444204 0.2433562 0.2388473 0.2383265 0.2373154
真 魅了 史 あなた 驚異 息 高校
0.2321594 0.2316864 0.2278959 0.2250903 0.2234548 0.2210090 0.2191397
幸せ 苦しみ 機会 ロッキー パフォーマンス 錯覚 夢中
0.2186497 0.2182573 0.2164146 0.2137339 0.2137313 0.2136067 0.2125026
魂 得 普遍 発見 会場 興奮 静か
0.2123675 0.2123202 0.2088983 0.2064744 0.2057500 0.2053968 0.2043879
元気 心 爽やか きっかけ エネルギー 沢山 悲しみ
0.2038822 0.2032743 0.2004573 0.2001287 0.1988765 0.1987255 0.1976924
実現 強烈 一品 痛み 余談 正解 充実
0.1971608 0.1925254 0.1915004 0.1904773 0.1900427 0.1897504 0.1893354
彼 世界中 実感 神父 表情 大切 ユーモア
0.1874558 0.1873107 0.1870585 0.1855150 0.1851191 0.1841697 0.1839244
尊敬 冬
0.1832950 0.1824810
パッと見て確かに高レビューを示す単語で間違いなさそう。
では低レビューを識別する単語も出してみよう。
sort(B["star_rating",], decreasing = FALSE) %>%
head(100)
結果は以下の通りである:
返品 最低 駄作 台無し 最悪 はずれ タレント
-1.0190886 -0.6998398 -0.6923001 -0.6797042 -0.6307700 -0.6231636 -0.6092385
中途半端 外れ 薄っぺら 失望 雑 駄目 良品
-0.6091974 -0.5788900 -0.5480786 -0.5331807 -0.5080459 -0.4808540 -0.4676010
肝心 退屈 イマイチ まとも 新品 単調 三つ
-0.4437556 -0.4405987 -0.4316232 -0.4220384 -0.4215306 -0.4146054 -0.4116980
ヤマト 陳腐 肩透かし 不快 ダメ 残念 素人
-0.4098719 -0.4094393 -0.4038273 -0.3997994 -0.3977049 -0.3920019 -0.3780450
不可 発送 皆無 声優 ご都合主義 不明 そっち
-0.3757632 -0.3746132 -0.3588497 -0.3538846 -0.3531784 -0.3509619 -0.3444955
下手 連絡 劣化 失敗 期待 申し訳 アホ
-0.3414452 -0.3399489 -0.3395628 -0.3374354 -0.3324252 -0.3298680 -0.3284379
不自然 ユーザー 起用 それなり アベンジャーズ 唐突 安易
-0.3275367 -0.3272311 -0.3238004 -0.3219481 -0.3208307 -0.3205134 -0.3175007
不足 消費 無駄 結局 正直 販売 いくら
-0.3161199 -0.3118912 -0.3115238 -0.3106028 -0.3103611 -0.3092195 -0.3089605
ドラゴン ハズレ 宣伝 すぎ 馬鹿 強引 星
-0.3036203 -0.3033403 -0.2999843 -0.2981952 -0.2954460 -0.2939974 -0.2927883
典型 記載 平凡 適当 消化 だめ せい
-0.2924323 -0.2901613 -0.2874980 -0.2869653 -0.2851846 -0.2849361 -0.2810355
評価 絶賛 吹替 微妙 腹 コピー 表記
-0.2804271 -0.2783422 -0.2766268 -0.2731117 -0.2731077 -0.2723769 -0.2714643
中身 なん 過ぎ お金 交換 バカ 無視
-0.2712283 -0.2687967 -0.2639483 -0.2633744 -0.2626931 -0.2614768 -0.2611007
戦艦 下品 我慢 無理 減点 金 削除
-0.2598838 -0.2594604 -0.2592758 -0.2580244 -0.2567061 -0.2566617 -0.2544211
正規 プレデター オチ 都合 古代 しょうが 延
-0.2541454 -0.2522473 -0.2521699 -0.2518697 -0.2509334 -0.2492089 -0.2486384
ハザード 仕方
-0.2484189 -0.2478494
なかなか厳しい言葉が、、、
ではユーザーがどんなレビューに役に立ったを付けるのかも見てみよう。
sort(B["helpful_votes",], decreasing = TRUE) %>%
head(100)
これはなかなか興味深い結果が出た:
長調 短調 タレント op bwv ソナタ ヴァイオリン
0.006151981 0.005713377 0.005712510 0.005589355 0.005513805 0.005484828 0.005254814
管弦楽 協奏曲 モノラル 追記 歌劇 吹替え 交響
0.004997259 0.004939048 0.004901324 0.004806371 0.004684344 0.004677448 0.004569431
ショパン チェロ 団 アベンジャーズ 消費 吹替 起用
0.004497356 0.004425615 0.004363012 0.004339299 0.004333723 0.004299250 0.004295330
記載 感謝 シンジ 予約 番 d 交響曲
0.004293018 0.004292005 0.004281560 0.004264031 0.004262525 0.004236298 0.004226001
生産 ステレオ 全集 セル ユーザー 販売 ch
0.004218172 0.004205784 0.004087914 0.004069533 0.004046858 0.003997277 0.003987817
ホ 声優 修正 オヤジ disc マスター ブック
0.003984790 0.003959990 0.003933736 0.003930842 0.003842302 0.003820405 0.003818482
件 エヴァ ベートーヴェン リマスタリング amazon ファントム 序
0.003779216 0.003760333 0.003739100 0.003715288 0.003699674 0.003697916 0.003697603
ブラームス 指揮 採用 ボックス テイク 開始 月
0.003693613 0.003677374 0.003669914 0.003654555 0.003651235 0.003619853 0.003614154
集 アナ 限定 仕様 us 公式 削除
0.003610085 0.003605346 0.003602597 0.003601825 0.003540815 0.003533249 0.003521483
上記 アイドル 改善 国内 シカ サービス デジタル
0.003512566 0.003509791 0.003485282 0.003479887 0.003475882 0.003463066 0.003439495
提示 掲載 楽団 スチール ライナー 劣化 ソフト
0.003431721 0.003414412 0.003403370 0.003402583 0.003372885 0.003350183 0.003342279
p q 初回 ニック 以下 ナウ 版
0.003341142 0.003339643 0.003322108 0.003315905 0.003294272 0.003294023 0.003289128
ワーナー ボンド 追加 メディア 発売 カット 失礼
0.003288541 0.003252003 0.003246496 0.003229859 0.003197931 0.003181247 0.003179342
値 ディスク asin マーラー 担当 メーカー 廉価
0.003177227 0.003173575 0.003171350 0.003164456 0.003103663 0.003095296 0.003089737
沢山 放送
0.003074422 0.003066910
上位の単語に音楽・楽器系のものが多く含まれている。更なる深掘りは本記事の範囲を超えているが、ユーザーは音楽系・楽器系の商品で十分な説明を得られていないため、詳細を説明した他ユーザーに高評価をつけているという仮説も考えられそう。
パッと見てあまり解釈性なさそうであるが、役に立ったとつけられないことを識別する単語もついでに出すと:
sort(B["helpful_votes",], decreasing = FALSE) %>%
head(100)
新品 外れ イマイチ はずれ アレン お気に入り ワイルド ラブ
-0.020908560 -0.019141532 -0.014602748 -0.014420262 -0.011005618 -0.010987784 -0.010495179 -0.010313258
素敵 デンゼル スピード ミラ ジェイソン ストーリ 損 ワシントン
-0.009298527 -0.008953085 -0.008863214 -0.008532473 -0.008499143 -0.008473980 -0.007986643 -0.007855129
ノリノリ やつ 佳作 とこ 元気 ボス ジョニー ストーン
-0.007452962 -0.007391602 -0.007207410 -0.007103005 -0.007006083 -0.006946238 -0.006916759 -0.006867224
テンポ デイ 爽やか 退屈 アラン アイルランド 感じ 平凡
-0.006797614 -0.006653219 -0.006639228 -0.006598148 -0.006579847 -0.006567533 -0.006515411 -0.006497391
ウィル 犯人 キュート ピーター 恐竜 スリル 久しぶり ケイジ
-0.006444495 -0.006161261 -0.006054396 -0.005973915 -0.005926521 -0.005875003 -0.005867969 -0.005779620
典型 過激 味 勧め スゴイ どんでん返し 州 かっこよさ
-0.005730219 -0.005687051 -0.005505755 -0.005471287 -0.005448829 -0.005445589 -0.005438677 -0.005359056
共演 キレイ 満足 アイデア アメリカン クリス マッチ ニコラス
-0.005289951 -0.005288158 -0.005233992 -0.005205604 -0.005125408 -0.005114854 -0.005035161 -0.004883182
始まり 麻薬 一品 きれい 実話 ジュリア ゴシック 馬
-0.004779740 -0.004758739 -0.004752566 -0.004738883 -0.004729063 -0.004707213 -0.004700222 -0.004661058
南部 好き good ボク スリリング ノリ セクシー 捜査
-0.004641337 -0.004596942 -0.004587371 -0.004451967 -0.004416632 -0.004275825 -0.004259157 -0.004208989
邦題 ブラピ 弁護士 カッコ ファッション カー 手頃 中古
-0.004164683 -0.004157246 -0.004148543 -0.004050652 -0.004049326 -0.004018219 -0.004014966 -0.004001804
bgm 抜群 期待 タッチ ジム ドキドキ 単調 娘
-0.003963625 -0.003953413 -0.003928109 -0.003813160 -0.003788497 -0.003787578 -0.003718311 -0.003699099
ライアン 友達 大好き キッド 前半 グリーン コミカル 良好
-0.003682346 -0.003644885 -0.003587551 -0.003572862 -0.003569098 -0.003564408 -0.003545330 -0.003522240
流石 正統 ちゃん 相棒
-0.003497929 -0.003416219 -0.003412296 -0.003395483
最後に、あくまでも参考に、モデルは裏で商品種類を識別する単語を保持しているので、おもちゃの場合だけ見てみよう。
sort(B["product_categoryToys",], decreasing = TRUE) %>%
head(100)
可動 レゴ 塗装 パーツ フィギュア 造形 部品
6.745529 6.393230 6.245736 5.569749 5.363076 4.872435 4.866802
プレデター ヤマト 難易 ブロック シール 人形 電池
4.641431 4.590952 4.188265 4.098417 4.003908 3.993202 3.938283
プレゼント ピット エイリアン 孫 特撮 ゴジラ ダム
3.849661 3.594412 3.575686 3.571197 3.495553 3.463391 3.454311
髪 ピース ミラ ルール 誕生 おもちゃ オードリー
3.421491 3.182202 3.178306 3.130589 3.105014 3.098894 3.068934
固定 遊び クリスマス 恐竜 夢中 箱 背中
3.064670 3.047633 3.040986 3.029918 3.015492 3.006630 2.996500
本体 号 付属 装着 戦艦 艦 回転
2.983588 2.946088 2.940748 2.909089 2.906178 2.901122 2.894875
パイロット 顔 スターウォーズ 息子 男の子 再現 手持ち
2.880747 2.799464 2.779725 2.776355 2.772354 2.761667 2.747752
劇 立体 腕 娘 接続 親子 袋
2.736292 2.729897 2.728133 2.710527 2.685429 2.677730 2.653460
交換 腰 喜び 剣 ロボット ハウス スーツ
2.624522 2.623282 2.622130 2.596595 2.588390 2.574495 2.568908
範囲 製品 アベンジャーズ スイッチ 収納 エフェクト 武器
2.549199 2.535598 2.532733 2.528873 2.522986 2.506467 2.491384
手頃 組み 城 親 クリムゾン 足 木
2.478698 2.464432 2.457261 2.454612 2.449803 2.437710 2.434366
ドラゴン 肩 歳 ボール 商品 カラフル テクニック
2.421050 2.417798 2.410303 2.400761 2.397896 2.394379 2.389457
後ろ バトル 首 台 センチ ver スケール
2.383089 2.381260 2.368002 2.362191 2.347746 2.341675 2.340983
専用 建物 クイーン バットマン mm 飛行 セット
2.335495 2.325436 2.316600 2.312255 2.306627 2.295342 2.290328
モード 才
2.275060 2.249533
参考文献
Kelly, Bryan, Asaf Manela, and Alan Moreira. "Text selection." Journal of Business & Economic Statistics 39.4 (2021): 859-879.
Taddy, Matt. "Multinomial inverse regression for text analysis." Journal of the American Statistical Association 108.503 (2013): 755-770.
Taddy, Matt. "Distributed multinomial regression." The Annals of Applied Statistics 9.3 (2015): 1394-1414.