[PYTHON] J'ai analysé les données Airbnb pour ceux qui veulent rester à Amsterdam

Voulez-vous rester à Amsterdam?

Amsterdam, la capitale des Pays-Bas, est une destination touristique très connue avec un très beau paysage urbain. C'est une ville avec de nombreux canaux caractéristiques en Europe, et elle est connue comme un lieu touristique où trop de touristes deviennent un problème. netherlands-happiest-coutries-2018-super-169.jpg

Airbnb Airbnb est un célèbre service d'hébergement privé. Airbnb vient d'Air bed and Bed & Breakfast. C'est un service qui aurait commencé lorsque Brian Chesky a loué son loft de temps en temps. C'est l'hébergement principal à l'étranger.

Objectif

Le but est de comprendre la situation d'Airbnb lorsque les touristes d'Amsterdam essaient de rester chez Airbnb. Cette fois, j'ai analysé les données d'hébergement Airbnb à Amsterdam pour découvrir quelles sont les caractéristiques et quelles variables affectent le prix des hébergements Airbnb.

Données cibles

[Inside Airbnb -Adding data to the debate] http://insideairbnb.com/get-the-data.html Inside Airbnb est un site qui fournit des données réelles sur Airbnb. Il fournit des données très bien organisées au format csv, de sorte que même les débutants comme moi peuvent facilement les analyser.

référence

https://towardsdatascience.com/exploring-machine-learning-for-airbnb-listings-in-toronto-efdbdeba2644 https://note.com/ryohei55/n/n56f723bc3f90

Analyse des données de séries chronologiques

calendar = pd.read_csv('calendar.csv')
print(calendar.date.nunique(), 'days', calendar.listing_id.nunique(), 'unique listings')

366 days 20025 unique listings Les données vont du 2020-12-08 au 2020-12-06, mais pour une raison quelconque, il y a une légère erreur de 366 jours, mais pour autant que je puisse voir les données, il ne semble y avoir aucun problème, je vais donc continuer. Il y a 20025 annonces, et je suis reconnaissant pour la grande quantité de données.

calendar.head(5)

Screenshot 2019-12-27 at 17.21.52.png

Puis-je faire une réservation?

J'ai essayé de représenter graphiquement la quantité d'Airbnb déjà réservée et la quantité d'espace disponible par ordre chronologique.

calendar_new = calendar[['date', 'available']]
calendar_new['busy'] = calendar_new.available.map( lambda x:0 if x == 't'  else 1)
calendar_new = calendar_new.groupby('date')['busy'].mean().reset_index()
calendar_new['date'] = pd.to_datetime(calendar_new['date'])

plt.figure(figsize=(10, 5))
plt.plot(calendar_new['date'], calendar_new['busy'])
plt.title('Airbnb Amsterdam Calendar')
plt.ylabel('Busy %')
plt.show()

download (12).png ** Considération ** Dans l'ensemble, le taux d'occupation est supérieur à 80%, on peut donc reconnaître qu'airbnb à Amsterdam est bondé toute l'année. Il y a beaucoup de monde au cours de l'année. Cela peut être dû à l'influence des touristes qui viennent voir des feux d'artifice au cours de l'année.

Le taux de congestion augmentera après mars. Une hausse soudaine similaire est observée en juin. Cependant, on considère que ces hausses sont dues au fait que l'hôte airbnb n'a pas libéré la chambre car les réservations un peu éloignées de l'heure actuelle ne peuvent pas être décidées car l'horaire de l'hôte n'a pas été décidé.

Comparaison des prix mensuels

calendar['date'] = pd.to_datetime(calendar['date'])
calendar['price'] = calendar['price'].str.replace('$', '')
calendar['price'] = calendar['price'].str.replace(',', '')
calendar['price'] = calendar['price'].astype(float)
calendar['date'] = pd.to_datetime(calendar['date'])

mean_of_month = calendar.groupby(calendar['date'].dt.strftime('%B'), sort=False)['price'].mean()

mean_of_month.plot(kind = 'barh', figsize=(12, 7))
plt.xlabel('Average Monthly Price')

download (13).png ** Considération ** Le prix moyen d'airbnb à Amsterdam tout au long de l'année est d'environ 160 euros (18000 ¥) par nuit. J'ai l'impression que janvier et février seront un peu moins chers si vous dites que c'est fort.

Prix par jour

calendar['dayofweek'] = calendar.date.dt.weekday_name
cats = [ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
price_week = calendar[['dayofweek', 'price']]
price_week = calendar.groupby(['dayofweek']).mean().reindex(cats)
price_week.drop(['listing_id','maximum_nights', 'minimum_nights'], axis=1, inplace=True)
price_week.plot(grid=True)

ticks = list(range(0,7,1))
labels = "Mon Tues Weds Thurs Fri Sat Sun".split()
plt.xticks(ticks, labels)![download (14).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505543/155809c6-0f06-2623-2d6e-78405d07ab30.png)

download (14).png ** Considération ** Du lundi au jeudi, le prix moyen est inférieur à 170 euros, mais en séjournant du vendredi au samedi, le prix est extrêmement élevé. On pense que la demande pour airbnb est biaisée le week-end, car les écoles et les entreprises se rendent les vendredis et samedis lorsqu'ils sont fermés.

Analyse des données de liste

Airbnb Contient des données sur chaque hébergement.

listings = pd.read_csv('listings.csv')
print('We have', listings.id.nunique(), 'listings in the listing data.')
listings.head(5)

Screenshot 2019-12-27 at 17.21.52.png Ça ressemble à ça.

Où sont les hébergements TOP10

listings.groupby(by = 'neighbourhood_cleansed').count()[['id']].sort_values(by='id', ascending=False).head(10)

Screenshot 2019-12-27 at 18.07.21.png

Répartition des prix

listings.loc[(listings.price <= 1000) & (listings.price > 0)].price.hist(bins=200)
plt.ylabel('Count')
plt.xlabel('Listing price in EUR')
plt.title('Histogram of listing prices')

download (15).png La distribution des prix est comme ça.

Boîte de prix moustaches par région

select_neighbourhood_over_100 = listings.loc[(listings.price <= 1000) & (listings.price > 0)].groupby('neighbourhood_cleansed')\
.filter(lambda x: len(x)>=100)["neighbourhood_cleansed"].values

listings_neighbourhood_over_100 = listings.loc[listings['neighbourhood_cleansed'].map(lambda x: x in select_neighbourhood_over_100)]

sort_price = listings_neighbourhood_over_100.loc[(listings_neighbourhood_over_100.price <= 1000) & (listings_neighbourhood_over_100.price > 0)]\
.groupby('neighbourhood_cleansed')['price'].median().sort_values(ascending=False).index

sns.boxplot(y='price', x='neighbourhood_cleansed', data=listings_neighbourhood_over_100.loc[(listings_neighbourhood_over_100.price <= 1000) & (listings_neighbourhood_over_100.price > 0)],
            order=sort_price)

ax = plt.gca()
ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha='right')
plt.show()

download (16).png ** Considération ** Comme vous pouvez le voir depuis Centrum-West Centrum-Oost, les prix près de la gare centrale sont extrêmement élevés. On peut dire que la fourchette de prix la moins chère est d'aller dans un quartier comme Bijnmer qui prend environ 30 minutes en tram. En gros, il semble que le prix d'Airbnb autour de lui soit déterminé par la distance de la gare centrale. ![xxamsterdam-train-stations-map.jpg.pagespeed.ic.POsCpucKFr.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505543/2a9486e8-df14 -64f2-c508-7e172c11656b.jpeg)

Diagramme barbe de boîte de prix pour chaque type d'hébergement

select_property_over_100 = listings.loc[(listings.price <= 1000) & (listings.price > 0)].groupby('property_type')\
.filter(lambda x:len(x) >=20)["property_type"].values

listings_property_over_100 = listings.loc[listings["property_type"].map(lambda x: x in select_property_over_100)]

sort_price = listings_property_over_100.loc[(listings_property_over_100.price <= 1000) & (listings_property_over_100.price >0)]\
.groupby('property_type')['price'].median().sort_values(ascending=False).index

sns.boxplot(y='price', x ='property_type', data=listings_property_over_100.loc[(listings_property_over_100.price <= 1000) & (listings_property_over_100.price >0)],
           order = sort_price)

ax = plt.gca()
ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha='right')
plt.show()

download (17).png ** Considération ** Tout d'abord, le diagramme des moustaches de la boîte montre la variation des données, la ligne centrale pointe vers la valeur centrale, la ligne sombre en dessous est le premier quadrant et la ligne sombre au-dessus est le troisième quadrant. C'est un nombre. Une auberge de jeunesse est un établissement d'hébergement où vous pouvez séjourner à un prix avantageux, ce qui est courant en Europe. Cependant, bien que bon marché, même si elle est classée comme une auberge, il semble qu'il y en ait beaucoup à Amsterdam qui coûtent 1000 EUR. Cependant, il faut tenir compte du fait que 1000 EUR ou plus sont exclus cette fois-ci comme valeur aberrante.

Les données pour l'hôtel varient également. Probablement parce que certains hôtels ont un goût haut de gamme. Cependant, comme la valeur médiane elle-même est d'environ 180 EUR, airbnb classé comme hôtel semble être essentiellement une classification bon marché.

Graphique des prix par type de chambre

listings.loc[(listings.price <= 1000) & (listings.price > 0)].pivot(columns='room_type', values='price').plot.hist(stacked=True, bins=100)
plt.xlabel('Listing Price in EUR')

download (18).png ** Considération ** Tout d'abord, vous remarquerez qu'il y a peu de chambres partagées et de chambres d'hôtel. Vous pouvez louer toute la maison / l'appartement ou ne louer que la chambre. Et la plupart d'entre eux semblent être loués pour chaque maison / appartement. Si vous souhaitez le rendre moins cher, il semble plus efficace de limiter votre recherche aux chambres privées. Dans le cas de la location de toute la maison / appartement, il est naturel que seule la pièce soit plus chère que la location.

Graphique du nombre de commodités

pd.Series(np.concatenate(listings['amenities'].map(lambda amns: amns.split(",")))).value_counts().head(20).plot(kind='bar')
ax = plt.gca()
ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha='right', fontsize=12)
plt.show()

download (19).png ** Considération ** Il y a beaucoup de Wifi. Il fait froid en hiver aux Pays-Bas, et la plupart d'entre eux sont équipés de chauffage. Il y a de nombreux endroits où il n'y a pas d'équipements tels que des sèche-shampoings en fer, vous devrez donc vérifier un peu.

Famille et enfants, c'est un peu ... mais je ne veux pas être gêné par airbnb, c'est donc considéré comme un avantage et demain. Vous pouvez également voir que le parking gratuit n'est pas dans le haut, alors soyez prudent lorsque vous venez en voiture.

Relation entre prix et commodités

amenities = np.unique(np.concatenate(listings['amenities'].map(lambda amns: amns.split(","))))
amenity_prices = [(amn, listings[listings['amenities'].map(lambda amns: amn in amns)]['price'].mean()) for amn in amenities if amn != ""]
amenity_srs = pd.Series(data=[a[1] for a in amenity_prices], index=[a[0] for a in amenity_prices])

amenity_srs.sort_values(ascending=False)[:20].plot(kind='bar')
ax = plt.gca()
ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha='right', fontsize=12)
plt.show()

download (20).png

** Considération ** Je ne sais pas si la laveuse / sécheuse est la plus liée au prix ... Cependant, il convient aux événements typiques d'Amsterdam. De nombreux événements ont lieu à Amsterdam. Il semble que les salles qui permettent d'assister facilement à l'événement et qui sont au bon endroit ont tendance à être chères. À part ces deux-là, la relation est presque uniforme.

Relation entre le nombre de lits et le prix


listings.loc[(listings.price <= 1000)&(listings.price > 0)].pivot(columns = 'beds', values='price').plot.hist(stacked=True, bins=100)
plt.xlabel('Listing price in EUR')

download (21).png ** Considération ** Surtout un ou deux lits. Est-ce le résultat que vous avez imaginé? Au fait, 32 lits! ?? J'ai pensé, alors j'ai essayé. https://www.airbnb.jp/rooms/779175?source_impression_id=p3_1577402659_vntGlW7Yj5I5pX4U C'était une histoire que ce ferry ait 32 lits. Je suis surpris.

Visualisez les relations entre les équipements avec une carte thermique

col = ['host_listings_count', 'accommodates', 'bedrooms', 'price', 'number_of_reviews', 'review_scores_rating']
corr = listings.loc[(listings.price<=1000)&(listings.price > 0)][col].dropna().corr()
plt.figure(figsize=(6,6))
sns.set(font_scale=1)
sns.heatmap(corr, cbar=True, annot=True, square=True, fmt='.2f', xticklabels=col, yticklabels=col)
plt.show()

** Considération ** Il s'agit d'une carte thermique qui permet de voir facilement chaque corrélation dans les données des listes par couleur. Mais seulement cette fois, il n'y a pas de corrélation dans la plupart des régions. Cependant, il existe une forte corrélation entre les chambres et l'hébergement. Puisqu'il s'agit du nombre de personnes qui peuvent rester et du nombre de lits, il est compréhensible qu'il y ait une corrélation. Cependant, une telle chose qui détermine le nombre de logements par le nombre de lits est considérée comme une pseudo-corrélation car le nombre d'invités est artificiellement déterminé comme le nombre de lits plutôt que d'avoir une corrélation.

Prédire le prix à l'aide de l'arbre de décision

Ce qui suit est la préparation des données. Les données sont transformées en une variable factice.


from sklearn.feature_extraction.text import CountVectorizer

count_vectorizer = CountVectorizer(tokenizer=lambda x:x.split(','))
amenities = count_vectorizer.fit_transform(listings['amenities'])
df_amenities = pd.DataFrame(amenities.toarray(), columns=count_vectorizer.get_feature_names())
df_amenities = df_amenities.drop('', 1)

columns = ['host_is_superhost', 'host_identity_verified', 'host_has_profile_pic', 'is_location_exact', 'requires_license', 'instant_bookable', 'require_guest_profile_picture', 'require_guest_phone_verification']
for c in columns:
    listings[c] = listings[c].replace('f',0,regex=True)
    listings[c] = listings[c].replace('t',1,regex=True)

listings['security_deposit'] = listings['security_deposit'].fillna(value=0)
listings['security_deposit'] = listings['security_deposit'].replace('[\$,]', '', regex=True).astype(float)
listings['cleaning_fee'] = listings['cleaning_fee'].fillna(value=0)
listings['cleaning_fee'] = listings['cleaning_fee'].replace('[\$,]', '', regex=True).astype(float)

listings_new = listings[['host_is_superhost', 'host_identity_verified', 'host_has_profile_pic','is_location_exact', 
                         'requires_license', 'instant_bookable', 'require_guest_profile_picture', 
                         'require_guest_phone_verification', 'security_deposit', 'cleaning_fee', 
                         'host_listings_count', 'host_total_listings_count', 'minimum_nights',
                     'bathrooms', 'bedrooms', 'guests_included', 'number_of_reviews','review_scores_rating', 'price']]

for col in listings_new.columns[listings_new.isnull().any()]:
    listings_new[col] = listings_new[col].fillna(listings_new[col].median())

for cat_feature in ['zipcode', 'property_type', 'room_type', 'cancellation_policy', 'neighbourhood_cleansed', 'bed_type']:
    listings_new = pd.concat([listings_new, pd.get_dummies(listings[cat_feature])], axis=1)

listings_new = pd.concat([listings_new, df_amenities], axis=1, join='inner')

Nous utiliserons RandomForestRegressor.


from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error
from sklearn.ensemble import RandomForestRegressor

y = listings_new['price']
x = listings_new.drop('price', axis=1)
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.25, random_state=123)
rf = RandomForestRegressor(n_estimators=500, random_state=123, n_jobs=-1)
rf.fit(X_train, y_train)
y_train_pred = rf.predict(X_train)
y_test_pred = rf.predict(X_test)
rmse_rf = (mean_squared_error(y_test, y_test_pred))**(1/2)

print('RMSE test: %.3f' % rmse_rf)
print('R^2 test: %.3f' % (r2_score(y_test, y_test_pred)))

RMSE test: 73.245 R^2 test: 0.479 Le résultat ressemble à ceci. C'est 0,479 dans le test R ^ 2, donc c'est assez précis. Pour le moment, regardons quel élément l'arbre de décision a jugé important.

coefs_df = pd.DataFrame()
coefs_df['est_int'] = X_train.columns
coefs_df['coefs'] = rf.feature_importances_
coefs_df.sort_values('coefs', ascending=False).head(20)

Screenshot 2019-12-27 at 19.10.04.png ** Considération ** Vous pouvez voir que le nombre de chambres a un effet significatif sur le prix. De plus, dans airbnb, les frais de nettoyage sont facturés séparément des frais de chambre, mais on peut voir que les frais affectent également le prix. Cela semble avoir un effet assez direct.

Régression au lasso


from sklearn.linear_model import  Lasso
lasso = Lasso()
lasso.fit(X_train, y_train)

#Coefficient de régression
print(lasso.coef_)
#Section(Erreur)
print(lasso.intercept_)
#Coefficient de décision
print(lasso.score(X_test, y_test))

[ 1.85022916e-03 1.31073590e+00 -0.00000000e+00 0.00000000e+00 5.23464952e+00 5.97640655e-01 6.42296851e-01 3.67942959e+01 8.80302532e+00 -3.96520183e-02 8.39294507e-01] -30.055848397234712 0.27054071146797

J'ai également essayé l'analyse de régression multiple, mais je ne pouvais pas beaucoup améliorer la précision. Eh bien, c'est inévitable car il est transformé en une variable factice, n'est-ce pas? droite? ??

Résumé

Je viens d'apprendre l'analyse des données, mais je suis reconnaissant en tant que débutant car l'airbnb à l'intérieur a des données très bien organisées. Je veux analyser comme ça! Il est un peu difficile de trouver des données ouvertes, alors veuillez vous y référer.

Cette fois, il y a beaucoup de parties que je viens de copier, mais je suis content d'avoir pu apprendre ce que je voulais et comment traiter les données.

J'apprécierais n'importe quel conseil!

Recommended Posts

J'ai analysé les données Airbnb pour ceux qui veulent rester à Amsterdam
Référence de référence pour ceux qui veulent coder avec Rhinoceros / Grasshopper
Points ennuyeux pour ceux qui veulent présenter Ansible
Pour ceux qui veulent écrire Python avec vim
Pour ceux qui souhaitent démarrer l'apprentissage automatique avec TensorFlow2
[Pour ceux qui veulent utiliser TPU] J'ai essayé d'utiliser l'API de détection d'objets Tensorflow 2
Créer un environnement Python pour ceux qui veulent devenir des data scientists 2016
Articles en vrac pour ceux qui veulent commencer le traitement du langage naturel
Technique Python pour ceux qui veulent se débarrasser des débutants
Je veux imprimer dans la notation d'inclusion
Je veux intégrer Matplotlib dans PySimpleGUI
Je veux trouver des variations dans diverses statistiques! Recommandation de rééchantillonnage (Bootstrap)
J'ai essayé d'utiliser NVDashboard (pour ceux qui utilisent le GPU dans l'environnement jupyter)
Je veux faire le test de Dunnett en Python
Je veux corriger Datetime.now dans le test de Django
Conseils pour ceux qui ne savent pas comment utiliser is et == en Python
Rejoignez Azure avec Go ~ Pour ceux qui veulent démarrer et connaître Azure avec Go ~
Quoi qu'il en soit, je veux vérifier facilement les données JSON
Je veux frapper 100 sciences des données avec Colaboratory
Je souhaite stocker les informations de la base de données dans la liste
Pour ceux qui veulent apprendre Excel VBA et se lancer avec Python
Je veux fusionner des dictionnaires imbriqués en Python
Points à garder à l'esprit lors de l'utilisation de Python pour ceux qui utilisent MATLAB
5 raisons pour lesquelles le traitement est utile pour ceux qui veulent se lancer avec Python
Je veux obtenir les données de League of Legends ③
Je veux obtenir les données de League of Legends ②
Je veux obtenir les données de League of Legends ①
Une bibliothèque pour la science des données "Je veux faire ça" sur le bloc-notes Jupyter
Je veux afficher la progression en Python!
La première étape pour ceux qui sont amateurs de statistiques mais qui souhaitent implémenter des modèles d'apprentissage automatique en Python
La première étape de l'apprentissage automatique ~ Pour ceux qui veulent essayer l'implémentation avec python ~
Je souhaite utiliser une source de données python dans Re: Dash pour obtenir les résultats de la requête.
Je veux configurer un serveur fictif pour python-flask en quelques secondes en utilisant swagger-codegen.
Je veux juste trouver l'intervalle de confiance à 95% de la différence de ratio de population en Python
Pour ceux qui débutent en programmation mais qui ont décidé d'analyser les données avec Python
Construction d'environnement pour ceux qui veulent étudier Python facilement avec VSCode (pour Mac)
Je veux écrire en Python! (1) Vérification du format de code
Je souhaite intégrer une variable dans une chaîne Python
Je veux facilement implémenter le délai d'expiration en python
Je veux donner un group_id à une trame de données pandas
Je veux faire la transition avec un bouton sur le ballon
Je veux utiliser self avec Backpropagation (tf.custom_gradient) (tensorflow)
Je veux écrire en Python! (2) Écrivons un test
Même avec JavaScript, je veux voir Python `range ()`!
PostgreSQL - Pour vous qui voulez INSÉRER à grande vitesse
Je veux échantillonner au hasard un fichier avec Python
Je veux travailler avec un robot en python.
Je veux écrire en Python! (3) Utiliser des simulacres
Lorsque vous voulez plt.save dans l'instruction for
Je veux dire qu'il y a un prétraitement des données ~
Je veux utiliser le jeu de données R avec python
Je veux faire quelque chose avec Python à la fin
Je veux manipuler des chaînes dans Kotlin comme Python!
Pour ceux qui veulent afficher les images côte à côte dès que possible avec matplotlib de Python
J'étais en charge de la maintenance du script Fabric, mais je ne sais pas.> <À ceux qui
[TensorFlow] Je souhaite maîtriser l'indexation pour Ragged Tensor
Pour ceux qui ont du mal à dessiner des graphiques avec python
Je veux échanger des cadeaux même pour moi! [Christmas Hackason]
Je veux déplacer le sélénium pour le moment [pour mac]
Je veux pouvoir analyser des données avec Python (partie 1)
[NetworkX] Je souhaite rechercher des nœuds avec des attributs spécifiques