Sean talks

Attitude is everything

0%

What’s Google Cloud Dataproc ?

dataproc 是 google 推出的 Spark, hadoop 托管服務,可以快速的佈建 cluster 環境,降低管理困難與使用成本,透過 dataproc 用戶可以專注在數據處理與分析上。

此外 dataproc 部署 Spark & hadoop 環境非常的快,同時也可以很好的整合與 BigQuery 、 Cloud Storage 、 Cloud Bigtable 、 Cloud Logging 間的服務。

接下來會說明簡單的建立與工作提交,更多細節參數設定還是需要參照 Dataproc Docs

How to use ?

Create dataproc clusters

建立 clusters 的方式除了透過 GCP 網頁介面也可以透過 gcloud cmd 佈建

1
2
3
gcloud dataproc clusters create \
dataproc-demo \
--region us-west1
Read more »

[Note] Kubernetes

最近因工作需求必須稍微弄懂 kubernetes 在做些什麼,
因此筆記起來一些基礎的使用與常用語法和遇過的坑。
但要深究細節的話還是得參照官方 doc. : https://kubernetes.io/

what’s kubernetes?

Kubernetes 提供自動化部署及管理 container 的服務,
以協助管理微服務(microservices)系統。

使用 kubernetes 可以提供以下功能:

  • 容器的部署(Deployment)至一或多台機器
  • 工作負載自動化擴展(Scaling)
  • 自動化偵測並重啟故障容器(Management),確保系統持續提供服務

Component of Kubernetes

kubernetes 組成元件由小至大分別為 Pod, Worker Node, Master Node

Pod

Pod 為 kubernetes 運作的最小單位,一個 Pod 對應到一個 Application (e.g. API Server/data transform service),而當多個 Containers 存在於同一個 Pod 時,這些 Containers 會共享資源及網路,以 yaml 定義並部署建立。

Read more »

概述

listtuple 都是 Python 中提供的陣列資料結構,當我們要建立陣列時,我們需先配置一塊記憶體區段 (其中的每一個區段都會被當成指向實際資料的整數指標),其中 :

  • list 為動態陣列型態
  • tuple 則是靜態陣列 (內容固定不可變的)

list 的可改變大小及修改特性意味著其比 tuple 需要存去更多的額外記憶體以計算。

list 為例:

1
list1 = [7, 8, 9, 10, 11]  

在記憶體內的操作即是 :

  1. 配置 list1 所需要的記憶體空間
  2. 產生一個空的 list 並存入這些指向元素的 pointer (如 list1 = 0x003)

因此,當我們需要取出 list1 的第 4 個元素時,我們就會透過指標前往該序列,並取出第 4 個貯體位置內容。

Read more »

載入 Julia Set

書中使用 julia set 來進行程式執行時間的分析。

Julia set

calculate_z_serial_purepython 為需要被計時的函式

直覺的分析方式可以用 print 函式,計算 func. 執行前後的時間間隔

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 擴展 julia pseudo code  
def calculate_z_serial_purepython(maxiter, zs, cs):
output = [0] * len(zs)
for i in range(len(zs)):
n = 0
z = zs[i]
c = cs[i]
while abs(z) < 2 and n < maxiter:
z = z * z + c
n += 1
output[i] = n
return output

# 建構座標串列,作為函式輸入
def calc_pure_python(desired_width, max_iterations):

... ...

print("Length of x:", len(x))
print("Total elements:", len(zs))
start_time = time.time()
output = calculate_z_serial_purepython(max_iterations, zs, cs)
end_time = time.time()
secs = end_time - start_time
print(calculate_z_serial_purepython.__name__ + " took", secs, " seconds")
pass

if __name__ == "__main__":
calc_pure_python(desired_width=10000, max_iterations=300)

此外我們也可以透過定義裝飾器 (Decorator) ,自動化計時

可以看出執行時間比 calc_pure_python 稍微快一點點,差在於 呼叫函式 的開銷。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def timefn(fn):  
@wraps(fn)
def measure_time(*args, **kwargs):
t1 = time.time()
result = fn(*args, **kwargs)
t2 = time.time()
print("@timefn:" + fn.__name__ + " took " + str(t2 - t1) + " seconds")
return result
return measure_time

@timefn
def calculate_z_serial_purepython(maxiter, zs, cs):
... ...
pass
1
2
3
4
5
6
>>>  
Length of x: 10001
Total elements: 22232223
@timefn:
calculate_z_serial_purepython took 12.860910654067993 seconds
calculate_z_serial_purepython took 12.861911058425903 seconds

使用 timeit 模組

1
2
python -m timeit -n 2 -r 3 -s "import julia_set" \  
"julia_set.calc_pure_python(desired_width=10000, max_iterations=300)"
1
2
3
4
5
6
7
8
9
10
>>>  
Length of x: 10001
Total elements: 22232223
@timefn:
calculate_z_serial_purepython took 13.562626361846924 seconds
calculate_z_serial_purepython took 13.562626361846924 seconds
Length of x: 10001
... ...
... ...
2 loops, best of 3: 24.3 sec per loop

使用 Unix time 計時

1
$ /usr/bin/time --verbose python julia_set.py  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Length of x: 10001  
Total elements: 22232223
@timefn:
calculate_z_serial_purepython took 13.609860897064209 seconds
calculate_z_serial_purepython took 13.609860897064209 seconds
Command being timed: "python julia_set.py"
User time (seconds): 12.53
System time (seconds): 0.50
Percent of CPU this job got: 99%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:13.03
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 2649264
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 516303
Voluntary context switches: 1
Involuntary context switches: 23
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0

注意:

  • Major (requiring I/O) page faults 可顯示出哪些程式由於資料從 RAM 搬移至 DISK,進行磁碟存取而導致運作速度降低。

使用 cPython 模組

cPython 是標準程式庫的內建分析工具,他可以連接至 CPython 內的虛擬機器查看每個函式的執行時間。 他會耗費更大的執行開銷,但式可以獲取更多資訊。

1
python -m cProfile -s cumulative julia_set.py  

參數解釋

Para. Description
ncalls 調用次數
tottime 在指定函数中消耗的總時間 (不含調用子含式時間)
percall 是 tottime 除以 ncalls 的商
cumtime 指定的函数及其所有子函数消耗的累計時間
percall 是 cumtime 除以原始調用 (次数) 的商 (含數運行一次的平均時間)
filename 提供相應數據的每個函式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
>>>  
Length of x: 10001
Total elements: 22232223
@timefn:calculate_z_serial_purepython took 17.469009399414062 seconds
85723442 function calls in 33.889 seconds

Ordered by: cumulative time

ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 33.889 33.889 {built-in method builtins.exec}
1 0.550 0.550 33.889 33.889 julia_set.py:1(<module>)
1 12.257 12.257 33.339 33.339 julia_set.py:7(calc_pure_python)
1 0.000 0.000 17.470 17.470 julia_set.py:42(measure_time)
1 13.078 13.078 17.470 17.470 julia_set.py:52(calculate_z_serial_purepython)
41246738 4.392 0.000 4.392 0.000 {built-in method builtins.abs}
44476670 3.611 0.000 3.611 0.000 {method 'append' of 'list' objects}
4 0.001 0.000 0.001 0.000 {built-in method builtins.print}
1 0.000 0.000 0.000 0.000 julia_set.py:41(timefn)
1 0.000 0.000 0.000 0.000 functools.py:34(update_wrapper)
1 0.000 0.000 0.000 0.000 functools.py:64(wraps)
4 0.000 0.000 0.000 0.000 {built-in method builtins.len}
4 0.000 0.000 0.000 0.000 {built-in method time.time}
7 0.000 0.000 0.000 0.000 {built-in method builtins.getattr}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
5 0.000 0.000 0.000 0.000 {built-in method builtins.setattr}
1 0.000 0.000 0.000 0.000 {method 'update' of 'dict' objects}

透過 pstats 模組格式化表格查看。

為了進一步控制 cProfile 結果,可以儲存成一個統計檔案 profile.stats,並以 python 分析它。

1
python -m cProfile -o profile.stats julia_set.py  

使用 pstats 載入分析:

1
2
3
4
import pstats  
p = pstats.Stats("profile.stats")
p.sort_stats("cumulative")
p.print_stats()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
>>>  
Wed Jan 13 16:38:37 2021 profile.stats

85723442 function calls in 33.296 seconds

Ordered by: cumulative time

ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 33.296 33.296 {built-in method builtins.exec}
1 0.534 0.534 33.296 33.296 julia_set.py:1(<module>)
1 11.865 11.865 32.762 32.762 julia_set.py:7(calc_pure_python)
1 0.000 0.000 17.240 17.240 julia_set.py:42(measure_time)
1 12.872 12.872 17.240 17.240 julia_set.py:52(calculate_z_serial_purepython)
41246738 4.368 0.000 4.368 0.000 {built-in method builtins.abs}
44476670 3.656 0.000 3.656 0.000 {method 'append' of 'list' objects}
4 0.001 0.000 0.001 0.000 {built-in method builtins.print}
1 0.000 0.000 0.000 0.000 julia_set.py:41(timefn)
1 0.000 0.000 0.000 0.000 C:\ProgramData\Anaconda3\lib\functools.py:34(update_wrapper)
4 0.000 0.000 0.000 0.000 {built-in method builtins.len}
1 0.000 0.000 0.000 0.000 C:\ProgramData\Anaconda3\lib\functools.py:64(wraps)
4 0.000 0.000 0.000 0.000 {built-in method time.time}
7 0.000 0.000 0.000 0.000 {built-in method builtins.getattr}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
5 0.000 0.000 0.000 0.000 {built-in method builtins.setattr}
1 0.000 0.000 0.000 0.000 {method 'update' of 'dict' objects}

使用 SnakeViz 將 cProfile 的輸出視覺化

執行 snakeviz profile.stats 可以將 CPU 耗費資源以圖表方式視覺化呈現,寬度表示執行所耗費時間。
下方表格則是歸納出函式的耗費時間,為了與人溝通解釋,圖表可以快速讓聽者了解你的觀點。

snakeviz

Reference

Introduction

現今新聞推薦系統中,許多的研究透過加入類神經網路 (Neural) 加強了模型的預測效能,但在變動快速的新聞生態以及用戶偏好容易隨時間改變的特性下,要作出優秀的預測仍是一大挑戰。

總的來說本作將問題視為三個部分:

  1. 過往的研究往往嘗試以提升 current reward 的預測為目標,卻忽略可能對未來推薦造成的影響。
  2. 大部分的推薦系統通常僅考慮用戶 點擊 或其他 user feedback 作為模型建模的依據 (label) ,但本作認為應對 User 之於系統的 滿意程度 多做著墨
  3. 當今推薦系統常有重複推薦相似新聞內容給用戶的問題,舉例來說:在某一時間中的重大新聞被系統大量重複推薦給用戶

因此本作基於上述 3 個議題提出基於 Deep Reinforcement Learning 的模型框架 (DRN) 以對應問題:

  1. 提出 Deep Q learning 以同時考慮 current & future reward 建模
  2. DRN 除了可考慮 user feedback 外,更進一步去估算 user activeness 造成的影響
  3. 使用 Dueling Bandit Gradient Descent Algo. 作搜索 (Exploration) 以避免推薦重覆相似的新聞,且避免推薦 Unrelated 的新聞
Read more »

Summary

Howerd Marks , 在碩士畢業後於花旗集團工作,並在 1978 年開始擔任花旗集團副總裁直至 1985 。 1995 年創立橡樹資本(Oaktree Capital),橡樹資本透過獨特的投資策略管理逾330億美元的資產。其中策略涵蓋私募股本、房地產、亞洲及新興市場股票、日本投資機會、電力基礎設施、不良債務、高息債券、可換股證券及次級債務。
本書講述的是作者對價值投資的思想理念與智慧,其中強調思考價值與價格的關係,並做出風險控管,才得以在適當的時機獲取報酬。

Oaktree Memo

如果你能避免損失,收益就會不請自來。
未來無法預測,但你可以做好準備。
最重要的不是預測,而是週期。


Read more »

簡單的紀錄一下近期複習 pandas 用到的 method 筆記,
舉例來說,今天有個 credit record 如下:

1
2
3
4
5
6
7
8
9
10
11
12
record.info()
>>>
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1048575 entries, 0 to 1048574
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 ID 1048575 non-null int64
1 MONTHS_BALANCE 1048575 non-null int64
2 STATUS 1048575 non-null object
dtypes: int64(2), object(1)
memory usage: 24.0+ MB

Method

.unique

透過 .unique() 得到 Series 中的唯一值

1
2
3
record['STATUS'].unique()
>>>
array(['X', '0', 'C', '1', '2', '3', '4', '5'], dtype=object)
Read more »

Summary

本書是迪士尼執行長 Robert Iger 所著,書中介紹 Iger 從 ABC 新聞員工到接任 ABC 新聞執行長,接著歷經被迪士尼收購後,一直到擔任迪士尼執行長的心路歷程。
其中最令我印象深刻的是 Iger 對創作的要求與包容,工作之餘時刻提點自己家人的重要,以及其與 Jobs 的金治情誼 - 兩人互動可以看到不同專業領域執行長的思維。


其中整理幾個自己較喜歡的段落出來以銘記:

當你有職責在身,眾人希望你扭轉乾坤時,缺乏經驗不能成為失敗的藉口。 此時你必須謙遜,切勿不懂裝懂。 位於領導地位時,也不能令謙遜阻礙你的領導。 真正的權威和領導力自於知道自己是誰,而非裝模作樣。

管理創意的流程必須瞭解這並非一門科學,一切都是主觀的。 多數創作者當能力遭到質疑時,都會很敏感。 因此當我被要求提出見解與批評時,我會十分留心創作者投入的心血,對他們來說承擔多少風險。 因此,負責管理創意作品財務與評估的人在行駛職權時,務必小心避免傷害創意發揮,導致反效果。

我發現許多人會專注於細節枝末,以掩飾自己缺乏明確、連貫的宏觀想法。 如果你從瑣碎的事情著手,你的格局就大不了。 若大局是一團糟,那麼細小的事情也無關緊要,你不該花時間專注在這些事上。

Read more »

Trie ,又可稱為字典樹、前綴樹 (Prefix Tree)

Trie 結構特性

  • hash tree 的變種,常用在搜尋系統中
  • 空間換取時間,利用字串的共同前綴詞 (commen prefix) 作為儲存依據,以字母作為結點,降低查詢時間的開銷以達到提高效率之目的。
  • 樹的高度為最長字串長 + 1
  • 時間複雜度為 O(m), m 為欲插入/搜尋的字串長度

trie

Read more »