Авторы Анкита Венката и Абдулрахман Идрис

Цель нашего проекта

Airbnb — это веб-сайт, на котором люди могут бронировать недвижимость для отпуска, представленную разными хозяевами в зависимости от доступности, цены, отзывов, удобств и т. д. Цель этого проекта — разработать количественно подкрепленные предложения для листингеров Airbnb, чтобы помочь им повысить рейтинг своих клиентов и прибыли.

Случаи использования в бизнесе

Есть два типа пользователей, которым могут быть полезны результаты этого проекта.

  1. Новые листинги, которые хотят разместить свою недвижимость на Airbnb

Какую цену они должны использовать? Каким факторам они должны отдать приоритет, чтобы увеличить запрашиваемую цену?

2. Существующие листингеры, которые уже разместили свою недвижимость на Airbnb:

Каким факторам они должны отдать приоритет, чтобы повысить рейтинг своих клиентов? Каким факторам они должны отдать приоритет, чтобы увеличить запрашиваемую цену?

Исследовательский анализ

Для этой презентации мы выбрали набор данных Airbnb от Opendatasoft. Исходный набор данных содержит информацию, которая была скопирована с веб-сайта Airbnb в 2017 году, и содержит все точки данных, отображаемые для каждого объявления на веб-сайте.

Исходный набор данных содержал 494 954 наблюдения с 70 атрибутами, но для простоты вычислений для проекта были выбраны данные, относящиеся только к Соединенным Штатам. Это включало 134 544 наблюдения и после очистки данных было сокращено до 130 814 наблюдений с 44 переменными, которые были включены в описание набора данных, приведенное ниже.

Для первого сегмента нашего анализа целевой переменной был столбец, созданный для классификации отзывов на хорошие и плохие. Для второго сегмента целевой переменной были данные о цене в долларах США.

Предварительная обработка данных

Для очистки данных были предприняты следующие шаги, чтобы упростить обработку данных:

  1. Столбец удобств был закодирован в горячем режиме и разделен на 106 отдельных атрибутов, поэтому каждое удобство было закодировано двоичным способом.
  2. Было обнаружено, что 1972 наблюдения имеют цену 0 или NULL, и эти строки были удалены.
  3. Было обнаружено, что 1665 наблюдений имеют нулевой почтовый индекс, и эти строки были удалены.
  4. Было обнаружено, что определенные типы свойств присутствуют среди менее чем 20 наблюдений, и соответствующие наблюдения для них были удалены, а 93 наблюдения были удалены.
  5. Некоторые наблюдения были NULL для большинства атрибутов, и они были удалены.

После предварительной обработки набор данных содержал 130 814 наблюдений со 151 атрибутом.

Визуализация данных

Данные были визуализированы, и результаты соответствовали нашей первоначальной интуиции:

По мере того, как пространство собственности стало более общим, цена собственности снизилась. Это соответствует нашей интуиции рынка, где аренда всего дома, как правило, дороже, чем проживание в общежитии.

Было обнаружено, что средняя цена листинга увеличивалась по мере ужесточения политики отмены. Это можно объяснить тем, что отмена объявлений с более высокими ценами оказывает более сильное влияние на бизнес, что вынуждает более дорогие объявления применять более строгие правила отмены.

Было обнаружено, что средняя цена на замки и таймшеры была выше, чем на другие типы недвижимости, в то время как диапазон цен на виллы, дома и кондо был выше, чем на другие типы недвижимости. Хостелы, общежития и палатки имели самые низкие средние цены, и даже их более высокие выбросы составляли около 100 долларов. Это согласуется с результатами Рис. 1, где общие комнаты имели самые низкие цены.

Выяснилось, что по мере увеличения вместимости жилья средняя цена листинга увеличивалась равномерно. Этот вывод соответствует общей бизнес-модели отелей и отелей, где цены сильно зависят от количества людей, которые могут остановиться в отеле.

Было замечено, что самая высокая средняя цена на списки была в штате Техас со стоимостью более 200 долларов. Среди других штатов был аналогичный диапазон от 100 до 200 долларов. Мы также признаем, что у нас нет данных для списков в определенных штатах, и это может привести к отсутствию точных прогнозов. Некоторые штаты, такие как Калифорния и Нью-Йорк, имеют больше точек данных для лучшего изучения.

Модель множественной линейной регрессии для прогнозирования цены листинга

Цель: прогнозировать цену нового объявления, а также оценивать влияние отдельных факторов на цену объявления.

Выбранная модель: с числовой целевой переменной (Цена) и различными предикторами (категориальными и числовыми) была выбрана множественная линейная регрессия. С помощью модели MLR можно найти коэффициенты для каждого из предикторов, чтобы оценить влияние каждого из этих предикторов на окончательную цену. Его также можно использовать для прогнозирования цены нового наблюдения на основе предыдущих наблюдений, что поможет новым листингерам понять, как установить конкурентоспособную цену на свой листинг, отвечая обоим аспектам намеченной цели.

Целевая переменная: цена (долл. США)

Предикторы. На основе визуализаций, упомянутых выше, и результатов модели случайного леса для цены были выбраны предикторы для модели, которые сильно коррелируют с ценой. Это включало: почтовый индекс, тип собственности, тип комнаты, размещение, ванные комнаты, спальни, кровати, тип кровати и удобства.

Метод. Модель была запущена с этими предикторами, и было получено значение R-квадрата 0,4569, а при проверке на проверочных данных было достигнуто среднеквадратичное отклонение 100,6401. Однако, стремясь к уровню значимости для значения R-квадрата 0,7, модель была переобучена, чтобы улучшить соответствие обучающим данным. Чтобы улучшить модель, из набора данных были удалены наблюдения, которые содержали почтовый индекс, который использовался менее чем в 50 других наблюдениях. Затем, из-за большого разброса ценовых данных, ценовые данные были нормализованы, и был взят логарифм цены. Также из списка предикторов были удалены некоторые удобства, не связанные с ценой. Это привело к улучшенному значению R-квадрата 0,7208, а при тестировании с проверочными данными - к среднеквадратичному отклонению 0,3491, оба показателя производительности показали значительное улучшение.

Результаты. Модель достигла значения R-квадрата 0,7207 при скорректированном значении R-квадрата 0,7187 в наборе обучающих данных. При запуске набора данных проверки полученный результат был следующим:

Когда прогнозируемые значения были нанесены на график по сравнению с наблюдаемыми значениями, было замечено, что большинство точек данных лежало рядом с линией, что означает, что прогнозируемые значения были линейно близки к наблюдаемым значениям. Однако было замечено, что были определенные точки, которые не попадали близко к линии, и, следовательно, это показывает, что модель можно улучшить.

Бизнес-аналитика. Из этой модели можно узнать цену новых объявлений, чтобы помочь новым листингерам Airbnb в процессе настройки. Кроме того, на основе коэффициентов предикторов в уравнении регрессионной модели были найдены факторы, которые относительно влияют на повышение цены, что было бы полезно как для существующих, так и для новых листингеров. Три основных удобства и рост цен, вызванный включением этих удобств в список, были следующими:

1. Ванна с душевой кабиной: $7,17.

2. Парковочное место для инвалидов: 3,55 доллара США.

3. Стиральная машина с сушкой: 2,07 доллара США.

Улучшения

  1. Более новые данные — данные в этом наборе данных относятся к 2017 году и, следовательно, не отражают картину текущего рынка.
  2. Больше данных — некоторые почтовые индексы не содержали достаточно данных для построения надежной модели.
  3. Смещение — набор данных содержит больше данных о Калифорнии и Нью-Йорке и, следовательно, будет лучше работать при прогнозировании информации о ценах в этих штатах.
  4. Ансамблевое обучение — путем создания случайного леса или внедрения таких алгоритмов, как повышение градиента, AdaBoost и т. д., мы считаем, что точность модели можно повысить, и сейчас мы работаем над этим.
library(ggplot2)
airbnb<-read.csv('USAirbnb.csv',stringsAsFactors=TRUE)
airbnb<- subset(airbnb, select = -c(X) )
#cancel<-read.csv('Cancel.csv',stringsAsFactors = TRUE)
airbnb$State = toupper(airbnb$State)
count(airbnb,'State')
#Correlations
cor(as.numeric(airbnb$MinimumNights), airbnb$Price)
#Classification process
library(dplyr)

#high correlation
selected.var <- c(21, 28, 29, 30, 31, 32, 33, 34, 36,42, 44:47,50:54,56:61,65,68,76,78:82, 93,97:99, 101,102,105,109, 114:117,120:122,127,133,135,138,140,144,145,149,150,151)
#selected.var of things that can change
selected.var <- c(34,44:151)
#amenities
selected.var<- c(44:151)
#All the data
selected.df <- airbnbonlyreview[, selected.var]
set.seed(100)
train.index <- sample(1:nrow(selected.df), nrow(selected.df)*0.6)
# Build training and validation set by indexing
train.df <- selected.df[train.index, ]
valid.df <- selected.df[-train.index, ]
# if not installed, run:
# install.packages(“rpart”)
library(rpart)
# if not installed, run:
# install.packages(“rpart.plot”)
library(rpart.plot)
default.ct <- rpart(Review ~ ., data = train.df, method = "class",control = rpart.control(maxdepth =10, minbucket =  10))
## plot tree
rpart.plot(default.ct, extra = 1)
#Predict
default.ct.point.pred <- predict(default.ct, valid.df, type = "class")
confusionMatrix(default.ct.point.pred, factor(valid.df$Review))
##full tree
full.ct <- rpart(Review ~ ., data = train.df, method = "class", control = rpart.control(cp = -1, minsplit = 1))
##plot full tree
rpart.plot(full.ct,extra=1)
library(caret)
count(train.df,'Review')
count(valid.df,'Review')

#Label Encoding
library(CatEncoders)
labs = LabelEncoder.fit(airbnb$PropertyType)
airbnb$PropertyType = transform(labs, airbnb$PropertyType)
labs2 = LabelEncoder.fit(airbnb$RoomType)
airbnb$RoomType = transform(labs2, airbnb$RoomType)
labs3 = LabelEncoder.fit(airbnb$BedType)
airbnb$BedType = transform(labs3, airbnb$BedType)
labs4 = LabelEncoder.fit(airbnb$Zipcode)
airbnb$Zipcode = transform(labs4, airbnb$Zipcode)
#Modelling
count(airbnb,'State')
airbnb$BedType<-as.numeric(as.character(airbnb$BedType))
#68,76, 93,140
selected.var <- c(21, 28, 29, 30, 31, 32, 33, 34, 36, 41,42, 44:47,50:54,56:61,65,68,76,78:82, 93,97:99, 101,102,105,109, 114:117,120:122,127,133,135,138,140,144,145,149,150)
selected.var <- c(21, 28, 29, 30, 31, 32, 33, 34, 36, 41,42, 44:150) #current
#amenities
selected.var<- c(44:150)
#All the data
selected.df <- airbnb.norm[, selected.var]

#Cali data
selected.var <- c(21, 28, 29, 30, 31, 32, 33, 34, 36, 41,42, 44:150)
california<-airbnb.norm[airbnb.norm$State=="CA",]
selected.df<-california[,selected.var]
#NY data
newyork<-airbnb[airbnb$State=="NY",]
selected.df<-newyork[,selected.var]
#Normalize price
library(caret)
# compute mean and standard deviation of each column
#norm.values <- preProcess(airbnb, method=c("center", "scale"))
# we perform the transformation/normalization
airbnb.norm$Price<-log(airbnb$Price)
airbnb.norm$Accommodates<-log(airbnb.norm$Accommodates)
airbnb.norm <- airbnb
selected.var <- c(21, 28, 29, 30, 31, 32, 33, 34, 36, 41,42, 44:150)
selected.var <- c(21, 28, 29, 30, 31, 32, 33, 34, 36, 41,42)
set.seed(300) 
selected.df<-airbnb.norm[,selected.var]
train.index <- sample(1:nrow(selected.df), nrow(selected.df)*0.75)  
train.df <- selected.df[train.index, ]
valid.df <- selected.df[-train.index, ]
#str(train.df)
bnb.lm<-lm(Price~., data=train.df)
abc<-summary(bnb.lm)
write.csv("summarybnblm.csv",abc)
#str(selected.df)
set.seed(100) 
train.index <- sample(1:nrow(selected.df), nrow(selected.df)*0.75)  
train.df <- selected.df[train.index, ]
valid.df <- selected.df[-train.index, ]
#str(train.df)
bnb.lm<-lm(Price~., data=train.df)
summary(bnb.lm)
calibnb.lm <- lm(Price~., data = train.df)
summary(calibnb.lm)
newyork.lm<-lm(Price~.,data=train.df)
summary(newyork.lm)
options(scipen = 999)
options(max.print=999999)
summary(bnb.lm)
library(plyr)
count(train.df,'CancellationPolicy')
count(valid.df,'CancellationPolicy')
valid.df<-valid.df[valid.df$CancellationPolicy!="long_term",]
bnb.lm.pred <- predict(bnb.lm, valid.df)
library(forecast)
#  use options() to ensure numbers are not displayed in scientific notation.
options(scipen=999)
# use accuracy() to compute common accuracy measures.
accuracy(bnb.lm.pred, valid.df$Price)
plot(bnb.lm.pred,valid.df$Price)
# Classification tree for cali data
selected.var<- c(44:151)
california<-airbnbonlyreview[airbnbonlyreview$State=="CA",]
selected.df<-california[,selected.var]
set.seed(100) 
train.index <- sample(1:nrow(selected.df), nrow(selected.df)*0.6)  
train.df <- selected.df[train.index, ]
valid.df <- selected.df[-train.index, ]
default.ct <- rpart(Review ~ ., data = train.df, method = "class",control =0)
rpart.plot(default.ct, extra = 1)
default.ct.point.pred <- predict(default.ct, valid.df, type = "class")
confusionMatrix(default.ct.point.pred, factor(valid.df$Review))

Дека слайдов

Использованная литература:

Набор данных — https://data.opendatasoft.com/explore/dataset/airbnb-listings%40public/table/?disjunctive.host_verifications&disjunctive.amenities&disjunctive.features