2019年11月23日 星期六

python3.8 新特性async實現自動化爬蟲功能


下面程式碼實現在指定URL下抓取HTML頁面裡包含javascript腳本生成quote節點後的訊息。
import asyncio
from pyppeteer import launch
from pyquery import PyQuery as pq

async def main():
    print ('start main()')
    browser = await launch()
    print('browser ready')
    page = await browser.newPage()
    print('Page ready')
    await page.goto('http://quotes.toscrape.com/js/')
    print('goto ready')
    doc = pq(await page.content())
    print('pq ready')
    print('Quotes:', doc('.quote').length)
    await browser.close()
    print('browser closed')


if __name__ == '__main__':
    if asyncio.iscoroutinefunction(main):
        asyncio.get_event_loop().run_until_complete(main())
    else:
        main()

好久沒有更新blogger了,來新增一波內容
pyppeteer :https://github.com/miyakogi/pyppeteer
chromium automation library

PyQuery: jquery-like library for python
async: keyword for coroutine, to write concurrent code in python3.8

2018年1月6日 星期六

神經網絡的普適性

啟發來源:
# https://github.com/mxjl620/reading_note/blob/master/Neural_Network_and_Deep_Learning/%E7%AC%AC%E5%9B%9B%E7%AB%A0_%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E5%8F%AF%E4%BB%A5%E6%8B%9F%E5%90%88%E4%BB%BB%E4%BD%95%E5%87%BD%E6%95%B0%E7%9A%84%E5%8F%AF%E8%A7%86%E5%8C%96%E8%AF%81%E6%98%8E.md

神經網絡的普適性:神經網絡可以擬和任意函數。


數學證明:
=========
# 基礎證明普適性
Approximation by superpositions of a sigmoidal function, by George Cybenko (1989).

# 採用Stone-Weierstrass定理的方式證明,包含hahn-Banach Theory、Riesz Representation、Fourier Analysis
Multilayer feedforward networks are universal approximators, by Kurt Hornik, Maxwell Stinchcombe, and Halbert White (1989)

# "神經網絡可以擬合任何函數"的普適性說明:
1. 增加隐藏神经元的个数,就能得到更好的结果,證明方式與微積分的趨近的delta-eplison表達雷同。
2. sigmoid神經元組成的網絡可以計算任意函數

sigmoid function的在神經元節點的weight足夠大時,可以擬合讓他趨近於step function。

2017年10月3日 星期二

how to start your chinese NLP journey?

# how to import chinese corpus for NLP
# http://cpmarkchang.logdown.com/posts/184192-python-nltk-sinica-treebank
# http://ckip.iis.sinica.edu.tw/CKIP/treebank.htm
# http://museum02.digitalarchives.tw/ndap/2002/SinicaTreebank/ckip.iis.sinica.edu.tw/CKIP/tr/201301_20140813.pdf
>>> from nltk.corpus import sinica_treebank
>>> import nltk

# get all treebank words in one time
>>> sinica_treebank.words()
['\xe4\xb8\x80', '\xe5\x8f\x8b\xe6\x83\x85', ...]

# get tagged_words and sentences in treebank
>>> sinica_treebank.tagged_words()
[('\xe4\xb8\x80', 'Neu'), ('\xe5\x8f\x8b\xe6\x83\x85', 'Nad'), ...]
>>> sinica_treebank.sents()[15]
['\xe5\xa4\xa7\xe8\x81\xb2', '\xe7\x9a\x84', '\xe5\x8f\xab', '\xe8\x91\x97']

# get the grammar tree
>>> sinica_treebank.parsed_sents()[15]
Tree('VP', [Tree('V\xe2\x80\xa7\xe5\x9c\xb0', [Tree('VH11', ['\xe5\xa4\xa7\xe8\x81\xb2']), Tree('DE', ['\xe7\x9a\x84'])]), Tree('VE2', ['\xe5\x8f\xab']), Tree('Di', ['\xe8\x91\x97'])])

# draw the grammar tree
>>> sinica_treebank.parsed_sents()[15].draw()

# get concordance
>>> sinica_text=nltk.Text(sinica_treebank.words())
>>> sinica_text.concordance('我')

# frequency distribution
>>> sinica_fd=nltk.FreqDist(sinica_treebank.words())
>>> top100=sinica_fd.items()[0:100]
>>> for (x,y) in top100:
>>>     print x,y

# how to list all docs in a corpus
# http://www.burnelltek.com/blog/0376c9eac69611e6841d00163e0c0e36
import nltk
from nltk.corpus import gutenberg
print(gutenberg.fileids())

# corpus from web
from nltk.corpus import webtext
print(webtext.fileids())

# corpus for inaugural
from nltk.corpus import inaugural
print(inaugural.fileids())

# corpus from chat
from nltk.corpus import nps_chat
print(nps_chat.fileids())

# how to get a document from a corpus
emma = gutenberg.words("austen-emma.txt")
print(emma)

# entropy, point mutual information, perplexity are measures for sentimental classification

# how to use conditional frequency Distribution
# http://www.burnelltek.com/blog/e08e0bbecb1811e6841d00163e0c0e36
import nltk
from nltk.corpus import brown
pairs = [(genre, word) for genre in brown.categories() for word in brown.words(categories=genre)]
cfd = nltk.ConditionalFreqDist(pairs)

# how to generate all possible bigrams
sent = ['I', 'am', 'a', 'good', 'man']
print(list(nltk.bigrams(sent)))


# how to use conditional frequency distribution
# http://www.burnelltek.com/blog/e08e0bbecb1811e6841d00163e0c0e36
import nltk
from nltk.corpus import brown
pairs = [(genre, word) for genre in brown.categories() for word in brown.words(categories=genre)]
cfd = nltk.ConditionalFreqDist(pairs)

# show conditions for conditional frequency distribution
print(cfd.conditions())

# display a table for specified conditions and term frequency
genres = ['news', 'religion', 'hobbies', 'science_fiction', 'romance', 'humor']
modals = ['can', 'could', 'may', 'might', 'must', 'will']
cfd.tabulate(conditions=genres, samples=modals)

# display a plot for conditional frequency distribution
cfd.plot(conditions=genres, samples=modals)

# how to get the frequency distribution with specified vacabularies from bigrams
text = brown.words(categories='news')
bigrams_words = nltk.bigrams(text)
cfd = nltk.ConditionalFreqDist(bigrams_words)
fd = cfd['can']
fd.plot(10)

# how to process pos tags
import nltk
words = nltk.word_tokenize('And now for something completely different')
print(words)
word_tag = nltk.pos_tag(words)
print(word_tag)

# nltk pos tagging for Chinese
nltk.word_tokenize(text):对指定的句子进行分词,返回单词列表
nltk.pos_tag(words):对指定的单词列表进行词性标记,返回标记列表
CategorizedTaggedCorpusReader::tagged_words(fileids, categories):该方法接受文本标识或者类别标识作为参数,返回这些文本被标注词性后的单词列表
CategorizedTaggedCorpusReader::tagged_sents(fileids, categories):该方法接受文本标识或者类别标识作为参数,返回这些文本被标注词性后的句子列表,句子为单词列表
SinicaTreebankCorpusReader::tagged_words(fileids):该方法接受文本标识作为参数,返回文本被标注词性后的单词列表
SinicaTreebankCorpusReader::tagged_sents(fileids):该方法接受文本标识作为参数,返回文本被标注词性后的句子列表,句子为单词列表

# how to stats all segmented chinese words?
python -m jieba 1.txt -q | tr '/' '\n' | sort | uniq -c
python -m jieba 1.txt -q | tr '/' '\n' | sed 's/^[ \t]//' # clean leading spaces in each line

# how to calculate the words diversity
numerator=$(python -m jieba 1.txt -q | tr '/' '\n' | sed 's/^[ \t]//' | sort  | uniq | wc -l) # stats how many uniq words in the doc
denominator=$(python -m jieba 1.txt -q | tr '/' '\n' | sed 's/^[ \t]//' | sort | wc -l # stats how many words in the doc)
words_diversity = $numerator / $denominator

# online code search on command line
https://github.com/stayhigh/how2
pip install how2

https://github.com/gautamkrishnar/socli
sudo apt-get install python python-pip
sudo pip install socli

https://www.npmjs.com/package/stack-overflow-search
 npm install -g stack-overflow-search

2017年5月25日 星期四

機器學習實戰 - kNN算法 - 2

kNN演算法

簡述:
kNN算法非常直覺,根據統計新的資料點離原本的k個最近的資料點的分類的出現數量與距離進行判斷,藉此分析新的資料所屬的分類。

主要應用:約會網站、手寫數字辨識系統
算法優點:精度高、對異常值不敏感、不假定輸入數據
適用資料範圍類型:數值型與標準型

參考來源:http://www.ifight.me/273/
kNN算法步驟:



kNN演算法的基本思路:在給定新資料后,考慮在訓練資料點中與該新資料點距離最近(最相似)的 K 個資料點,根據這 K 個資料點所屬的類別判定所屬的分類類別,具體的演算法步驟如下:


  1. 計算已知類別資料及當中的點與當前點之間的距離
  2. 按照距離遞增次序排列
  3. 選取與當前點距離最小的k個點
  4. 確定前k個點所在類別的出現頻率
  5. 返回前k個點出現高頻的類別作為當前點的預測分類
距離公式可採用下面多種距離,一般建議Mahalanobis distance效果較佳。

關於更多Mahalanobis distance資訊: https://en.wikipedia.org/wiki/Mahalanobis_distance


下面附上常用的距離公式列表:

  1. 歐氏距離 (各個維度距離重要度均等)
  2. 曼哈頓距離 (Manhattan distance又稱city block distance,格子距離)
  3. 切比雪夫距離 (Chebyshev Distance,等同國際象棋國王與棋子的行走距離)
  4. 閔可夫斯基距離 (Minkowski Distance)
    當p=1時,就是曼哈頓距離
    當p=2時,就是歐氏距離
    當p→∞時,就是切比雪夫距離
  5. 標準化歐氏距離 (根據傳統歐氏距離的每個維度標準差變量進行標準化)
  6. 馬氏距離 (Mahalanobis Distance
    @解決思想:由於各維度權重相同所造成的分類誤判、排除變量之間的相關性的干擾
    @數學原理:距離近的加權高、距離遠的加權低、最後算總值。
  7. 夾角餘弦(Cosine Similarity,衡量向量之間的差異)
  8. 漢明距離 (Hamming distance,兩個等長字串的最小替換次數,應用在訊息編碼)
  9. 傑卡德距離 & 傑卡德相似係數
    (Jaccard similarity coefficient,兩集合交集數除以聯集數,應用於集合相似度的計算)
    Jaccard distance = 1 - Jaccard similarity coefficient
  10. 相關係數 & 相關距離 (Correlation coefficient, Correlation distance)
    可用於計算線性相關度。
  11. 信息熵 (Information Entropy,用於衡量分布的分散程度的度量,分佈越集中entropy就越小)


機器學習實戰 - 機器學習的應用步驟 - 1


由於身邊很多朋友想要接觸機器學習,卻不知道如何開始與應用,所以撰寫簡易的入門文讓新手理解如何應用機器學習的演算法於現實世界的問題。也分享個人經驗。

根據Machine Learning in Action書裡面的講解,可分成下面步驟:

  1. 收集數據
  2. 準備輸入數據
  3. 分析輸入數據
  4. 訓練算法
  5. 測試算法
  6. 使用算法 
收集數據部分:個人是使用python透過scrapy框架撰寫網絡爬蟲程式,好用便捷。
準備輸入數據:可透過numpy或pandas裡面讀取文件的API,並確認Load資料正確無誤。
分析輸入數據:查看資料是否有異常值、分析特徵的數值分佈、使用matplotlib將資料視覺化
訓練算法:根據資料抽取知識跟信息後,根據資料特性來選擇適合的機器學習演算法。
測試算法:設計評估算法,透過accuracy與recall數值評分。
使用算法:如何設計整個應用的流程pipeline。

建議使用python語言,提供適用的字串處理、數值運算、文本分析工具、機器學習套件等。
下面是IEEE選出的TOP 10演算法,可先以這些算法著手學習:






scikit-learn 機器學習套件 - 分析 supervised machine learning algorithm 效率

參考資料: http://scikit-learn.org/

套件說明:
scikit-learn此python套件非常適合用於機器學習領域。
機器學習領域一般分為:監督式學習、非監督式學習、增強式學習等
在能拿過去資料並有相關特徵標籤的分析案例而言,一般採用監督式學習演算法。

由於過去研究SVM是當前分類accuracy比較高的算法, 這次透過scikit裡面的內容驗證監督式學習演算法的效率,分析各個算法的效率。

分析程式碼與資源:
相關程式碼參閱下面連結:
http://scikit-learn.org/stable/auto_examples/classification/plot_classifier_comparison.html#sphx-glr-auto-examples-classification-plot-classifier-comparison-py

裡面的程式碼片段可以看到所有羅列出來的算法。
names = ["Nearest Neighbors", "Linear SVM", "RBF SVM", "Gaussian Process",
         "Decision Tree", "Random Forest", "Neural Net", "AdaBoost",
         "Naive Bayes", "QDA"]

下面是分析結果示意圖,右下角數值為accuracy:

實驗結論:
實驗中採用三種特性的dataset,第一個是部分特徵數值混在一起的、第二個是線性不可分的資料集合、第三個是簡易可以線性分割的資料集。由圖可知RBF-SVM是在這次實驗當中表現最好的一個算法。

關鍵解析:
重點在於SVM採用的kernel function,解決的線性不可分的資料集合所產生的問題。
其中kernel function原理就是透過內積運算原理將較低維度的空間資料及轉換到高維度的空間,使其資料集合較能夠線性可分,下方示意圖為2維轉換到3維的空間轉換示意圖。

關於kernel function原理請參閱下面連結: https://ireneli.eu/2016/09/13/two-sample-problem2-kernel-function-feature-space-and-reproducing-kernel-map/
關於RBF kernel 請參考:https://read01.com/2xMOa4.html





2017年2月12日 星期日

如何快速製作terminal的動作成gif動畫圖檔?

開發程式常常會需要說明使用方法,其中一個就是製作在terminal上面的動畫圖檔
下面推薦兩款ttygif與ttystudio使用。


各個作業系統的安裝方式可參考下面連結:
https://github.com/icholy/ttygif
https://github.com/chjj/ttystudio



下面以mac osx作為範例說明如何安裝與使用

# ttygif 安裝與使用
brew install ttygif
ttyrec recording
ttygif recording 

# ttystudio 安裝與使用

npm install ttystudio
ttystudio output.txt --log # 執行此行指令便開始錄製,使用ctrl+Q退出錄製並製作gif檔案。