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.
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.
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.
[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.
https://towardsdatascience.com/exploring-machine-learning-for-airbnb-listings-in-toronto-efdbdeba2644 https://note.com/ryohei55/n/n56f723bc3f90
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)
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()
** 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é.
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')
** 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.
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)
** 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.
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)
Ça ressemble à ça.
listings.groupby(by = 'neighbourhood_cleansed').count()[['id']].sort_values(by='id', ascending=False).head(10)
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')
La distribution des prix est comme ça.
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()
** 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)
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()
** 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é.
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')
** 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.
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()
** 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.
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()
** 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.
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')
** 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.
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.
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)
** 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.
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? ??
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!