【自習】ベーカリーの売上分析【前処理~可視化】

データ分析について自分なりに勉強を始めたけれども, 使わない知識がどんどん抜け落ちていくので,アウトプットして少しでも定着させられたらと思う.

今回はRを使ってベーカリーのレシート情報(kaggle:Transactions from a bakery よりDL)
からどんな知見が得られるのかやってみます.
半年前までQiitaって何？って状態だった私が試すことなので, 同じような非エンジニアから入ってきた人にも分かるようくどい内容になっています.

# 1. データの前処理

```R
#「BreadBasket_DMS.csv」の置き場を作業ディレクトリにする.
setwd("C:\\Users\\name\\Desktop\\pan")
#ほかにもファイルがある場合, csvだけを指定して取得する.
csv_list <- list.files(pattern=".csv")
#csv_listにはいっているBreadBasket_DMS.csvをbread_dataとして格納する.
bread_data <- read.csv(csv_list)
#直接ファイル名を指定してもできる.
#read.csv("BreadBasket_DMS.csv")
#kaggleなど見ているとreadrのread_csv関数を使ってることが多いみたいです.
#データの中にNAが無いかを確認する.
table(is.na(bread_data))
#FALSE
#85172
#NAは無いようなので次にデータの構造を調べる.

#データの構造(行列)の次元を調べる.
dim(bread_data) 
#[1] 21293     4
#21293行 4列のカタチをしていることがわかった.

names(bread_data)
#[1] "Date" "Time" "Transaction" "Item"  
#4列のタイトルは日付, 時間, 取引番号, 品物　らしい.

#頭と尾の3行を確認する.

head(bread_data,3)
#        Date     Time Transaction         Item
#1 2016-10-30 09:58:11           1        Bread
#2 2016-10-30 10:05:34           2 Scandinavian
#3 2016-10-30 10:05:34           2 Scandinavian
tail(bread_data,3)
#            Date     Time Transaction      Item
#21291 2017-04-09 14:57:06        9683    Coffee
#21292 2017-04-09 14:57:06        9683    Pastry
#21293 2017-04-09 15:04:24        9684 Smoothies

#Itemには商品名が文字として入っていて, Transactionには一回の取引番号に対して品物が結び付いているらしい.
#時間のデータは2016年の10月末から2017年の4月頭までの半年間のデータのよう.
```

ここまで確認して, データから得られそうな情報は
・取引番号(Transaction)と品物(Item)が結び付いているので何と何が一緒に購入されているのか調べる
　(パンとコーヒーは同時に買われることが多そう)
・時期によってどんな品物が売れるのか
　(季節で特に売れる品、売れない品などあるのか)

これだけではわからないけれど, データから予想できそうなこと
・実はキャンペーンやCMを始めたことで、売り上げが伸びた時期がある（逆に下がる）

では品物の特性を調べてみます.

```R
#品物はどんなものを取り扱っているのか確認.
table(bread_data$Item)

#                   Adjustment      Afternoon with the baker                     Alfajores 
#                            1                            44                           369 
#              Argentina Night                      Art Tray                         Bacon 
#                            7                            38                             1 
#              　　　　　　(                           以下省略                             )

#見にくい!できれば読み込んだ時と同様に行列で見たい.
#data.frameという属性を個別に指定できるような少し変わった構造に突っ込む.
data.frame(table(bread_data$Item))
#                            Var1 Freq
#1                     Adjustment    1
#2       Afternoon with the baker   44
#3                      Alfajores  369
#4                Argentina Night    7
#5                       Art Tray   38
#                         （　以下省略　）
#95              Victorian Sponge    7
#見やすくなった!　95品目あるらしい.
#品物によっては1回という全然売れていない品も見受けられる.
#商品の名前だけほしいときは.
unique(bread_data$Item)
#で取得できる.

#data.frameにしておくとedit関数でエクセルのような直観的な操作もできるようになる.
data <- data.frame(table(bread_data$Item))
edit(data)
```
品目数や品物名や購入された数が分かった.
ここまでで半年間の人気商品,不人気商品がわかる.
では時系列で半年間のデータを確認した時, 季節で売り上げ個数が変化するものはあるのか？を調べてみます.

まず一日刻みだとプロットした時大変になるので一か月ごとに品物を集計して, 月別売上数を調べることにしましょう.
品物も95個すべてに対して行うと95本の線が出来てしまうので上位の数品目程度に対して行ってみます.

#2.とりあえずプロット(大事)

```R
plot_data <- sort(data$Freq)
plot(plot_data)
```
![01.png](https://qiita-image-store.s3.amazonaws.com/0/275572/fceabfee-2610-46bc-490f-95bdfca6fdc8.png)
![02.png](https://qiita-image-store.s3.amazonaws.com/0/275572/2321e35c-df51-2826-be20-da151f6247d8.png)

95品目のうちほとんどが1000以下(グラフからして100以下がほとんど),
上位10~30品目程度が主力と考えられる.

今回は上位10品目で確認していく.

```R
order_data <- data[order(data$Freq, decreasing=T),]
order_data_10 <- order_data[1:10,]
order_data_10
#            Var1 Freq
#24        Coffee 5471
#12         Bread 3325
#85           Tea 1435
#16          Cake 1025
#67        Pastry  856
#64          NONE  786
#75      Sandwich  771
#56     Medialuna  616
#49 Hot chocolate  590
#27       Cookies  540
```
頻度を多い順からorder関数で数えてみると上記のようになった.
NAはなかったがNONEというおそらく分類できない品目が入ってきている.
NONEが分析するのに意味のあるものなら残し、何かわからないようなものなら消す.
今回はNONEを除いていこうと思う.

```R
#上位10品目が含まれている行を取り出す.
#dateの列から年-月までの7文字を切り出して新しい列とする.
for (i in 1:nrow(order_data_10)){
  extract_Item           <- order_data_10$Var1[i]
  bind_data              <- bread_data[bread_data$Item==extract_Item,]
  bind_data$month        <- substr(bind_data$Date,1,7)
  #より細かい条件で抽出したり、時間帯など範囲指定をするときは時刻データに直しておくと便利
  #bind_data$time_series <- as.POSIXct(paste(bind_data$Date ,bind_data$Time))
  bind_all_data          <- rbind(bind_all_data, bind_data)
  }

bind_all_data
#　　　　　   Date      Time Transaction          Item   month
#48201  2016-11-29 11:02:41        2282        Coffee 2016-11
#48211  2016-11-29 11:03:17        2283        Coffee 2016-11
#48241  2016-11-29 11:26:39        2285        Coffee 2016-11
#48261  2016-11-29 11:34:50        2287        Coffee 2016-11
#48331  2016-11-29 12:00:52        2291        Coffee 2016-11
#（以下省略）
```
あとはmonthに対してItemの登場する頻度を数え上げる.

```R
df2 <- NULL
for (i in 1:nrow(order_data_10)){
  df1 <- bind_all_data[bind_all_data$Item==order_data_10$Var1[i],]
  df1 <- data.frame(table(df1$month))
  df2 <- rbind(df2,df1)
  }
df2
#monthと頻度だけのデータなので品目名を入れる.
item_list <- c(
  rep("Coffee",7),
  rep("Bread",7),
  rep("Tea",7),
  rep("Cake",7),
  rep("Pastry",7),
  rep("NONE",7),
  rep("Sandwich",7),
  rep("Medialuna",7),
  rep("Hot_chocolate",7),
  rep("Cookies",7)
  )
#eachを明記してもできる.
#c(rep(c("Coffee","Bread","Tea","Cake","Pastry",
  "NONE","Sandwich","Medialuna","Hot_chocolate",
  "Cookies"),each=7))
df2$item <- item_list
head(df2)
#     Var1 Freq   item
#1 2016-10  186 Coffee
#2 2016-11 2378 Coffee
#3 2016-12 1864 Coffee
#4 2017-01 1784 Coffee
#5 2017-02 2008 Coffee
#6 2017-03 2142 Coffee

#忘れないようにNONEの行を除いておく
df2 <- df2[!df2$item == "NONE",]

```
月, 頻度, 品目のデータができたので月ごとの折れ線グラフにする.

```R
#install.packages("ggplot2")
#library(ggplot2)
monthly_sales <- ggplot(df2, aes(x = Var1, y = Freq, color = item, group=item)) +  
                   geom_point() + 
                   geom_line()
monthly_sales
```
![03.png](https://qiita-image-store.s3.amazonaws.com/0/275572/e08a7cf1-68fa-ef73-2415-decda2ff7500.png)

breadとcoffeeは同じような線ですから, 一緒に買われるのかもしれません.
より正確にはアソシエーション分析しましょう.

1月は売れ行きが下がっています.
他の商品はそうでもないのに何かあったのでしょうか.

アソシエーション分析についても続けて別の記事にしたいとおもいます.

（やっていることを記事にして人に伝えることは難しい）

以上
(2019/04/01　記入)
(2019/04/02 read.csvについて修正)