AirBnb: Customized Decision Tree and Recommendation Algorithm

Guangwei Ren
Data Mining the City
4 min readNov 10, 2019

AirBnb is an online marketing for arranging homestays during a trip. However, the main interaction on the web page is through the price as the symbol showing each location. A lot of tourists don’t put the consideration of cost as first priority. So this proposal is to bring up a new interactive system for users to customize their own priority for choosing a place to stay overnight and the evaluation for level of recommendation is based on this.

The web page of AirBnb when exploring the stays

The system diagram for the new recommendation system is composed by this:

I want to have a trip.

Considering money, location, space and service,

How can I customize the recommendation?

Factors in Priority

These four decision elements all have other detailed choice, either to have a parameter affecting the recommendation level or give a threshold value that excludes the choices users don’t want.

Division of Factors

In the actual UI system, the user can drag the bars to prioritize their choices. And the detailed divisions have checkbox that tell the user if he/she want this condition. The recommendation level is shown by the brightness and saturation of agents. Also when some choices are highly recommended, there will be a text box shows the detailed information (price, occupancy and review) to the user.

Below are the three gifs recording how the decision tree influences the result of recommendation. First gif is about the single element of influence. Second is telling how the combination of different powers affect the result. The last one shows what happens when changing the priority in decision tree.

Influence of Single Factor
Combination of Different Factors
Influence of Priority

Code Snippet:

using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;public class AirbnbScript : MonoBehaviour{static private List<float> ScoresHolder=new List<float>();public float Price;public int HoldGuests;public float StarNo;private float ToTarget=10000000;private float ToStation=10000000;static private float HighestScore=0;private bool IsExcluded=false;private float MyScore=0;GameObject Info;Canvas InfoBar;Text myText;private int MyCode;void Start(){CalculateDistance();if(!CheckValidity()){Object.Destroy(this);Debug.Log(“An Invalid Agent Detected!”);}ScoresHolder.Add(MyScore);MyCode=ScoresHolder.Count-1;Info=new GameObject(“Information”);InfoBar=Info.AddComponent<Canvas>();InfoBar.renderMode=RenderMode.WorldSpace;InfoBar.referencePixelsPerUnit=1;Info.transform.position=this.transform.position;Info.transform.rotation=this.transform.rotation;Info.transform.Rotate(90.0f,0,0);RectTransform Z=InfoBar.GetComponent<RectTransform>();Z.sizeDelta=new Vector2(100,50);Info.transform.position=this.transform.position+new Vector3(0,0.5f,18f);myText = Info.AddComponent<Text>();myText.transform.localScale=new Vector3(0.5f,0.5f,0.5f);myText.fontSize=14;myText.color=Color.white;myText.alignment=TextAnchor.MiddleCenter;myText.font=Resources.GetBuiltinResource(typeof(Font), “Arial.ttf”) as Font;}void CalculateDistance(){GameObject Target=GameObject.FindGameObjectWithTag(“Target”);ToTarget=Vector3.Magnitude(this.transform.position-Target.transform.position);GameObject[] Stations=GameObject.FindGameObjectsWithTag(“ToStation”);for(int i=0;i<Stations.Length;i++){if(Vector3.Magnitude(this.transform.position-Stations[i].transform.position)<ToStation){ToStation=Vector3.Magnitude(this.transform.position-Stations[i].transform.position);}}}bool CheckValidity(){if(Price<=0||HoldGuests>10||HoldGuests<=0||StarNo>5||StarNo<0||ToTarget<0||ToStation<0)return false;return true;}private void Update(){MyScore=GetLocationScore()+GetMoneyScore()+GetSpaceScore()+GetServiceScore();if(IsExcluded)MyScore=0;ScoresHolder[MyCode]=MyScore;//Debug.Log(MyScore);HighestScore=0;for(int i=0;i<ScoresHolder.Count;i++){if(ScoresHolder[i]>HighestScore)HighestScore=ScoresHolder[i];}ShadeTheAgent();if(MyScore/HighestScore>0.9f){if(myText.text==””){myText.text = “$”+Price+”\n”+HoldGuests+” Guests”+”\n”+StarNo+” ※”;}}else{myText.text=””;}}void ShadeTheAgent(){if(HighestScore>0){float x=MyScore/HighestScore;{this.gameObject.GetComponent<Renderer>().material.color=new Color(x*x*x*1f,x*x*x/4,x*x*x*0.6f,1);this.gameObject.GetComponentInChildren<Light>().color=new Color(x*x*x*1f,x*x*x/2,x*x*x*0.8f,1);this.gameObject.GetComponentInChildren<Light>().intensity=x*x*55;this.gameObject.GetComponentInChildren<Light>().range=x*x*17;}}else{this.gameObject.GetComponent<Renderer>().material.color=new Color(0,0,0,1);this.gameObject.GetComponentInChildren<Light>().color=new Color(0,0,0,1);this.gameObject.GetComponentInChildren<Light>().intensity=0;}}float GetLocationScore(){float parameter=0.0f;if(GameObject.Find(“Iv4”).transform.position.y==980){parameter=10.0f;}if(GameObject.Find(“Iv4”).transform.position.y==860){parameter=6.0f;}if(GameObject.Find(“Iv4”).transform.position.y==740){parameter=3.0f;}if(GameObject.Find(“Iv4”).transform.position.y==620){parameter=1.0f;}float PartScore=0;GameObject Downtown, Station;Toggle DowntownIsOn, StationIsOn;Downtown=GameObject.Find(“Downtown”);Station=GameObject.Find(“Subway”);DowntownIsOn=Downtown.GetComponent<Toggle>();StationIsOn=Station.GetComponent<Toggle>();if(DowntownIsOn.isOn){PartScore+=Mathf.Sqrt(1/ToTarget)*10;}if(StationIsOn.isOn){PartScore+=Mathf.Sqrt(1/ToStation)*5;}return PartScore*parameter;}float GetMoneyScore(){float parameter=0.0f;if(GameObject.Find(“Iv3”).transform.position.y==980){parameter=16.0f;}if(GameObject.Find(“Iv3”).transform.position.y==860){parameter=9.0f;}if(GameObject.Find(“Iv3”).transform.position.y==740){parameter=4.0f;}if(GameObject.Find(“Iv3”).transform.position.y==620){parameter=1.0f;}float PartScore=0;GameObject Cheap, Value;Toggle CheapIsOn, ValueIsOn;Cheap=GameObject.Find(“Cheap”);Value=GameObject.Find(“Value”);CheapIsOn=Cheap.GetComponent<Toggle>();ValueIsOn=Value.GetComponent<Toggle>();if(CheapIsOn.isOn){PartScore+=Mathf.Sqrt(10/Price);}if(ValueIsOn.isOn){InputField input;input=GameObject.Find(“MoneyBar”).GetComponent<InputField>();float Bar = float.Parse(input.text);if(Price>=Bar)IsExcluded=true;elseIsExcluded=false;}elseIsExcluded=IsExcluded||false;return PartScore*parameter;}float GetSpaceScore(){float parameter=0.0f;if(GameObject.Find(“Iv2”).transform.position.y==980){parameter=16.0f;}if(GameObject.Find(“Iv2”).transform.position.y==860){parameter=9.0f;}if(GameObject.Find(“Iv2”).transform.position.y==740){parameter=4.0f;}if(GameObject.Find(“Iv2”).transform.position.y==620){parameter=1.0f;}float PartScore=0;GameObject Large, Guests;Toggle LargeIsOn, GuestsIsOn;Large=GameObject.Find(“Large”);Guests=GameObject.Find(“Guests”);LargeIsOn=Large.GetComponent<Toggle>();GuestsIsOn=Guests.GetComponent<Toggle>();if(LargeIsOn.isOn){float guests=HoldGuests;PartScore+=Mathf.Sqrt(guests/10);}if(GuestsIsOn.isOn){InputField input;input=GameObject.Find(“GuestBar”).GetComponent<InputField>();int Bar = int.Parse(input.text);if(HoldGuests<Bar)IsExcluded=true;elseIsExcluded=false;}elseIsExcluded=IsExcluded||false;return PartScore*parameter;}float GetServiceScore(){float parameter=0.0f;if(GameObject.Find(“Iv1”).transform.position.y==980){parameter=16.0f;}if(GameObject.Find(“Iv1”).transform.position.y==860){parameter=9.0f;}if(GameObject.Find(“Iv1”).transform.position.y==740){parameter=4.0f;}if(GameObject.Find(“Iv1”).transform.position.y==620){parameter=1.0f;}float PartScore=0;GameObject Star, Rating;Toggle StarIsOn, RatingIsOn;Star=GameObject.Find(“Star”);Rating=GameObject.Find(“Rating”);StarIsOn=Star.GetComponent<Toggle>();RatingIsOn=Rating.GetComponent<Toggle>();if(StarIsOn.isOn){PartScore+=StarNo/5;}if(RatingIsOn.isOn){InputField input;input=GameObject.Find(“RatingBar”).GetComponent<InputField>();float Bar = float.Parse(input.text);if(StarNo<Bar)IsExcluded=true;elseIsExcluded=false;}elseIsExcluded=IsExcluded||false;return PartScore*parameter;}}

--

--