2017年2月21日 星期二

自己帶牌打爐石(誤)

去年 AlphaGO 大勝人類之後,曾經有風聲傳出它即將挑戰卡牌遊戲 "爐石戰記" ,研究了一下發現它的通訊協定早已被破解, github 上有人做了整理:Understanding the Hearthstone Protocol ,所以顯然是滿 doable 的。

這些開發者成立一個網站在 https://hearthsim.info/ ,有這麼一句話:

It was used by the DeepMind team at Google for Hearthstone card generation.

其最新一代作品叫 flireplace ,網址在 https://github.com/jleclanche/fireplace

https://github.com/HearthSim 上列出了一些其它的作品,如牌組計算的 https://github.com/HearthSim/Hearthstone-Deck-Tracker ,安裝版可下載自 https://hsdecktracker.net/

過年期間玩了一陣子,覺得這麼複雜的規則竟然能吸引這麼多人去精通,那麼把生活上的一些(冷)知識、時事等等,做成一套牌組來 KUSO 應該也是滿有趣、又富有教育意義的吧。


2017年2月15日 星期三

玩轉 corenlp(2)

第一次執行時可能要做此初始化,速度比較慢,之後速度就很快了。

如果中文的部分出來的結果不好,我覺得常常是專門用語的問題,例如:


"促"這個字單獨出現時,記憶中也只有 TSH 有這種形容詞的詞性,怨不得 CoreNLP 了

P.S. 使用 ant 編譯後,我沒有壓成 jar ,所以執行方式要修正一下:

java -Xmx4g -cp "*;classes" edu.stanford.nlp.pipeline.StanfordCoreNLPServer -serverProperties StanfordCoreNLP-chinese.properties -port 9000 -timeout 15000

2017年2月11日 星期六

一些縮短 perl 程式行數的小技巧

用兩個等長陣列建構 hash


@hash{@keys} = @values

參 http://stackoverflow.com/questions/16755642/perl-built-in-function-to-zipper-together-two-arrays

順便一提,很多時候我們都忘記了, list 和 array 是不同的資料結構。 list 是 literal ,不是一種變數的形態,只是我們經常以 list 來初始化 array (以及 hash )。

my %parataxis=(); #empty hash
my @parataxis=(); #empty array

但是如果初始化的是一個參考資料型態,不管是 hash 或 array ,都有各自的符號 {} / []

my $parataxis={}; #empty hash ref
my $parataxis=[]; #empty array ref

此外,該網頁中使用的 Benchmark 模組可以用來計算函數的執行效率,這是個很實用的小技巧。更詳細的說明參 https://blog.gtwang.org/perl/perl-benchmark-module/

簡單迴圈以 map / grep 處理陣列,以 split / join / splice 處理字串


泛 C 程式語言經常以 { } 括號來表示一個 block ,但是無形中也產生了一、兩個很稀疏的冗行。 python 嘗試以縮排解決這個問題,效果滿不錯的。 perl 的話其實 map 就是一個迴圈,用得好的話可以讓程式很精簡…易讀的話就不是重點了

將一個陣列插入到另一個陣列


參 https://perlmaven.com/how-to-insert-an-array-into-another-array-in-perl

可以分為兩種情況,扁平的或是層級的插入,主要以 splice 函數實作


圖片來源:https://hsto.org/getpro/habr/post_images/707/723/436/70772343650f66c353ad80a06d5272ca.jpg

2017年2月9日 星期四

TF-IDF 以整體稀有度加權來計算詞彙重要性,以決定文件的關鍵詞

打關鍵字可以找出一堆網頁,但是有說明力的網頁,在設計和撰寫上是有一些工夫的。

我個人滿喜歡 文本分析初探 裏的說明,一是在第一頁就講到重點,二是適當的使用實例和圖片/公式,這篇的觀眾就是大眾導向。

排名較高的如 TF-IDF Text-mining 演算法 使用的是很正規的公式,這在翻成程式碼時很直觀,每個下標都對應一個迴圈;但是很多讀者是害怕數學公式的( formula-phobia ),當然例子舉得很好,這篇的觀眾就是工程師導向。

用我的話再解釋一次 tf-idf 的話,假設有 m 份文件, n 種辭彙:

  1. tf 就是 m X n 大小的矩陣,每個元素是該辭彙在該文件中出現的次數(可做些正規化)
  2. df 就是長為 n 的向量,每個元素是包含該辭彙出現的文件數(佔總文件數的比例)
  3. idf 就是 df 的倒數,為免發生除以 0 的情況, idf = 1 / (1 + df)
  4. tf-idf 就是 tf 的每個值對於對應的辭彙做加權
這種計算其實有點 arbitrary .臨界值可能要有點取捨才能得到好的模型,各數值本身也可以做正規化以得到不同的結果。好處就是計算快,所以花點時間都能調出不錯的結果。

2017年2月8日 星期三

emacs 中列出/刪除特定行

2013年我寫過一篇 "使用perl one liner進行檔案搜尋取代的流程(SOP)"

今天遇到列出/刪除具有特定字串的行的問題,發現 perl one liner 只有取代的功能,行是無法刪除的,而且在 windows 平台上,perl one liner 遇到 utf8 滿不好使的。http://xahlee.org/emacs/elisp_list_matching_lines.html 這篇介紹了  list-matching-lines / delete-matching-lines 兩個指令,輕鬆完成任務啊!!!

要注意的是在 org-mode 下使用的話,要把所有大綱縮合起來,有顯示出來的文字是無法被刪除的~~

2017年2月6日 星期一

perl socket 編程速查

基本原理 ,流程圖畫得真是好

小小飯粒範例 ,拿來做 trouble shooting 真是方便

分解動作 ,這種 while ($line = <$sock>) 的寫法邪惡精簡得很啊

console-based 的程式通常是啟動費時短,沒有(or不需要)多工的能力,用來服務單一客戶端之用。一旦出現 contraindication 時,就是 socket-based + non-blocking IO 程式出現的時機了,尤其是還可視負載將服務分散到不同主機上。直覺上就是這樣,只有一台機器的時候,就是排隊,不想排隊而假裝多工,只是讓大家都等,等得更久而已。讓人排隊,還不如讓它 timeout / 返回錯誤值,讓人可以利用等待的時間做其它的工作。所以單機的情況下真的需要多工嗎?這要先好好了解,才能知道接下來要做什麼。

所以回過頭來看,最開頭分享的三個連結,其實對一般日常的任務而言,已經是很足夠的了。

perl 程式中 use utf8 的效果

在涉及 stdin / stdout / sockets 時,如果有處理 unicode / utf8 時,一定要在程式開頭加上 use utf8 宣告

詳情請見 Perl Unicode全攻略