実際にランダムフォレストを使って、価格予測モデルを作成していきます。
フロー
参考: https://www.kaggle.com/amaiaga/xgboost-v8
# ライブラリの読み込み
library(data.table)
library(dplyr)
library(stringr)
library(ggplot2)
library(randomForest)
# データの読み込み
data <- fread("./data/case07_train.tsv", showProgress = FALSE, data.table = FALSE)
# 価格が0の商品をデータから取り除く
data <- filter(data, price != 0)
# 商品カテゴリーをレベル別に分解
temp <- str_split(data$category_name, pattern = "/")
data$category01 <- sapply(temp, function(x) x[1])
data$category02 <- sapply(temp, function(x) x[2])
data$category03 <- sapply(temp, function(x) x[3])
### データセットの作成
model.dat <- data.frame(
price = data$price,
condition = data$item_condition_id)
### カテゴリー数の上限にかからないようにダミー変数化
# 特定のキーワードが含まれていれば1を返す関数の定義
word_contain <- function(cate, desc, ...){
temp1 <- sapply(..., function(word) {
ifelse(grepl(word, cate) | grepl(word, desc), 1, 0)
})
ifelse(rowSums(temp1) != 0, 1, 0)
}
# ブランド
model.dat$pink <- word_contain(data$brand_name, data$item_description, "PINK")
model.dat$secret <- word_contain(data$brand_name, data$item_description, "VICTORIA'S SECRET")
model.dat$nike <- word_contain(data$brand_name, data$item_description, "NIKE")
model.dat$apple <- word_contain(data$brand_name, data$item_description, c("APPLE", "MAC"))
model.dat$lularoe <- word_contain(data$brand_name, data$item_description, "LULAROE")
# カテゴリー1
model.dat$beauty <- word_contain(data$category01, data$item_description, "BEAUTY")
model.dat$electronic <- word_contain(data$category01, data$item_description, "ELECTRONIC")
model.dat$handmade <- word_contain(data$category01, data$item_description, c("HANDMADE","DYI"))
model.dat$home <- word_contain(data$category01, data$item_description, c("HOME","HOUSE"))
model.dat$kid <- word_contain(data$category01, data$item_description, c("KID","BOY","GIRL", "CHILD"))
model.dat$women <- word_contain(data$category01, data$item_description, "WOMEN")
model.dat$men <- ifelse(((!grepl("WOMEN", data$category01)) & (grepl("MEN", data$category01)))|
((!grepl("WOMEN", data$item_description)) & (grepl("MEN", data$item_description))),
1, 0)
model.dat$athletic <- word_contain(data$category01, data$item_description, c("ATHLETIC","SPORT"))
model.dat$wine <- word_contain(data$category01, data$item_description, c("WINE","ALCOCHOL"))
# カテゴリー2
model.dat$athletic_apparel <- word_contain(data$category02, data$item_description, "ATHLETIC APPAREL")
model.dat$makeup <- word_contain(data$category02, data$item_description, "MAKEUP")
model.dat$blouse <- word_contain(data$category02, data$item_description, "BLOUSE")
model.dat$shoes <- word_contain(data$category02, data$item_description, "SHOE")
model.dat$toy <- word_contain(data$category02, data$item_description, "TOY")
model.dat$jewelry <- word_contain(data$category02, data$item_description, "JEWELRY")
model.dat$phone <- word_contain(data$category02, data$item_description, "PHONE")
model.dat$bag <- word_contain(data$category02, data$item_description, "BAG")
model.dat$dress <- word_contain(data$category02, data$item_description, "DRESS")
model.dat$pant <- word_contain(data$category02, data$item_description, c("PANT","JEAN"))
model.dat$accessories <- word_contain(data$category02, data$item_description, "ACCESSORIES")
model.dat$luxury <- word_contain(data$category02, data$item_description, c("WATCH","JEWELRY","RING","BRACELETS"))
# カテゴリー3
model.dat$tshirt <- word_contain(data$category03, data$item_description, c("T-SHIRT","TSHIRT"))
model.dat$face <- word_contain(data$category03, data$item_description, "FACE")
model.dat$game <- word_contain(data$category03, data$item_description, "GAME")
model.dat$lip <- word_contain(data$category03, data$item_description, "RIP")
model.dat$eye <- word_contain(data$category03, data$item_description, "EYE")
model.dat$care <- word_contain(data$category03, data$item_description, "CARE")
model.dat$top <- word_contain(data$category03, data$item_description, "TOP")
モデリング用と検証用にデータセットを分離
# ! すべてのデータを使うと処理に時間がかかるので、注意すること
train <- model.dat[1:100000,] # トレーニング用
test <- model.dat[100001:150000,] # 検証用
ランダムフォレストでモデリング
# チューニング
train.tune <- tuneRF(train[, -1], train[, 1], doBest = T)
## mtry = 11 OOB error = 1442.244
## Searching left ...
## mtry = 6 OOB error = 1440.779
## 0.001016172 0.05
## Searching right ...
## mtry = 22 OOB error = 1443.463
## -0.000844914 0.05
# モデリング
train.rf <- randomForest(price ~., data = train, mtry = train.tune$mtry)
# 検証用データにモデルを適用
test$pred <- predict(train.rf, test)
# 平均二乗誤差(検証用データのpriceと予測値の離れ具合)でモデル精度を評価
(mean((test$price - test$pred) ^ 2)) ^ 1/2
## [1] 692.1059
この数値はいろいろなパターンでモデルを作成し、比較する際に使う。
ggplot(test, aes(x = pred, y = price)) +
geom_point(alpha = 0.6)
#実際の価格が100ドル未満を対象
filter(test, price < 100) %>%
ggplot(aes(x = pred, y = price)) +
geom_point(alpha = 0.6)
予測値に100ドル以上のものはない。原因として次のようなことが考えられます。
モデルの変数(キーワード)を増やすことで、モデルの精度をあげられる可能性がある。
「データから価値を創造する」一般社団法人データマーケティングラボラトリー
Copyright© DML All Rights Reserved.