미국 도로교통안전국(NHTSA)은 미국에서 시판되는 자동차에 대한 리콜 및 고객불만 데이터를 NHTSA Office of Defects Investigation (ODI) - Recalls 웹API를 통해서 제공하고 있다.
R 팩키지도 공개되어 있어 openNHTSA를 통해서 별도 RESTful API 프로그래밍을 생략하고 R 코드로 자동차 리콜과 고객불만 데이터를 긁어올 수 있다.
NHTSA - 현대기아차 리콜과 불만 추세(2001-2017)에서 현대기아차 자동차 리콜 추세를 살펴보기 위한 상위수준 데이터를 긁어왔다면, 이번에는 동일한 기간 2001-2017 리콜에 대한 상세 내역을 긁어와서 분석을 추가로 추진한다.
openNHTSA 예제 코드를 참조하여 2001-2017년까지 현대차와 기아차에 대한 리콜과 불만 데이터을 위한 설정을 준비한다.
crawl_nhtsa()
함수를 통해 차량모델(vehicle_model()
) 함수에 넣을 차량모델을 추출하고 나서, 이를 crawl_nhtsa_detail()
함수에 넣어 리콜 및 고객불만에 대한 상세 내역을 웹API를 통해 가져온다.
# 0. 환경설정 ----------------
## 1.0. NHTSA 데이터 긁어오기
### 1.0.1. 제조사별, 리콜, 고객불만 모형 데이터
crawl_nhtsa <- function(maker, recall_complaint) {
nhtsa_df <- data.frame()
for(myear in 2001:2017) {
tmp_df <- facility(recall_complaint) %>%
model_year(myear) %>%
vehicle_make(maker) %>%
nhtsa_fetch()
nhtsa_df <- bind_rows(nhtsa_df, tmp_df)
}
return(nhtsa_df)
}
### 1.0.2. 리콜, 고객불만 상세 데이터
crawl_nhtsa_detail <- function(maker, recall_complaint, model) {
nhtsa_df <- data.frame()
for(myear in 2001:2017) {
tmp_df <- facility(recall_complaint) %>%
model_year(myear) %>%
vehicle_make(maker) %>%
vehicle_model(model) %>%
nhtsa_fetch()
nhtsa_df <- bind_rows(nhtsa_df, tmp_df)
}
return(nhtsa_df)
}
먼저 현대자동차 리콜(“recalls”)에 대한 상세 내역을 가져오고 나서, 고객불만(“complaints”) 데이터도 가져온다.
# 1. 현대차 리콜, 고객불만 데이터 가져오기 ----------------
## 1.1. 현대차 모델 뽑아내기
hyundai_df <- crawl_nhtsa("hyundai", "recalls")
hyundai_model_v <- hyundai_df %>% count(Model) %>% pull(Model)
## 1.2. 현대차 리콜 상세 데이터 긁어오기
# 2001년부터 현대차 리콜 상세 내역
hyundai_recall_df <- data.frame()
for(i in seq_along(hyundai_model_v)){
tmp_df <- crawl_nhtsa_detail("hyundai", "recalls", hyundai_model_v[i])
hyundai_recall_df <- bind_rows(hyundai_recall_df, tmp_df)
cat(i, ":", hyundai_model_v[i], "\n")
}
saveRDS(hyundai_recall_df, "data/hyundai_recall_df.rds")
## 1.3. 현대차 고객불만 상세 데이터 긁어오기
# 2001년부터 현대차 고객불만 상세 내역
hyundai_complaint_df <- data.frame()
for(i in seq_along(hyundai_model_v)){
tmp_df <- crawl_nhtsa_detail("hyundai", "complaints", hyundai_model_v[i])
hyundai_complaint_df <- bind_rows(hyundai_complaint_df, tmp_df)
cat(i, ":", hyundai_model_v[i], "\n")
}
saveRDS(hyundai_complaint_df, "data/hyundai_complaint_df.rds")
이어서 기아자동차 리콜(“recalls”)에 대한 상세 내역을 가져오고 나서, 고객불만(“complaints”) 데이터도 가져온다.
# 2. 기아차 리콜, 고객불만 데이터 가져오기 ----------------
## 2.1. 기아차 모델 뽑아내기
kia_df <- crawl_nhtsa("kia", "recalls")
kia_model_v <- kia_df %>% count(Model) %>% pull(Model)
## 2.2. 기아차 리콜 상세 데이터 긁어오기
# 2001년부터 기아차 리콜 상세 내역
kia_recall_df <- data.frame()
for(i in seq_along(kia_model_v)){
tmp_df <- crawl_nhtsa_detail("kia", "recalls", kia_model_v[i])
kia_recall_df <- bind_rows(kia_recall_df, tmp_df)
cat(i, ":", kia_model_v[i], "\n")
}
saveRDS(kia_recall_df, "data/kia_recall_df.rds")
## 2.3. 기아차 고객불만 상세 데이터 긁어오기
# 2001년부터 기아차 고객불만 상세 내역
kia_complaint_df <- data.frame()
for(i in seq_along(kia_model_v)){
tmp_df <- crawl_nhtsa_detail("kia", "complaints", kia_model_v[i])
kia_complaint_df <- bind_rows(kia_complaint_df, tmp_df)
cat(i, ":", kia_model_v[i], "\n")
}
saveRDS(kia_complaint_df, "data/kia_complaint_df.rds")
현대차 리콜 hyundai_recall_df
, 기아차 리콜 kia_recall_df
을 합하여 recall_df
분석용 데이터를 준비한다.
## 1.3. 리콜 데이터
recall_df <- bind_rows(hyundai_recall_df, kia_recall_df)
현대기아차 북미 NTHSA에서 리콜 부품에 대해서 BOM 위계체계를 갖는 형태로 데이터를 제공하기 하기 때문에 가장 상단 시스템 수준에 대한 고장부품/시스템에 대해서 분석을 하기 위해서 일정부분 전처리가 필요하다.
또한, 리콜 당시 한가지 부품만 문제가 되는 것이 아니라 다수 부품이 문제가 되기 때문에 이에 대해서도 적절한 데이터 정제과정을 거쳐 깔끔하게 정리한다.
# 2. 탐색적 데이터 분석 -------------
## 2.1. BOM 수준별 정리
bom_part_df <- recall_df %>%
count(Component, sort=TRUE) %>%
mutate(bom = str_split(Component, "\\|")) %>%
unnest(bom) %>%
mutate(part = str_split(bom, ":")) %>%
mutate(level = map_int(part, length)) %>%
unnest(part) %>%
mutate(part = str_trim(part)) #처음과 끝 공백 제거
## 2.2. BOM 최상위 수준
bom_system_df <- bom_part_df %>% group_by(Component, bom, level) %>%
summarise(system_part = first(part),
recall_cnt = first(n)) %>%
ungroup() %>%
select(Component, system_part, recall_cnt)
가장 먼저 현대기아차 모델별 리콜 횟수를 표로 도식화한다.
# 3. 리콜 자동차 부품 표/시각화 -------------
## 3.1. 자동차 모델
recall_df %>% count(Model, sort=TRUE) %>%
mutate(비율 = n/ sum(n),
누적비율 = cumsum(비율)) %>%
select(차량모델=Model, 리콜횟수=n, everything()) %>%
DT::datatable() %>%
DT::formatPercentage(c("비율", "누적비율"), digits=1)
다음으로 현대기아차 부품별로 가장 많은 리콜을 일으킨 부위를 표로 정리한다.
## 3.1. 리콜 자동차 부품
bom_system_df %>% group_by(system_part) %>%
summarise(recall_sum = sum(recall_cnt)) %>%
arrange(desc(recall_sum)) %>%
mutate(비율 = recall_sum/ sum(recall_sum),
누적비율 = cumsum(비율)) %>%
DT::datatable() %>%
DT::formatPercentage(c("비율", "누적비율"), digits=1)
현대기아차 차량모델, 부품별을 표로 작성하여 살펴면 다음과 같다.
## 3.3. 자동차 모델과 리콜 자동차 부품
recall_component_model_df <- recall_df %>% select(Make, Model, ModelYear, Component) %>%
mutate(bom = str_split(Component, "\\|")) %>%
unnest(bom) %>%
mutate(system_part = ifelse(str_detect(bom, ":"), str_extract(bom, "(^.*):"), bom)) %>%
mutate(system_part = str_trim(str_replace_all(system_part, ":", "")))
recall_component_model_df %>%
count(Model, system_part, sort=TRUE) %>%
mutate(비율 = n/ sum(n)) %>%
select(차량모델=Model, 고장부품=system_part, 리콜횟수=n, everything()) %>%
DT::datatable() %>%
DT::formatPercentage(c("비율"), digits=1)
현대기아차 차량모델, 부품별로 리콜 상세 내역을 차량 출시 연도와 함께 표로 살펴볼 수 있도록 정리한다.
recall_component_model_df %>%
select(-bom) %>%
DT::datatable()