2017年10月29日 星期日

藤原栗子週末碎念-1029

這兩天渡過了已婚男性最羨慕的自由日,雖然自由,卻也感到空虛。
少了喵喵小姐在耳邊喵喵叫,也少了泡泡先生的吵吵鬧鬧
不過也總算是可以再回去菜園看看,三叔種了不少的洛神花,送了我四朵試泡,如果好的話再自己種!
阿霸現在水耕的比例愈來愈高了,愈來愈有心得,今年的草莓應該是可以量產了吧。
這次阿霸給了一顆很重的超級大LEMON,他說這次不會漏氣了,保證多汁味美。
禮拜六帶了阿目去她哈很久的溪頭,雖然阿目只要10元,可是我要200元...這價差真大,
果然是家有一老如有一寶。
等我老了,也可以這麼清閒的種著菜,然後喝著茶或是咖啡,聊聊是非。
最近學機器學習跟深度學習似乎是到了撞牆期了,加油,撐著吧。
人生總不可能事事如意!!
社團人數有100人了,只要再9900就破萬,我想辦研討會就不是問題了....
這是燈籠果,老化之後真的很像。

2017年10月23日 星期一

機器學習_ML-MLPClassifier

機器學習_ML-MLPClassifier

官方連結
This model optimizes the log-loss function using LBFGS or stochastic gradient descent.
這說明了,在sklearn中,MLP是利用隨機梯度或是LBFGS來做權重(參數)θ的計算。
神經網路是最近非常熱門的一門顯學,MLP意為多層類神經網路。何謂多層,即有輸入層、輸出層跟至少一個隱藏層。

借用了官網照片,X那層即為輸入層,OUPUT即為輸出層,中間的a即為隱藏層。
下層單元與上層各單位都會有交錯到!
一般的表示方式為a(2)代表第二層。
借用吳恩達老師上課的一個式子
a1(2)=g(Θ10(1)x0+Θ11(1)x1+Θ12(1)x2+Θ13(1)x3)
Θ的下標的部份,Θ10中的1所指為下一層所對應單元,0為這一層的對應單元。
所以a1(2)=Θ10(1)+....就是,第二層的第一個單元來自於第一層的第0+1+2+3單元的值。
注意到後面的啟動函式是Θ1
Θ即為權重(參數)
這邊主要談的是實用性,所以對於觀念性的部份就不多說,再另外補充。

優缺點

優點:
  • Capability to learn non-linear models.
  • Capability to learn models in real-time (on-line learning) using partial_fit.
    缺點:
  • MLP with hidden layers have a non-convex loss function where there exists more than one local minimum. Therefore different random weight initializations can lead to different validation accuracy.
  • MLP requires tuning a number of hyperparameters such as the number of hidden neurons, layers, and iterations.
  • MLP is sensitive to feature scaling.
sklearn官方說明中也提到兩個關於MLP的優點,第一點是可以學習非線性模型,第二點是可以做線上學習,所以它就會有partial_fit這個method可以使用。
缺點的部份在於,隱藏層有著non_convex的特性,所以不同的權重初始會有可能落入不同的局部最優,而非全域最優,以及MLP需調的參數很多很多,MLP對特徵縮放很敏感(記得做標準化StandardScaler(可參考官方說明搭配pipeline與gridsearchcv取alpha參數))。

IMPORT

from sklearn.neural_network import MLPClassifier

CLASS

MLPClassifier(hidden_layer_sizes=(100, ), 
              activation=’relu’, 
              solver=’adam’, 
              alpha=0.0001, 
              batch_size=’auto’, 
              learning_rate=’constant’, 
              learning_rate_init=0.001, 
              power_t=0.5, 
              max_iter=200, 
              shuffle=True, 
              random_state=None, 
              tol=0.0001, 
              verbose=False, 
              warm_start=False, 
              momentum=0.9, 
              nesterovs_momentum=True, 
              early_stopping=False, 
              validation_fraction=0.1, 
              beta_1=0.9, 
              beta_2=0.999, 
              epsilon=1e-08)

參數說明

hidden_layer_sizes=(100, 2)

default 100
隱藏層的數量

activation

default relu {identity, logistic, tanh, relu}
啟動函數
  • identity, no-op activation, useful to implement linear bottleneck, returns f(x) = x
  • logistic, the logistic sigmoid function, returns f(x) = 1 / (1 + exp(-x)).
  • tanh, the hyperbolic tan function, returns f(x) = tanh(x).
  • relu, the rectified linear unit function, returns f(x) = max(0, x)

solver

default adam {lbfgs, adam, sgd}
優化方式
官方建議,在小型的資料集中使用L-BFGS
資料集 方式
lbfgs
adam
sgd(隨機梯度下降,batch),如果學習效率(learning_rate)有調校好的話,那使用sgd的效果會較上述兩個佳。

alpha

default 0.0001
L2正規化參數

batch_size

default auto(200, n_samples)
如果solver是lbfgs,則不考慮

learning_rate

default constant {constant, invscaling, adaptive}
Only used when solver=‘sgd’.
constant:不變,依learning_rate_init
invscaling:逐漸減小,effective_learning_rate = learning_rate_init / pow(t, power_t)
adaptive:只要成本函數保持下降,那學習效率就會保持不變。但是當不能有效降低至tol,或當early_stopping=on,不能增加驗證分數的時候,那學習效率就會/5

learning_rate_init

default 0.001
Only used when solver=’sgd’ or ‘adam’.

power_t

default 0.5
Only used when solver=’sgd’.
反縮放學習效率的指數,當learning_rate=invscaling時用來更新學習效率用。

max_iter

default 200
最大迭代次數,看是先到tol還是先到max_iter。
但是在sgd與adam的時候似乎不是用於此?
For stochastic solvers (‘sgd’, ‘adam’), note that this determines the number of epochs (how many times each data point will be used), not the number of gradient steps.

shuffle

default True {True, False}
每次的迭次是否要亂數洗牌。
Only used when solver=’sgd’ or ‘adam’.

random_state

default None
隨機數種子

tol

default 0.0001
假如連續兩次的迭代無法降低成本函數,或是得分無法增加,除非learning_rate=‘adaptive’,不然就當做已經收斂完成而結束。

verbose

default 0
過程是否輸出
0不輸出
1偶爾輸出
2一定輸出

warm_start

default False {True, False}
官方說明
如果你想做更多的監控來了解模型走向的話,就可以自己寫for來配合使用。

momentum

default 0.9
配合sgd的一個動量設置,(0-1)
Δxt=ρΔxt1ηgt中的ρ

nesterovs_momentum

default True {True, False}
nesterovs_momentum是momentum的一個改良。
只用於sgd與momentum>0

early_stopping

default False {True, False}
設置用於當驗證得分沒有改善的時候是否要提早結束。
如果設置True的話,則會自動拿10%數據集來做驗證,當最後兩次的迭代都沒有改善的時候就會停止。
Only effective when solver=’sgd’ or ‘adam’

validation_fraction

default 0.1
驗證數據比例,early_stopping=True的時候有效。

beta_1

default 0.9(0-1)
Only used when solver=’adam’

beta_2

default 0.999(0-1)
Only used when solver=’adam’

epsilon

default 1e-8
Only used when solver=’adam’

方法

fit(X, y)

適合(訓練、擬合)資料集

get_params([deep])

取得參數

predict(X)

回傳預測分類

predict_log_proba(X)

回傳類別概率(機率、或然率)對數

predict_proba(X)

回傳類別概率(機率、或然率)

score(X, y[, sample_weight])

Returns the mean accuracy on the given test data and labels.

set_params(**params)

設置參數

partial_fit

線上適合(訓練、擬合)資料集

屬性

classes_

array or list of array of shape (n_classes,)
每個輸出的label

loss_

float
成本函數的值

coefs_

list, length n_layers - 1
第i個元素表示對應於第i層的權重矩陣。
a(j)=g(z(j))
z(j+1)=Θ(j)a(j)

intercepts_

list, length n_layers - 1
回傳第i個元素與層i+1相對應的偏置向量。
a(j)=g(z(j))
z(j+1)=Θ(j)a(j)

n_iter_

int
終止計算的時候做了幾次的迭代

n_layers_

int
這個多層神經網路有幾層

n_outputs_

int
輸出單元的數量

out_activation_

string
回傳啟動函數的名稱

範例

取自官方網站
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_mldata
from sklearn.neural_network import MLPClassifier

#  取手寫辨視的資料集
mnist = fetch_mldata("MNIST original")
# rescale the data, use the traditional train/test split
X, y = mnist.data / 255., mnist.target  #  /255的部份就單純的簡單的標準化
X_train, X_test = X[:60000], X[60000:]
y_train, y_test = y[:60000], y[60000:]

# mlp = MLPClassifier(hidden_layer_sizes=(100, 100), max_iter=400, alpha=1e-4,
#                     solver='sgd', verbose=10, tol=1e-4, random_state=1)
mlp = MLPClassifier(hidden_layer_sizes=(50,), max_iter=10, alpha=1e-4,
                    solver='sgd', verbose=10, tol=1e-4, random_state=1,
                    learning_rate_init=.1)

mlp.fit(X_train, y_train)
print("Training set score: %f" % mlp.score(X_train, y_train))
print("Test set score: %f" % mlp.score(X_test, y_test))

fig, axes = plt.subplots(4, 4)
# use global min / max to ensure all weights are shown on the same scale
vmin, vmax = mlp.coefs_[0].min(), mlp.coefs_[0].max()
for coef, ax in zip(mlp.coefs_[0].T, axes.ravel()):
    ax.matshow(coef.reshape(28, 28), cmap=plt.cm.gray, vmin=.5 * vmin,
               vmax=.5 * vmax)
    ax.set_xticks(())
    ax.set_yticks(())

plt.show()

補充說明

label over 2

如果label超過2個,那可以透過獨熱編碼轉換為輸出單位。

sklearn的MLP是那一種?

Class MLPClassifier implements a multi-layer perceptron (MLP) algorithm that trains using Backpropagation
官方說明中很清楚的表示是反向傳播。

2017年10月13日 星期五

機器學習_ML_模型指標_roc_curve

機器學習_ML_模型指標_roc_curve

原文連結
適用性:Classification metrics

各種的數值計算都跟上面這張圖有關。(取自(維基百科))
this implementation is restricted to the binary classification task.
限於二類lable使用(0,1)or(1,-1),或是透過pos_label來設置。
一般我們在選擇分類模型的時候會使用ROC圖來觀察模型的效能,即透過真陽率(TPR)與假陽率(FPR)來做選擇,所以這是一個對P的概率估計。
以完美來說,當然是希望真陽率為1,而假陽為0。
FPR=FP/N
TPR=TP/P
N=(FP+TN)
P=(FN+TP)

IMPORT

from sklearn.metrics import roc_curve

參數

y_true

shape=n_samples
實際的標籤

y_score

shape=n_samples
屬真的機率

pos_label

default None {int str}
當設置了以後,以設置的為真,另一為假。
假如你的label是2,3
而設置了pos_label=3,則表示3為真,而2為假

sample_weight

權重

drop_intermediate

default True

屬性

fpr

假陽率

tpr

真陽率

thresholds

閥值

範例

import numpy as np
from sklearn.metrics import roc_curve
y = np.array([1, 1, 2, 2])
scores = np.array([0.1, 0.4, 0.35, 0.8])
fpr, tpr, thresholds = roc_curve(y, scores, pos_label=2)
fpr
tpr
thresholds
結果
>>> fpr
array([ 0. ,  0.5,  0.5,  1. ])
>>> tpr
array([ 0.5,  0.5,  1. ,  1. ])
>>> thresholds
array([ 0.8 ,  0.4 ,  0.35,  0.1 ])

範例說明

這邊說明上會有些許的複雜,但是我盡可能的白話文些。
roc的計算,會以真的機率(即score的設置)從大到小排序當做閥值(thresholds)。
此例來看,在計算時的排序會是如下
y score
2 0.8
1 0.4
2 0.35
1 0.1
這時候會發現,此排序與上面屬性排序相同。
接著,從第一個閥值開始,閥值以上即為真(此例為2)
故第一輪的時候為
yt=[2,1,2,1]
yp=[2,1,1,1]  #  閥值以上為真,故僅第一個為真
此時透過混洧矩陣來查看
tn, fp, fn, tp =confusion_matrix(yt,yp).ravel()
>>> tn
2
>>> fp
0
>>> fn
1
>>> tp
1
假陽率:FPR=FP/N = 0/2 = 0
真陽率:TPR=TP/P = 1/2 = 0.5
N=(FP+TN)
P=(FN+TP)
即屬性上tpr與fpr的數值。
依此邏輯計算四個閥值產生的fpr與tpr,
接著,再依序將這些點繪製於圖面上(x:fpr, y:tpr),即為著名的roc曲線!

圖面繪製

為什麼要用roc曲線呢?
因為roc曲線有個特性,當測試資料的真假樣本分佈變化的時候,roc曲線依然不變!
從roc曲線我們可以看的到整個模型效能。
一般來說,也會做一條對角線來做判斷(稱之為隨機機率),只要線落於對角線之外即代表該模型效能不佳。(比隨便亂猜還不如了)
搭配多折(StratifiedKFold)效果更好!
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve
import numpy as np

y = np.array([1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 2, 1, 2])
scores = np.linspace(0,0.9,20)  #  產生一個0~0.9的1x20向量
fpr, tpr, thresholds = roc_curve(y, scores, pos_label=2)
plt.plot(fpr,tpr,lw=1,label='roc')
plt.plot([0,0,1],[0,1,1],label='perfect', linestyle=':')
plt.plot([0,1],[0,1],label='judge', linestyle='--'])
plt.legend()
plt.show()

一般來說,數值愈多所產生的roc曲線圖會愈平滑!
改一下!
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve
import numpy as np

y = np.random.randint(1,3,500)  #  亂數產生500個1跟2
scores = np.linspace(0,0.9,500)  #  產生一個0~0.9的1x500向量
fpr, tpr, thresholds = roc_curve(y, scores, pos_label=2)
plt.plot(fpr,tpr,lw=1,label='roc')
plt.plot([0,0,1],[0,1,1],label='perfect', linestyle=':')
plt.plot([0,1],[0,1],label='judge', linestyle='--'])
plt.legend()
plt.show()

2017年10月11日 星期三

機器學習_ML_模型指標_accuracy

機器學習_ML_模型指標_accuracy

原文連結
適用性:Classification metrics

各種的數值計算都跟上面這張圖有關。(取自(維基百科))
(真真(TP)+真假(TN))/全部(TP+FP+FN+TN)
就是真的有預測到的比例有多高!

IMPORT

from sklearn.metrics import accuracy_score

範例

from sklearn.metrics import accuracy_score
y_true = [1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0 ,1]
y_pred = [0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1 ,1]
accuracy_score(y_true, y_pred)

結果

0.61538461538461542
from sklearn.metrics import accuracy_score
y_true = [1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0 ,1]
y_pred = [0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1 ,1]
accuracy_score(y_true, y_pred, normalize=False)
accuracy_score(y_true, y_pred)

結果

8

如果設定normalize是False(預設True),那回傳的就不是分數,而是真的預測到的筆數。
所以回傳的是8!
可以手動比對一下y_true與y_pred,確實是8筆預測正確。

機器學習_ML_模型評估

機器學習_ML_模型評估

原文連結
在使用GridViewCV或是cross_val_score做模型評估的時候,總是會需要我們做scoring的設定,好做效能指標!(另一篇混洧矩陣也記得閱讀)

各種的數值計算都跟上面這張圖有關。(取自(維基百科))

SCIKIT-LEARN

下面的表格取自SCIKIT-LEARN,已經有幫我們做好各種類型演算法的模型評估的LIB了。
配上上圖的說明,可以很快速的了解各種模型評估的數值來源。
Scoring Function Comment
Classification
accuracy accuracy_score
average_precision average_precision_score
f1 f1_score for binary targets
f1_micro f1_score micro-averaged
f1_macro f1_score macro-averaged
f1_weighted f1_score weighted average
f1_samples f1_score by multilabel sample
neg_log_loss log_loss requires predict_proba support
precision etc. precision_score suffixes apply as with f1
recall etc. recall_score suffixes apply as with f1
roc_auc roc_auc_score
Clustering
adjusted_mutual_info_score adjusted_mutual_info_score
adjusted_rand_score adjusted_rand_score
completeness_score completeness_score
fowlkes_mallows_score fowlkes_mallows_score
homogeneity_score homogeneity_score
mutual_info_score mutual_info_score
normalized_mutual_info_score normalized_mutual_info_score
v_measure_score v_measure_score
Regression
explained_variance explained_variance_score
neg_mean_absolute_error mean_absolute_error
neg_mean_squared_error mean_squared_error
neg_mean_squared_log_error mean_squared_log_error
neg_median_absolute_error median_absolute_error
r2 r2_score

2017年10月3日 星期二

Python-Pandas

Python_pandas:以諾貝爾得獎資料為例

記得先下載一下諾貝爾得獎資料,github上有得下載!

IMPORT

import pandas as pd
df = pd.read_csv('你的檔案位置或是網路連結')

基礎操作

範例_columns:取得所有欄位

df.columns

範例_set_index:設置索引

#  name的部份可以調整你要的欄位
df = df.set_index('name')  
#  依你要搜尋的name來下條件,就跟sql的where一樣
df.loc('xxxx')  
#  透過reset調整回來以數值搜尋
df = df.reset_index()

範例_iloc與loc

loc是以標籤(索引)來做搜尋,而iloc是以位置
df.iloc[2]

範例_groupby:選擇群組

phy_group = df.groupby('category')
phy_group.groups.keys()
phy_group = phy_group.get_group('physics')
phy_group.category  
pyh_group.head()

範例_透過布林遮罩顯示需求資料列

groupby之外的方法
df[df.category == 'physics']

建立DataFrame的方式

dict

df = pd.DataFrame.from_dict([
       {'name':'123','tel':123},
       {'name':'456','tel':456}
       ])
       

JSON

#  讀取json檔
df = pd.DataFrame.read_json('Source')
#  寫入json檔
json = df.to_json('Target', orient='records')

CSV

#  讀取csv,也可以搭配stringio將文字轉csv
#  sep用於定義分割符號
#  names用於欄位標題
from StringIO import StringIO
df = pd.read_csv('Source', 
                 sep=',', 
                 names=['head1','head2'...],
                 skipinitialspace=True,
                 quotechar="")
#  寫入csv
df.to_csv('Target', encoding='utf8')

EXCEL

excel的部份用到python的xlrd的lib,故要記得import!

方法一

dfs = []
xls = pd.ExcelFile('Source')
#  取得工作表,
df['Shee1'] = xls.parse('SourceSheet1',  #  來源excel的sheet
                        na_values=['NA'],  #  把什麼字串視為null
                        index_cols=1,  #  設定抬頭欄位索引是那一列
                        skiprows=3)  #  跳過幾行

方法二

df = pd.DataFrame.read_excel('SourceExcel',
                             ['SourceExcelSheet1', 'SourceExcelSheet2'],
                             index_col=None,
                             na_values=['NA'])                             
來源sheet的部份可以用名稱,也可以用索引
df_dict = pd.DataFrame.read_excel('SourceExcel', sheetname=None)
以上面的方式操作,就會把所有的工作表載到df_dict裡面
其餘的參數
parse_col=4 就代表取前5欄的資料
parse_col=[1, 4] 就代表取第2與第5欄的資料

寫入excel

df.to_excel('TargetExcel',sheet_name='SheetName')

SQL

MongoDB

mongoDB的部份,是以BSON(binary json)的格式來儲存。

讀取

from pymongo import MongoClient
client = MongoClient()
db = client.YourDB  #  取得資料庫
cursor = db.Yourdc.find()  #  取得Yourdc的所有文件
df = pd.DataFrame(list(cursor))

寫入

db = get_mongo_database('YourDB')
#  將dataframe轉dict,records代表把列轉為個別物件
records = df.to_dict('records')  
db[collection].insert(records)

Series轉DataFrame

Panel

理解上,就有點像是dataset,而DataFrame就是table!
df1 = pd.DataFrame({'abc':[1, 2, 3]})
df2 = pd.DataFrame({'def':[4, 5, 6]})
pn = pd.Panel({'item1':df1, 'item2':df2})
pn

資料清理

範例:info(資料檢索)

取得df上的資料、屬性、項目數量、記憶體用量
df.info()

由資料也可以看到,975列的資料,有些資料不足,那代表資料是有空缺的!

範例:describe(數值欄位統計摘要)

df.describe()

如果想要對其它類型也做出統計
df.describe(include=['object'])

圖可以看到,數量(count),不重覆值(unique),最高(top)…等有用資訊!
像美國就是最多的國家!

範例:head(取得前五筆資料)

df.head()

範例:tail(取得末五筆資料)

df.tail()

範例:isnull(查null資料)

取得資料為null的資料列
df.isnull()
回傳資料是null的話就是True

範例:isnull().sum()(查null各欄總數)

回傳各欄null數
df.isnull().sum()

範例:drop(移除資料集)

配合isnull的話,就可以移除null資料行
df = df[df.firstname.isnull() == False]
#  記得,是null就是True,所以非null就是False
要刪除整列的話
df.drop('surname', axis=1)
當然,null的部份除了直接移除之外也可以利用其它插補法來補值。

範例:取DataFrame欄

兩種方法都可以!
會回傳series物件,並保留DataFrame的索引
city_col = df.city
or
city_col = df['city']

範例:選擇多列

df[0:10]  #  取前10列
df[-4:0]  #  取最後4列

範例:利用條件取資料

mask = df.year > 2000
#  需注意mask此時為True, False
df[mask]  #  這樣子就能取得mask為True的資料
or
y2000 = df[df.year>2000]

範例:確認欄位型別

set(df.city.apply(type))

可以看出city這個欄位不乾不淨的兩個型別!

範例:replace取代字串

#  拿上面的y2000
dd = df.city
dd.replace('', np.nan, inplace=True)
dd.count()
#  整個df一起轉換
df.replace('',np.nan, inplace=True)
上面的語法可以把空格轉numpy的NaN格式
如此在計算的時候就不會把值加進去了!

範例:replace取代目標欄位數值

在資料預處理的時候,有時候我們會需要將字串標籤調整成數值標籤。
如True、False要改成1、0,
作法上,我們會先宣告一個dict,再透過pandas的replace來處理。
dict = {'label':{'True':1,'False':0}}      # label = column name
ata.replace(dict,inplace = True)
這樣,就可以把資料集內的字串調整成數值了。

範例:利用str+正則式清理資料,去空格,移除部份符號

df[df.name.str.contains('\*')]['name']  #  顯示有*的資料
df.name = df.name.str.replace('*','')  #  取代*
df.name = df.name.str.strip()  #  去空格

2017年10月2日 星期一

臺灣走走-龍鳳漁港

臺灣走走-龍鳳漁港


龍鳳漁港位於竹南鎮龍鳳里,這幾年不少志工會早起(AM5:00)做淨灘的活動,所以海灘愈來愈漂亮。
不過好的景點還是需要有水準的人民共同來維護!
夏天來這邊會看到很多的家長帶齊工具與小孩一起來這挖泥挖沙,不過老一輩的總是覺得七、八月帶去海邊不吉利,哈哈。

但是不信邪的我還是很喜歡帶著小孩去就是了。
基本上這邊不適合做沖浪,不然我也很想試一下。

有活動的時候也會擠的水洩不通的,不過夏天下午的時候真的很適合一遊。
記得也去龍鳳宮拜個媽祖求個平安。