Get category of a word with WordNet in the NLTK package

WordNet is a copus reader in the NLTK package. Though the main usage of this method is to find similarity between words and find synonyms, it can help to find a general group of noun and verb because it categorises them into a general group. The examples of the group are noun that is animal, noun that is food, verb about feeling, etc. More group can be found at https://wordnet.princeton.edu/documentation/lexnames5wn.

For declaration, I use Python 3.7.3. The Jupyter notebook with the same content can be found here.

# Import
from nltk.corpus import wordnet as wn

Word can be found in WordNet by using synsets.

word_set = wn.synsets("officer")
word_set

The definition and group of each word from synsets can be obtained as follow.

# Get name, definition and group
for i in word_set:
    print("Name: " + i.name() + "\n" 
          + "Definition: " + i.definition() + "\n"
          + "Group: " + i.lexname() + "\n")

Be careful that some of the words might be a specific noun, such as the word teach that look like it is a verb, but it could be a noun (as the name of the pirate Teach).

word_set2 = wn.synsets("teach")
for i in word_set2:
    print(i.lexname())

word_set2[0].definition()

References

lexnames(5WN) | WordNet. (2021). Retrieved from https://wordnet.princeton.edu/documentation/lexnames5wn
Python Programming Tutorials. (2021). Retrieved from https://pythonprogramming.net/wordnet-nltk-tutorial/
Question How to find the “lexical file” in Wordnet?. (2021). Retrieved from https://www.titanwolf.org/Network/q/5e8d94e2-8dd0-49e3-9aa1-941b8677beda/y
user1850980. (2014). How to find the “lexical file” in Wordnet?. Retrieved from https://stackoverflow.com/questions/6681348/how-to-find-the-lexical-file-in-wordnet/24630887#24630887
wninput(5WN) | WordNet. (2021). Retrieved from https://wordnet.princeton.edu/documentation/wninput5wn
WordNet Interface. (2021). Retrieved from https://www.nltk.org/howto/wordnet.html

Visualisation of the temperature in my room

This personal project aims to learn to use a temperature sensor on Raspberry Pi and conduct the exploratory on the data obtained from the sensor.

I used Raspberry Pi 3 connected with a digital thermometer (model DS18B20) to measure temperature in my room every 10 minutes. The code for recording the temperature can be found here. The recorded data is in CSV format. The Jupyter notebook version of this report can be found here.

According to all collected data from 16 September 2020, 16:33 to 22 December 2020, 14:09, the average temperature in my room is 23.85 °C. The minimum temperature is 17.44 °C and the maximum is 30.56 °C.
For the selection of the most suitable level of granularity for visualising daily temperature, multiple levels of granularity were visualised and compared. The result is to aggregation data into an average of 1 hour.
Moreover, The room maximum and minimum temperature show linear correlations to the outside temperature.

Data preparation

The temperature data was recorded in multiple CSV files, the files will be read and join into a dataframe. It consists of three columns, date, time, and temperature. The temperature column will be converted into numeric. The date and time columns will be merge and convert into datetime type. Note that it will be separated as date and time again for visualisation purpose as seaborn does not accept datetime data type for axis.

First, import the necessary packages.

# Import
import os
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from scipy import stats  # for finding corelation between outside and room temp
import matplotlib.patches as mpatches  # for create custom legend

Then,

# List of dataframe
temp_file_list = []

# Read the temperature files
for file in os.listdir("temp_record/"):
    if file.endswith(".txt"):
        record = pd.read_csv("temp_record/"+file,  
                             header=None, 
                             names=["date", "time", "temperature"])
        temp_file_list.append(record)

# Concat all files in list into a dataframe
temp_df = pd.concat(temp_file_list, axis=0)

# Convert string into float
temp_df["temperature"] = pd.to_numeric(temp_df["temperature"], errors="coerce")

# Remove null row
temp_df.dropna(inplace=True)

# Create datetime column
dt_df = temp_df.copy()
dt_df["datetime"] = temp_df["date"]+" "+temp_df["time"]
dt_df.drop(["date", "time"], axis=1, inplace=True)
dt_df["datetime"] = pd.to_datetime(dt_df["datetime"])
dt_df.head()
temperaturedatetime
024.6872020-09-16 16:33:20.677699
124.6872020-09-16 16:43:21.680049
224.5002020-09-16 16:53:22.634034
324.3752020-09-16 17:03:23.566841
424.3122020-09-16 17:13:24.600617
dt_df.describe(datetime_is_numeric=True)
temperaturedatetime
count13749.00000013749
mean23.8512442020-11-04 08:38:18.934868736
min17.4370002020-09-16 16:33:20.677699
25%22.4370002020-10-10 20:53:16.890990080
50%23.8120002020-11-04 18:34:50.884818944
75%25.0620002020-11-28 16:22:05.646606080
max30.5620002020-12-22 14:09:02.517132
std2.093345NaN

EDA on daily temperature graph

The example of my room daily temperature

Because the temperature was collected every 10 minutes which has higher detail than required as it can be seen from the example graph of room temperature on 17 September 2020 (Fig. 1). The interesting point of the graph is the lowest temperature and three peaks of higher temperature which occur because I turned on the heater, however, the data fluctuates along with the graph, which is not significant to the information gain from the graph.

It is also lower the performance in creating a visualisation. Thus, a suitable level of granularity will be found.

# The example graph of daily temperature
f, ax = plt.subplots(figsize=(15,6)) 
eg_date = "2020-09-17"
ten_min = temp_df[temp_df["date"]==eg_date].reset_index(drop=True)
g = sns.lineplot(data=ten_min, x="time", y="temperature")
g.set_xticks([0, 35, 70, 105, 140]) 
g.set_xticklabels(["00:04:04","05:54:38","11:45:12", "17:35:46","23:26:20"])
plt.title("Fig. 1 My room temperature on 17 September 2020")
plt.xlabel("Time")
plt.ylabel("Temperature (°C)") 
plt.show()
#print(list(ax.get_xticklabels()))

Find the suitable granularity level

To find the suitable granularity level, the data of example date will be aggregated to 30 minutes, 1 hour, and 2 hours, compared to 10 minutes. The data after aggregation is display in Fig. 2. From the graph, 30 minutes and 1 hour aggregate level show the valleys and peaks similar to 10 minutes data. However, at 2 hours data, the valley at 11:40 disappear.

Thus, to maintain significant detail and improve performance for visualisation of daily temperature, aggregate data into one hour should be the suitable level of granularity.

# Adjust the timestamp scale to be able to plot on the same axis with other
tm_m = dt_df.resample("10min", on="datetime").mean().reset_index()

# Group time in range of 30 min
tt_m = dt_df.resample("30min", on="datetime").mean().reset_index()

# Group time in range of 1 hour
one_hour = dt_df.resample("60min", on="datetime").mean().reset_index()

# Group time in range of 2 hour
two_hour = dt_df.resample("120min", on="datetime").mean().reset_index()

# Split date and time
df_list = [tm_m, tt_m, one_hour, two_hour]
for i in df_list:
    i["date"] = i["datetime"].dt.strftime("%Y-%m-%d")
    i["time"] = i["datetime"].dt.strftime("%H:%M:%S.%f")
    
# Select only the example date (2020-09-17)
tt_m_eg = tt_m[tt_m["date"]==eg_date].reset_index(drop=True)
one_hour_eg = one_hour[one_hour["date"]==eg_date].reset_index(drop=True)
tm_m_eg = tm_m[tm_m["date"]==eg_date].reset_index(drop=True)
two_hour_eg = two_hour[two_hour["date"]==eg_date].reset_index(drop=True)

# Identify granularity level
tm_m_eg["granularity"] = "10 min"
tt_m_eg["granularity"] = "30 min"
one_hour_eg["granularity"] = "1 hour"
two_hour_eg["granularity"] = "2 hour"
all_lvl = pd.concat([tm_m_eg, tt_m_eg, one_hour_eg, two_hour_eg])

Plot the graph

# Graph for select suitable granularity level
f, ax = plt.subplots(figsize=(15,6)) 
g = sns.lineplot(data=all_lvl, x="time", y="temperature", hue="granularity", palette="bright")
plt.title("Fig. 2 Different granularity level of my room temperature on 17 September 2020")
g.set_xticks([0, 35, 70, 105, 140]) 
g.set_xticklabels(["00:00:00","05:50:00","11:40:00", "17:30:00","23:20:00"])
plt.xlabel("Time")
plt.ylabel("Temperature (°C)") 
plt.show()

All daily my room temperature

The graph of all daily temperature from 17 September 2020 to 21 December 2020 is shown in Fig. 3.
Though the recorded temperature was from spring (September) to summer (December), the trend of increasing temperature is not clear in the graph. This might happen because the room has a heater and the temperature in the room is more stable than the temperature outside. Moreover, the overall change in temperature from spring to summer is not as clear as summer to winter (or winter to summer) as shown in the graph of outside temperature (Fig. 5).

# Graph for all daily room temperature
f, ax = plt.subplots(figsize=(15,6))
g = sns.lineplot(data=one_hour[8:2312], x="time", y="temperature", hue="date", palette="viridis")

# Legend
first_day = mpatches.Patch(color=[0.451, 0.259, 0.506], label="17 September 2020")
mid_day = mpatches.Patch(color=[0.345, 0.671, 0.663], label="03 November 2020")
last_day = mpatches.Patch(color=[0.976, 0.925, 0.345], label="21 December 2020")
plt.legend(handles=[first_day, mid_day, last_day])
# Ref for custom legend: https://matplotlib.org/3.2.1/tutorials/intermediate/legend_guide.html
# Ref for color: https://matplotlib.org/tutorials/colors/colors.html

plt.setp(g.lines, alpha=.7) 
plt.title("Fig. 3 My room temperature from 17 September 2020 to 21 December 2020")
g.set_xticks([0, 5, 10, 15, 20]) 
g.set_xticklabels(["00:00:00","05:00:00","10:00:00", "15:00:00","20:00:00"])
plt.xlabel("Time")
plt.ylabel("Temperature (°C)") 
plt.show()

Compare room minimum and maximum temperature to the temperature outside

My room daily minimum and maximum temperature

The raw temperature data get aggregate to find the minimum and maximum temperature. To reduce misleading information, the day that fails to record more than 2 hours will be removed. The graph shows slightly resemble of the minimum and maximum temperature in my room when compares them in Fig. 4.

# Get min and max of each day
daily_temp = dt_df.resample("D", on="datetime")["temperature"].agg(["min", "max", "count"]).reset_index()

# Remove null row
daily_temp.dropna(inplace=True)

# Remove row that miss more than 2 hour of record
daily_temp.drop(daily_temp[daily_temp["count"] < 132].index, inplace=True)

# Drop count column
daily_temp.drop("count", axis=1, inplace=True)

# Convert to long format
daily_temp = pd.melt(daily_temp, id_vars=["datetime"], value_vars=["min", "max"])

daily_temp.head()
datetimevariablevalue
02020-09-17min22.000
12020-09-18min20.937
22020-09-19min25.312
32020-09-20min22.750
42020-09-21min22.562

Plot the graph of daily minimum and maximum temperature in my room.

f, ax = plt.subplots(figsize=(15,6)) 
g = sns.lineplot(data=daily_temp, x="datetime", y="value", 
                 hue="variable", markers=True, dashes=False, style="variable")
ax.legend(labels=["minimum", "maximum"], loc="upper left")
plt.title("Fig. 4 Daily minimum and maximum temperature in my room")
plt.xlabel("Time")
plt.ylabel("Temperature (°C)") 
plt.show()

Minimum and maximum outside temperature

The data that will be used for comparison is from the Bureau of Meteorology (2021), measure at Moorabbin Airport, Victoria, Australia, which is the nearest weather station to my room. The graph of all year minimum and maximum temperature from the weather station (Fig. 5) shows the increasing and decreasing of temperature trend in each month. The trends are similar between the minimum and maximum temperature.

# Read weather station temperature data
weather_sta_max = pd.read_csv("weather_station_max.csv")
weather_sta_min = pd.read_csv("weather_station_min.csv")


# Merge datetime column
ws_list = [weather_sta_max, weather_sta_min]
for i in ws_list:
    i[["Year", "Month", "Day"]] = i[["Year", "Month", "Day"]].astype("str")
    i["datetime"] = i["Year"] + "-" + i["Month"] + "-" + i["Day"]
    i["datetime"] = pd.to_datetime(i["datetime"])
    
# Drop unuse column
acc_name = ["Days of accumulation of maximum temperature", 
            "Days of accumulation of minimum temperature"]
for i in range(len(ws_list)):
    ws_list[i].drop(["Product code", 
            "Bureau of Meteorology station number",
            "Year",
            "Month",
            "Day",
            acc_name[i],
            "Quality"],
           axis=1, inplace=True)
    ws_list[i].head()

# Join min and max from weather station
station_temp = pd.merge(weather_sta_max, weather_sta_min)
station_temp.columns = ["max", "datetime", "min"]

# Convert to long format
station_temp = pd.melt(station_temp, id_vars=["datetime"], value_vars=["min", "max"])
station_temp.head()
datetimevariablevalue
02020-01-01min10.0
12020-01-02min11.8
22020-01-03min12.2
32020-01-04min15.5
42020-01-05min12.7

Plot the graph of daily minimum and maximum temperature from weather station.

f, ax = plt.subplots(figsize=(15,6)) 
sns.lineplot(data=station_temp, x="datetime", y="value", 
             hue="variable", markers=True, dashes=False, style="variable")
ax.legend(labels=["minimum", "maximum"], loc="upper left")
plt.title("Fig. 5 Daily minimum and maximum temperature from weather station")
plt.xlabel("Time")
plt.ylabel("Temperature (°C)") 
plt.show()

Compare room minimum and maximum temperature to the outside minimum and maximum temperature

When compare my room and outside minimum (Fig. 6) and maximum (Fig. 7) temperature, the temperature inside the room is more stable (less fluctuated) than the outside temperature. Especially the minimum temperature in the room is significantly lower than the outside temperature during all the period of data collection. The main reason is that the heater was used during the day time when it was a cold day, the room temperature during spring is warmer than outside and the room was build to preserve the heat.

# Compare the maximum temperature in the room and weather station
max_temp = pd.merge(daily_temp[daily_temp["variable"]=="max"], 
                    station_temp[station_temp["variable"]=="max"], 
                    on="datetime")
max_temp = max_temp[["datetime", "value_x", "value_y"]]
max_temp.columns = ["datetime", "room_temp", "station_temp"]

# Convert to long format
max_temp_l = pd.melt(max_temp, id_vars=["datetime"], value_vars=["room_temp", "station_temp"])

f, ax = plt.subplots(figsize=(15,6)) 
sns.lineplot(data=max_temp_l, x="datetime", y="value", 
             hue="variable", markers=True, dashes=False, style="variable")
ax.legend(labels=["in the room", "weather station"], loc="upper left")
plt.title("Fig. 6 Daily maximum temperature in my room compare to the temperature from weather station")
plt.xlabel("Time")
plt.ylabel("Temperature (°C)") 
plt.show()
# Compare the minimum temperature in the room and weather station
min_temp = pd.merge(daily_temp[daily_temp["variable"]=="min"], 
                    station_temp[station_temp["variable"]=="min"], 
                    on="datetime")
min_temp = min_temp[["datetime", "value_x", "value_y"]]
min_temp.columns = ["datetime", "room_temp", "station_temp"]

# Convert to long format
min_temp_l = pd.melt(min_temp, id_vars=["datetime"], value_vars=["room_temp", "station_temp"])

f, ax = plt.subplots(figsize=(15,6)) 
sns.lineplot(data=min_temp_l, x="datetime", y="value", 
             hue="variable", markers=True, dashes=False, style="variable")
ax.legend(labels=["in the room", "weather station"], loc="upper left")
plt.title("Fig. 7 Daily minimum temperature in my room compare to the temperature from weather station")
plt.xlabel("Time")
plt.ylabel("Temperature (°C)") 
plt.show()

Find the relationship between room and outside temperature

To find the level of correlation between inside and outside temperature, the Pearson correlation coefficient (r) will be used as a measurement. From the graphs of the relationship between daily maximum (Fig. 8) and minimum (Fig. 9) temperature from outside temperature and inside the room, both of the relationships are close to the linear model. However, the data points of daily maximum temperature are more distributed than the daily minimum temperature. The correlation coefficient of the daily maximum temperature of room and outside is 0.7380, while the daily minimum is 0.7493 which is slightly higher. Though the temperature outside seems to be the major factor that influences the room temperature, there are other factors that can affect the room temperature as well, such as the use of a heater, cooking, room insulator, etc.

# Find the coefficient of room and outside max temp
np_max_room = max_temp["room_temp"].to_numpy()
np_max_sta = max_temp["station_temp"].to_numpy()
max_corelation = stats.pearsonr(np_max_room, np_max_sta)[0]
print("Pearson correlation coefficient (r) between max room temperature and max outside temperature: "
      + "{:.4f}".format(round(max_corelation, 4)))
Pearson correlation coefficient (r) between max room temperature and max outside temperature: 0.7380
# Graph of the relationship beteen room and outside max temp
f, ax = plt.subplots(figsize=(10,6)) 
sns.regplot(data=max_temp, x="station_temp", y="room_temp")
ax.text(30, 29, "r = "+ "{:.4f}".format(round(max_corelation, 4)), fontsize = 12)
plt.title("Fig. 8 The relationship between daily maximum temperature from outside temperature and inside the room")
plt.xlabel("Weather station temperature (°C)")
plt.ylabel("My room temperature (°C)") 
plt.show()
# Find the coefficient of room and outside min temp
min_temp.dropna(inplace=True)
np_min_room = min_temp["room_temp"].to_numpy()
np_min_sta = min_temp["station_temp"].to_numpy()
min_corelation = stats.pearsonr(np_min_room, np_min_sta)[0]
print("Pearson correlation coefficient (r) between min room temperature and min outside temperature: "
      + "{:.4f}".format(round(min_corelation, 4)))
Pearson correlation coefficient (r) between min room temperature and min outside temperature: 0.7493
# Graph of the relationship beteen room and outside min temp
f, ax = plt.subplots(figsize=(10,6)) 
sns.regplot(data=min_temp, x="station_temp", y="room_temp")
ax.text(18, 26, "r = "+ "{:.4f}".format(round(min_corelation, 4)), fontsize = 12)
plt.title("Fig. 9 The relationship between daily maximum temperature from outside temperature and inside the room")
plt.xlabel("Weather station temperature (°C)")
plt.ylabel("My room temperature (°C)") 
plt.show()

References

Bureau of Meteorology. (2021). Retrieved from http://www.bom.gov.au/climate/data/Legend guide — Matplotlib 3.2.1 documentation. (2021). Retrieved from https://matplotlib.org/3.2.1/tutorials/intermediate/legend_guide.htmlscipy.stats.pearsonr — SciPy v1.6.0 Reference Guide. (2021). Retrieved from https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.pearsonr.htmlSpecifying Colors — Matplotlib 3.3.3 documentation. (2021). Retrieved from https://matplotlib.org/tutorials/colors/colors.html

The number of visitors in provinces of Thailand in 2018

I want to practice myself in creating a chloropleth map, so I found an interesting data from Ministry of Tourism & Sports which is a number of visitors in each provinces of Thailand. The data consisting of the total visitors, Thai visitors and foreigner visitors

The chloropleth map of number of visitors in Thailand

The deeper shade of blue means higher visitors. The darkest blue means the number of visitors is higher than 10 million people.

The top 5 of total visitors

Province Visitors (person)
Bangkok 64,605,920
Chon Buri 18,354,227
Phuket 14,383,348
Chiang Mai 10,844,753
Nakhon Ratchasima 9,989,578

The top 5 of Thai visitors

Province Visitors (person)
Bangkok 40,348,164
Nakhon Ratchasima 9,787,780
Kanchanaburi 8,902,751
Chon Buri 8,588,391
Phetchaburi 8,515,431

The top 5 of foreigner visitors

Province Visitors (person)
Bangkok 24,257,756
Phuket 10,328,952
Chon Buri 9,765,836
Krabi 4,382,074
Surat Thani 3,705,783

It can be seen from the above that Thai and foreigner have some difference in travel destination. Some provinces have more foreigner visitors than Thai such as Phuket, Chon Buri and Surat Thani but most of the provinces have Thai visitors.

My code on Github 
https://github.com/supvolume/Thailand_visitors_stat

References
https://www.mots.go.th/more_news.php?cid=509&filename=index
https://data.humdata.org/dataset/thailand-administrative-boundaries
https://towardsdatascience.com/lets-make-a-map-using-geopandas-pandas-and-matplotlib-to-make-a-chloropleth-map-dddc31c1983d



จำนวนนักท่องเที่ยวในจังหวัดต่าง ๆ ของประเทศไทยปี 2561

อยากฝึกทำแผนที่ chloropleth เลยใช้ข้อมูลจากกระทรวงการท่องเที่ยวและกีฬา ซึ่งเป็นสถิตินักท่องเที่ยวจากไทยและต่างประเทศที่ไปเยือนจังหวัดต่าง ๆ ในปี 2561 แยกเป็นผู้เยี่ยมเยือนทั้งหมด ผู้เยี่ยมเยือนชาวไทย และผู้เยี่ยมเยือนชาวต่างชาติ

สร้างเป็นแผนที่ได้ดังนี้

พื้นที่สีน้ำเงินเข้มสุดคือจำนวนผู้เยี่ยมเยือน 10 ล้านคนขึ้นไป ยิ่งสีอ่อนลงคือจำนวนผู้เยี่ยมเยือนน้อยลงไปตามลำดับ

5 อันดับแรกที่มีผู้เยี่ยมเยือนรวมทั้งชาวไทยและชาวต่างชาติสูงสุด

จังหวัด ผู้เยี่ยมเยือน (คน)
กรุงเทพมหานคร 64,605,920
ชลบุรี 18,354,227
ภูเก็ต 14,383,348
เชียงใหม่ 10,844,753
นครราชสีมา 9,989,578

5 อันดับแรกที่มีผู้เยี่ยมเยือนชาวไทยสูงสุด

จังหวัด ผู้เยี่ยมเยือน (คน)
กรุงเทพมหานคร 40,348,164
นครราชสีมา 9,787,780
กาญจนบุรี 8,902,751
ชลบุรี 8,588,391
เพชรบุรี 8,515,431

5 อันดับแรกที่มีผู้เยี่ยมเยือนชาวต่างชาติสูงสุด

จังหวัด ผู้เยี่ยมเยือน (คน)
กรุงเทพมหานคร 24,257,756
ภูเก็ต 10,328,952
ชลบุรี 9,765,836
กระบี่ 4,382,074
สุราษฎร์ธานี 3,705,783

จะเห็นว่าการเดินทางไปจังหวัดต่าง ๆ ของชาวไทยกับชาวต่างชาติมีความแตกต่างกันอยู่บ้าง บางจังหวัดมีนักท่องเที่ยวชาวต่างชาติมากกว่าชาวไทย เช่น ภูเก็ต ชลบุรี และสุราษฎร์ธานี แต่ส่วนมากแล้วแต่ละจังหวัดจะมีผู้มาเยือนเป็นชาวไทยมากกว่าชาวต่างชาติ

ดูโค้ดได้ที่ 
https://github.com/supvolume/Thailand_visitors_stat

อ้างอิง
https://www.mots.go.th/more_news.php?cid=509&filename=index
https://data.humdata.org/dataset/thailand-administrative-boundaries
https://towardsdatascience.com/lets-make-a-map-using-geopandas-pandas-and-matplotlib-to-make-a-chloropleth-map-dddc31c1983d



How many Starbucks in each area of Bangkok?

When I traveled to shopping district in Bangkok, it was hard to not found any Starbucks store in direction I walked. Some shopping mall has 3 stores, and there are other 2 stores just across the street. So, I wonder which area have the highest number of stores.

With the time limitation and complicated in counting data. The spelling of district names is also difference. For example Rajthewi, Ratchathewi, Ratchatevee are the same district but they used different spelling, which increase complication in counting stores per each distract.

Therefore, I counted stores per each postcode instead. The area was divided into 26 areas according to postcode.

The amount of Starbucks store in Bangkok in each area

Rank District Postcode Store amount
1 Khlong Toei, Watthana 10110 34
2 Pathum Wan 10330 29
3 Din Daeng, Phaya Thai, Ratchathewi 10400 18
4 Wang Thonglang, Huai Khwang 10310 16
5 Bang Kho Laem, Yan Nawa, Sathon 10120 15
6 Bang Kapi, Saphan Sung, Bueng Kum 10240 12
6 Bang Rak 10500 12
7 Khan Na Yao, Lat Phrao 10230 10
7 Bang Na, Phra Khanong 10260 10
8 Chatuchak 10900 9
9 Bang Khae, Phasi Charoen, Nong Khaem 10160 7
10 Don Mueang, Lak Si 10210 6
10 Prawet, Suan Luang 10250 6
11 Chom Thong, Bang Khun Thian, Bang Bon 10150 5
11 Phra Nakhon 10200 5
11 Bang Khen, Sai Mai 10220 5
11 Khlong San, Thon Buri, Bangkok Yai 10600 5
12 Pom Prap Sattru Phai, Samphanthawong 10100 4
12 Bangkok Noi, Bang Phlat 10700 4
13 Taling Chan, Thawi Watthana 10170 3
13 Dusit 10300 3
14 Lat Krabang 10520 2
15 Bang Sue 10800 1
16 Rat Burana, Thung Khru 10140 0
16 Khlong Sam Wa, Min Buri 10510 0
16 Nong Chok 10530 0

*Postcode have exception on some building that postcode is not consistent with district name, more detail on https://file.thailandpost.com/upload/content/2558_56a9d444d5276.pdf (Thai)
**Data was collected on 22 February 2019

Interesting information

  • The total number of Starbucks in Bangkok is 221 stores.
  • The top 6 areas is the area that connected to mass rapid transit systems (BTS, MRT or Airport link)
  • From all districts that are not connected to mass rapid transit systems, Khan Na Yao and Lat Phrao district (10230) has the highest number of Starbucks stores.
  • The district that don’t have any Starbucks store are Rat Burana and Thung Khru (10140), Khlong Sam Wa and Min Buri (10510) and Nong Chok district (10530)

My code on Github
https://github.com/supvolume/Bangkok_starbucks

References
http://www.starbucks.co.th/store-locator/search
https://en.wikipedia.org/wiki/Mass_Rapid_Transit_Master_Plan_in_Bangkok_Metropolitan_Region

Featured image from
https://pixabay.com/en/starbucks-shop-people-coffee-man-2594992/

ปริมาณร้านสตาร์บัคส์ในแต่ละพื้นที่

พอได้เดินทางเข้าไปในเมืองแล้วมีความรู้สึกว่าเจอร้านสตาร์บัคส์เยอะจัง ในห้างเดียวกันบางทีมีถึง 3 สาขา ถ้าข้ามถนนไปก็จะเจออีก 2 สาขา เลยเกิดความสงสัยว่า พื้นที่ไหนนะที่มีร้านสตาร์บัคส์เยอะที่สุด

ด้วยข้อจำกัดทางด้านเวลาและความยุ่งยากของการรวบรวมข้อมูล การสะกดชื่อเขตของเว็บสตาร์บัคส์สะกดชื่อเขตเดียวกันไม่เหมือนกัน เช่น เขตราชเทวีสะกดเป็น Rajthewi, Ratchathewi หรือ Ratchatevee ทำให้การแบ่งพื้นที่ตามชื่อเขตทำได้ยาก เลยเก็บสถิติเป็นตามรหัสไปรษณีย์แทน เท่ากับว่านับร้านโดยแบ่งเป็น 26 พื้นที่ตามรหัสไปรษณีย์

อันดับจำนวนร้านสตาร์บัคส์ในกรุงเทพมหานคร แบ่งตามรหัสไปรษณีย์

อันดับที่ เขต รหัสไปรษณีย์ จำนวนร้าน
1 คลองเตย วัฒนา 10110 34
2 ปทุมวัน 10330 29
3 ดินแดง พญาไท ราชเทวี 10400 18
4 วังทองหลาง ห้วยขวาง 10310 16
5 บางคอแหลม ยานนาวา สาทร 10120 15
6 บางกะปิ สะพานสูง บึงกุ่ม 10240 12
6 บางรัก 10500 12
7 คันนายาว ลาดพร้าว 10230 10
7 บางนา พระโขนง 10260 10
8 จตุจักร 10900 9
9 บางแค ภาษีเจริญ หนองแขม 10160 7
10 ดอนเมือง หลักสี่ 10210 6
10 ประเวศ สวนหลวง 10250 6
11 จอมทอง บางขุนเทียน บางบอน 10150 5
11 พระนคร 10200 5
11 บางเขน สายไหม 10220 5
11 คลองสาน ธนบุรี บางกอกใหญ่ 10600 5
12 ป้อมปราบศัตรูพ่าย สัมพันธวงศ์ 10100 4
12 บางกอกน้อย บางพลัด 10700 4
13 ตลิ่งชัน ทวีวัฒนา 10170 3
13 ดุสิต 10300 3
14 ลาดกระบัง 10520 2
15 บางซื่อ 10800 1
16 ราษฎร์บูรณะ ทุ่งครุ 10140 0
16 คลองสามวา มีนบุรี 10510 0
16 หนองจอก 10530 0

*รหัสไปรษณีย์อาจมีข้อยกเว้นคือรหัสไม่สอดคล้องกับชื่อเขตในบางอาคาร ดูรายละเอียดเพิ่มเติมได้ที่ https://file.thailandpost.com/upload/content/2558_56a9d444d5276.pdf
**เก็บข้อมูลเมื่อวันที่ 22 กุมภาพันธ์ 2562

สรุปสิ่งที่น่าสนใจ

  • มีร้านสตาร์บัคส์ในเขตพื้นที่กรุงเทพฯ ทั้งหมด 221 ร้าน
  • 6 อันดับแรกเป็นเขตที่มีพื้นที่ติดแนวรถไฟฟ้า (BTS, MRT, Airport link)
  • เขตคันนายาวและลาดพร้าว (10230) เป็นเขตที่ไม่ติดแนวรถไฟฟ้าที่มีร้านสตาร์บัคส์เยอะที่สุด
  • เชตที่ไม่มีร้านสตาร์บัคส์เลยคือ ราษฎร์บูรณะ ทุ่งครุ (10140) คลองสามวา มีนบุรี (10510) และหนองจอก (10530)

ดูโค้ดได้ที่
https://github.com/supvolume/Bangkok_starbucks

อ้างอิง
http://www.starbucks.co.th/store-locator/search
https://th.wikipedia.org/wiki/รถไฟฟ้าในกรุงเทพมหานครและปริมณฑล

ภาพ featured image จาก
https://pixabay.com/en/starbucks-shop-people-coffee-man-2594992/

ตำแหน่งที่ผู้จัดการทีมฟุตบอลเคยเล่น มีผลต่อความสำเร็จในการคุมทีมไหม?

คำถามมาจาก Reddit จำไม่ได้แล้วว่ากระทู้ไหนจำรายละเอียดไม่ได้ แต่มีการถกเถียงกันว่าผู้เล่นตำแหน่งนี้ดีหนักหนา เป็นตำแหน่งที่ต้องมีความสามารถในการอ่านเกมทั้งทีมตัวเองและทีมตรงข้าม ทำให้สามารถพัฒนาเป็นผู้จัดการทีมที่ประสบความสำเร็จได้ ตามมาด้วยคำถามที่ว่าตำแหน่งที่ผู้จัดการทีมฟุตบอลเคยเล่นมาก่อนในอดีตมีผลต่อผลงานการคุมทีมจริงหรือไม่

เพื่อที่จะพิสูจน์คำถามนี้ในเชิงสถิติก็ต้องหาข้อมูลมาวัดกัน โดยรายชื่อผู้จัดการทีมมาจากผู้จัดการทีมที่เคยคุมทีมในพรีเมียร์ลีกอย่างน้อยหนึ่งทีม เหตุผลคือหาและรวบรวมข้อมูลง่าย  และคิดว่าข้อมูลน่าจะมากพอในการทำให้เห็นแนวโน้ม ผลการแข่งขันที่นำมาวิเคราะห์นั้นรวมทั้งหมดทุกทีมที่ผู้จัดการเหล่านั้นคุมไม่ว่าจะเป็นในหรือนอกพรีเมียร์ลีกก็ตาม

อย่างแรกต้องนิยามคำว่าความสำเร็จในการคุมทีมก่อน ซึ่งเราใช้สถิติที่ชนะเป็นตัววัดความสำเร็จ ในที่นี้ดูอยู่สองอย่างคือ เปอร์เซ็นต์ชนะรวมทั้งหมดในทุกเกมทุกทีม คิดจากผลชนะจากทุกเกมที่เคยคุมมาหาเป็นเปอร์เซ็นต์ อย่างที่สองคือจุดพีคในอาชีพ คือเปอร์เซ็นต์ชนะที่สูงที่สุด* คิดจากเปอร์เซ็นต์ชนะแยกตามทีมที่เคยคุมมาก่อนแล้วหาเปอร์เซ็นต์ที่สูงที่สุด

*ทั้งนี้เปอร์เซ็นต์ชนะที่สูงที่สุดจะตัดข้อมูลของทีมที่คุมน้อยกว่า38 นัด (เทียบเท่า 1 ฤดูกาล) หรือคุมน้อยกว่า 1 ปีออก เพื่อตัดข้อมูลของการคุมทีมชั่วคราวที่เปอร์เซ็นต์การแพ้ชนะแกว่ง (เช่นคุม 1 นัด ชนะ 1 นัดเท่ากับชนะ 100%) หรืออาจยังคุมทีมไม่ลงตัว

การแบ่งตำแหน่งการเล่นแบ่งเป็นตำแหน่งหลัก ๆ คือกองหน้า กองกลาง กองหลัง และผู้รักษาประตู แต่ในข้อมูลจะมีบางคนที่เคยเล่นสองตำแหน่งหรือไม่พบข้อมูล (N/A) อยู่ด้วย

จากข้อมูลผู้จัดการทีม 189 คน มีถึง 76 คน (40.2%) เคยเล่นตำแหน่งกองกลาง ตามมาด้วย 65 คน (34.4%) ที่เคยเล่นกองหลัง มีเพียง 27 คน (14.3%) ที่เคยเล่นกองหน้า ถือว่าน้อยมากเมื่อเทียบกับอีกสองตำแหน่ง ส่วนผู้รักษาประตูมีเพียง 3 คน (1.6%) เท่านั้น

ถ้าดูแค่นี้ก็เหมือนผู้เล่นกองหน้าหรือผู้รักษาประตูไม่นิยมทำอาชีพผู้จัดการทีม หรือไม่ประสบความสำเร็จเท่าตำแหน่งอื่น….

แต่เดี๋ยวก่อน!!! เราไม่สามารถสรุปชี้ชัดไปได้ทันทีได้แบบนั้น ต้องพิจารณาอัตราส่วนผู้เล่นด้วย 
สมมุติเอาเองว่าทุกทีมเล่นกันด้วยระบบ 4-4-2 หรือคิดเป็นกองหน้า 20 กองกลาง 40 และกองหลัง 40 เปอร์เซ็นต์ ก็อาจจะต่างจากอัตราส่วนของผู้จัดการนิดหน่อยเท่านั้น (อย่าลืมว่าทุกทีมไม่ได้เล่น 4-4-2 ทั้งหมดและจำนวนของนักฟุตบอลก็ไม่ได้ตรงตามอัตราส่วนของระบบการเล่นเป๊ะ ๆ เช่นกัน) เพราะฉะนั้นจะไปฟันธงเอาจากจำนวนตำแหน่งที่เคยเล่นมาก่อนของผู้จัดการทีมเลยไม่ได้

มาดูกราฟกันดีกว่า

เป็นกราฟระหว่างเปอร์เซ็นต์ชนะรวมทั้งหมดกับเปอร์เซ็นต์ชนะที่สูงที่สุด

ถ้าอยู่ด้านขวาบนหมายความว่าทำผลงานในแต่ละทีมดีมาก ในทางกลับกันถ้าอยู่ด้านซ้ายล่างหมายความว่าทำผลงานในแต่ละทีมไม่ค่อยดี

ถ้าอยู่เยื้องมาทางซ้ายบนหมายความว่าทำผลงานทีมหนึ่งไว้ดีมาก แต่กับบางทีมอาจทำไม่ได้ดีนักทำให้ค่าเฉลี่ยลดลง

(อาจจะมีข้อสงสัยตรงที่ทำไมบางคนเปอร์เซ็นต์ชนะรวมทั้งหมดถึงมากกว่าเปอร์เซ็นต์ชนะที่สูงที่สุดได้ เพราะว่าเปอร์เซ็นต์ชนะที่สูงที่สุดมีการตัดข้อมูลที่คุมน้อยกว่า 38 นัด หรือคุมน้อยกว่า 1 ปีออก*)

ถึงแม้ว่าด้านขวาบนจะมีผู้จัดการทีมที่เคยเล่นตำแหน่งกองกลางอยู่มาก แต่ถ้ามองด้านซ้ายล่างก็จะเห็นตำแหน่งกองกลางกระจายตัวอยู่เช่นกัน

สุดท้ายแล้วแต่ละตำแหน่งมีความแตกต่างหรือเปล่าล่ะ?

มาดู box plot กัน (เคยอธิบายเรื่อง box plot ไปแล้วที่นี่)

พล๊อตกราฟเฉพาะตำแหน่งที่มีข้อมูลเพียงพอ ได้แก่กองหน้า กองกลาง และกองหลัง

ถ้าดูจากบริเวณ notch ใน box plot ไม่ว่าจะเป็น box plot จากเปอร์เซ็นต์ชนะรวมหรือเปอร์เซ็นต์ชนะสูงสุด เกยกันทุกตำแหน่งหรือก็คืองไม่แตกต่างกันอย่างมีนัยสำคัญทางสถิติ

เพื่อเป็นการคอนเฟิร์ม เลยหาค่า P-value เพื่อดูว่ามีความแตกต่างอย่างมีนัยสำคัญหรือไม่ (เฉพาะข้อมูลตำแหน่งกองหน้า กองกลาง กลองหลัง) พบว่า P-value ของเปอร์เซ็นต์ชนะรวมอยู่ที่ 0.482 และของเปอร์เซ็นต์ชนะที่สูงที่สุดอยู่ที่ 0.569 ซึ่งมากกว่า 0.05 ทั้งสองค่าก็คือไม่แตกต่างกันอย่างมีนัยสำคัญทางสถิตินั่นเอง

สรุป: ถ้ามีใครถามคำถามว่าตำแหน่งที่ผู้จัดการทีมฟุตบอลเคยเล่นมีผลต่อความสำเร็จในการคุมทีมไหม ก็ตอบไปเลยว่า
“หากอ้างอิงจากข้อมูลผู้จัดการที่เคยคุมทีมในพรีเมียร์ลีกแล้วตำแหน่งที่ผู้จัดการทีมเคยเล่นมาก่อนในอดีตไม่ได้มีผลอย่างมีนัยสำคัญทางสถิติต่อเปอร์เซ็นต์ชนะรวมและเปอร์เซ็นต์ชนะสูงสุด”

ถ้าจะเอาให้ผลสามารถสรุปชัดเจนกว่านี้คงต้องรวมข้อมูลของผู้เล่นอาชีพทั้งหมดที่ผันตัวเป็นผู้จัดการทีมไม่ว่าจะเป็นผู้จัดการทีมที่ไหนก็ตาม แต่การหาข้อมูลผลการแข่งขันของผู้ที่ไม่ประสบความสำเร็จทำได้ยาก

อ้างอิง
https://en.wikipedia.org/wiki/List_of_Premier_League_managers
https://www.soccerbase.com/managers/home.sd

ข้อมูลทางสถิติรวบรวมในวันที่ 11 ธันวาคม 2561

สรุปทริปไต้หวัน

วันที่ 1: TaipeiMain station – อนุสรณ์สถานเจียงไคเชก – ตึกแดง
วันที่ 2: Line Friends Cafe & Store – ไทเป 101 – วัดหลงซาน – ตลาดกลางคืนซื่อหลิน
วันที่ 3: จิ่วเฟิ่น- พิพิธภัณฑ์ทองคำ
วันที่ 4: พิพิธภัณท์กู้กง– สวนสัตว์ไทเป – ห้างโซโก้
วันที่ 5: วัดซงซานฉือโย่ว– สวนสันติภาพ 288 – พิพิธภัณฑ์แห่งชาติไต้หวัน – ย่านจงซาน
วันที่ 6: พิพิธภัณฑ์ของจิ๋ว- EverRich
รีวิวไทเปอาย
รีวิวชานมไข่มุก

การเดินทางครั้งนี้ไปกับแม่สองคน สถานที่เลยไม่ได้อัดแน่นมากเท่าไหร่ เอาที่ไม่เหนื่อยมาก ที่พักเป็นโรงแรมย่านซีเหมินถือว่าสะดวกสบาย อยู่ใกล้กับคาร์ฟูร์ที่เปิด 24 ชั่วโมง

ภาพในบล็อกนี้จะเป็นภาพมือถือปนกับภาพจากกล้อง เพราะฉะนั้นอาจมีดีบ้างแย่บ้างปนกันไป

ทริปไต้หวัน วันที่ 6

อ่านเรื่องทริปไต้หวันวันอื่น ๆ คลิกที่นี่

พิพิธภัณฑ์ของจิ๋ว (Miniatures Museum of Taiwan)

ค่าเข้าชมอาจจะแพงไปหน่อยแต่ไปแล้วจะต้องทึ่งถึงความพยายามของคนที่สร้างของจิ๋วเหล่านี้ ข้าวของต่าง ๆ เก็บรายละเอียดได้ดีมาก

ในบ้านจิ๋ว

ยังมีบ้านจิ๋วกว่าอยู่

เหมือนเด็กจริง ๆ มาก ๆ 

หุ่นเหมือนปีศาจกระดูกขาวที่ไปดูวันก่อนเลย

อาจจะหาตัวพิพิธภัณฑ์ยากอยู่ซักหน่อยถ้ามาจาก MRT เพราะไม่ค่อยมีป้ายบอกทาง ก็ไปตามที่ Google map บอกไว้แล้วสังเกตป้ายแบบนี้ให้ดี ทางเข้าอยู่ชั้น B1 (เดินลงบันไดไป)

EverRich

ช่วงบ่ายไปช้อปส่งท้ายที่ EverRich สาขาที่คิดว่าเดินทางสะดวกที่สุดแล้ว จะเป็นสาขาที่ไม่ใหญ่มาก ถ้าขี้เกียจมาก็ไปซื้อที่สนามบินก็ได้ สินค้าบางตัวต้องไปรับที่สนามบิน

ทริปไต้หวัน วันที่ 5

อ่านเรื่องทริปไต้หวันวันอื่น ๆ คลิกที่นี่

วัดซงซานฉือโย่ว (Songshan Ciyou Temple)

คนนิยมมาวัดนี้ตอนกลางคืนมากกว่าเพราะข้าง ๆ วัดจะมีตลาดกลางคืน แต่มากลางวันก็สวยไปอีกแบบ วัดสูง 6 ชั้น มีกระถางธูปเกือบทุกชั้น ควันธูปที่เข้าถึงทุกพื้นที่ของวัดบ่งบอกถึงศรัทธาได้ดี

สวนสันติภาพ (228 Peace Memorial Park)

สถานที่พักผ่อนหย่อนใจของชาวไทเป ชื่อของสวนเป็นการรำลึกถึงเหตุการณ์ความไม่สงบทางการเมืองที่เกิดขึ้นเมื่อวันที่ 28 กุมภาพันธ์ 1947 

น้องวัวตอนรับอยู่ที่ทางเข้า

มีอนุสาวรีย์รำลึกถึงเหตุการณ์ดังกล่าวด้วย

พิพิธภัณฑ์แห่งชาติไต้หวัน (National Taiwan Museum)

พิพิธภัณฑ์แห่งชาติไต้หวันตั้งอยู่ภายในสวน 228 นั่นแหละ ภายในจัดนิทรรศการถาวรเกี่ยวกับไต้หวันและชนพื้นเมือง และนิทรรศการหมุนเวียน

ย่านจงซาน (Zhongshan)

อีกที่นึงที่ไปแต่ไม่ได้ถ่ายรูปไว้คือย่านจงซาน เป็นแหล่งช้อปปิ้งที่มีศูนย์การค้าติด ๆ กันอยู่ เดินเข้าห้างนู้นออกห้างนี้กันจนเมื่อยขา

TaipeiEYE

ปิดท้ายด้วยการแสดงที่ไทเปอาย ประทับใจจนต้องเขียนแยกไว้ที่นี่

อ่านต่อวันที่ 6 คลิกที่นี่