2017年9月28日 星期四

機器學習_ML_confusion_matrix(混淆矩陣)

機器學習_ML_confusion_matrix(混淆矩陣)

原文連結
Compute confusion matrix to evaluate the accuracy of a classification
計算混淆矩陣來評估準確性!
這個矩陣代表著{真真、假假、真假、假真}
透過這四個預估也計算著不同準確評估的數值。

IMPORT

from sklearn.metrics import confusion_matrix

範例

from sklearn.metrics import confusion_matrix
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]
confusion_matrix(y_true=y_true, y_pred=y_pred)
結果
array([[3, 2],
       [3, 5]], dtype=int64)
這樣…似乎有點不能理解這個矩陣到底是什麼意思!!
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
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]
confmat = confusion_matrix(y_true=y_true, y_pred=y_pred)
fig, ax = plt.subplots(figsize=(2.5, 2.5))
ax.matshow(confmat, cmap=plt.cm.Blues, alpha=0.3)
for i in range(confmat.shape[0]):
    for j in range(confmat.shape[1]):
        ax.text(x=j, y=i, s=confmat[i,j], va='center', ha='center')
plt.xlabel('predicted label')        
plt.ylabel('true label')
plt.show()
把圖表列印出來,就清楚多了。

原文範例有一個多類別的矩陣function,可以參考一下。
原文範例連結

延伸說明

那為什麼說可以利用這個矩陣來評估模型呢?
請看下圖(取自維基百科)

上圖說明著,我們常在scikit-learn用的score的模型評估來源!

最常見的accuracy準確率,就是(真真加上真假)/總數
所以,一定要認識一下這個圖。

2017年9月20日 星期三

機器學習-ml-gridsearchcv-網格搜尋

機器學習_ML_GridSearchCV_網格搜尋

官方連結說明
Exhaustive search over specified parameter values for an estimator.
開宗明義的一句話,就是極盡所能的對所有指定的參數做搜尋,故稱之為暴力搜尋。
透過GridSearchCV我們可以對所設置的所有參數做所有的可能排列組合下去測,然後取得一個最佳參數。相對的,這部份的取得成本是非常可觀的。
個人用了50k筆資料,測了幾個條件去做,印象中是跑了5小時才結束…
Important members are fit, predict.
重點是模型要有fit跟predict這兩個方法!!
也可以搭配著pipeline來執行,就不用另外再做個標準化或pca的動作,讓pipeline來處理就可以。

IMPORT

from sklearn.model_selection import GridSearchCV

CLASS

class sklearn.model_selection.GridSearchCV(
    estimator, param_grid,  scoring=None, 
    fit_params=None, n_jobs=1,    iid=True,  
    refit=True,  cv=None, verbose=0,   
    pre_dispatch='2*n_jobs',  error_score='raise',      
    return_train_score=True  

參數說明

estimator

使用的分類器

param_grid

list 或是 dict 做最佳化的參數

scoring

default None
None的時候即使用estimator的預設score

fit_params

丟給fit的參數,不過0.19版之後已經不用了

n_jobs

defualt 1
使用多少CPU執行緒,如果設置-1就是火力全開!
may raise errors if the dataset is large and not enough memory is available
如果設置-1或>1的話,在數據量過大的情況下就可能會因為記憶體不足error

iid

default True
設置為True時即假設在折疊中樣本概率分佈一致,損失估計為所有樣本總合,而非平均。

refit

default True
設置為true的話,會在最後取得最佳參數之後再以該參數做fit一次全部的資料。

cv

default 3
交叉驗證,將資料分n份
可以是整數、交叉驗證或一個可迭代器
None:默認為3
整數n:n折交叉驗證
另篇文字分詞的演算法是以5來計算,這個部份的用途主要是將資料分群之後交叉取得較佳模型。
For integer/None inputs, if the estimator is a classifier and y is either binary or multiclass, StratifiedKFold is used. In all other cases, KFold is used.
說明也提到,預設情況下是以KFold來處理的。除非你是多分類才會以StratifiedKFold。
那KFold與StratifiedKFold的話,我們另篇再說簡單說明。

verbose

default 0
設置為0即訓練過程不會顯示,為1的話偶爾顯示,大於1的時候必顯示。

pre_dispatch

default
指定總共分發的並行任務,似乎是用來控制CPU使用率。
None-所有作業立即展開,用在較小型的測試作業!
int-要指定確切數量
String-2*n_jobs
. A workaround in this case is to set pre_dispatch. Then, the memory is copied only pre_dispatch many times. A reasonable value for pre_dispatch is 2 * n_jobs.
在api說明下,建議設置是2 * n_jobs

error_score

default raise

return_train_score

default True {‘True’, ‘False’}
如果設置False就不會回傳結果!
即屬性cv_results_ 就不會有分數的值了。

方法

decision_function(X)

Call decision_function on the estimator with the best found params.
只有在refit=True跟分類器可以實作的時候才有效果。
以最佳參數執行!
主要取得X的

fit(X[, y, groups])

適合、訓練模型(開始用設置的參數開始暴力測試)

get_params([deep])

取得模型參數

inverse_transform(Xt)

Call inverse_transform on the estimator with the best found params.
只有在refit=True跟分類器可以實作的時候才有效果。
以最佳參數執行!
各演算法的inverse_transform意義不同,可參閱SKlearn的api說明!

predict(X)

Call predict on the estimator with the best found parameters.
用最佳參數來做預測,特別貼出來說明是取最佳參數來做預測!

predict_log_proba(X)

回傳類別概率對數(機率、或然率)…一樣是以最佳參數來執行

predict_proba(X)

回傳類別概率(機率、或然率)…一樣是以最佳參數來執行

score(X[, y])

看你的上面參數SCROING設置來回傳,上面是NONE就以選擇的分類器的SCORE為預設

set_params(**params)

設置模型參數

transform(X)

Call transform on the estimator with the best found parameters.
以最佳參數來做轉換,但一樣要分類器可以實作!

屬性

cv_results_

這邊記錄著你的所有參數的狀況,是個dict(字典)形態。
可以直接丟給pandas
以下面的範例去看的話,就是下面這樣子!
{
'param_kernel': masked_array(data = ['poly', 'poly', 'rbf', 'rbf'],
                             mask = [False False False False]...)
'param_gamma': masked_array(data = [-- -- 0.1 0.2],
                            mask = [ True  True False False]...),
'param_degree': masked_array(data = [2.0 3.0 -- --],
                             mask = [False False  True  True]...),
'split0_test_score'  : [0.8, 0.7, 0.8, 0.9],
'split1_test_score'  : [0.82, 0.5, 0.7, 0.78],
'mean_test_score'    : [0.81, 0.60, 0.75, 0.82],
'std_test_score'     : [0.02, 0.01, 0.03, 0.03],
'rank_test_score'    : [2, 4, 3, 1],
'split0_train_score' : [0.8, 0.9, 0.7],
'split1_train_score' : [0.82, 0.5, 0.7],
'mean_train_score'   : [0.81, 0.7, 0.7],
'std_train_score'    : [0.03, 0.03, 0.04],
'mean_fit_time'      : [0.73, 0.63, 0.43, 0.49],
'std_fit_time'       : [0.01, 0.02, 0.01, 0.01],
'mean_score_time'    : [0.007, 0.06, 0.04, 0.04],
'std_score_time'     : [0.001, 0.002, 0.003, 0.005],
'params'             : [{'kernel': 'poly', 'degree': 2}, ...],
}

best_estimator_

最佳分類器,如果refit是False就沒有效果!
SVC(C=10, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape='ovr', degree=3, gamma=0.001, kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)

best_score_

最佳分類器的平均驗證得分。(記得我們有分折吧!)

best_params_

取得最佳參數

best_index_

在cv_results_中的最佳參數的索引值

scorer_

記錄你的評分指標(記得下面範例的迴圈吧!用了recall(召回率)跟precision)
make_scorer(recall_score, pos_label=None, average=macro)

n_splits_

cv的保存!

結果保存

GridSearchCV計算之後,結果是存放在(.cv_results_)中,可以透過pandas直接to_csv存入csv檔即可。
cv_result = pd.DataFrame.from_dict(clf.cv_results_)
with open('cv_result.csv','w') as f:
  cv_result.to_csv(f)

範例

原文說明上有一個範例不錯,可以看一下。
下面的範例看懂了,大概就懂了,整個複製貼上到你的環境去跑,把每個參數都run出來確認它的狀態!
連結
#  Import需求lib
from __future__ import print_function

from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import classification_report
from sklearn.svm import SVC

print(__doc__)

# 讀入sklearn的範例資料
digits = datasets.load_digits()

#  資料預處理
# To apply an classifier on this data, we need to flatten the image, to
# turn the data in a (samples, feature) matrix:
n_samples = len(digits.images)  #  1797筆
X = digits.images.reshape((n_samples, -1))
y = digits.target

# 資料切割訓練與測試集
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.5, random_state=0)

# 要給gv的參數,可以看到正規化的惩法給了四個,gamma也給了兩個 kernel也用了rbf跟liner
tuned_parameters = [{'kernel': ['rbf'], 'gamma': [1e-3, 1e-4],
                     'C': [1, 10, 100, 1000]},
                    {'kernel': ['linear'], 'C': [1, 10, 100, 1000]}]

#  評估模型的計算得分設置了兩個,並用迴圈來執行這個gv
scores = ['precision', 'recall']

for score in scores:
    print("# Tuning hyper-parameters for %s" % score)
    print()
    #  以5折下去做暴力尋參,用svc來做分類器
    clf = GridSearchCV(SVC(), tuned_parameters, cv=5,
                       scoring='%s_macro' % score)
    clf.fit(X_train, y_train)

    print("Best parameters set found on development set:")
    print()
    #  列印最佳參數
    print(clf.best_params_)
    print()
    print("Grid scores on development set:")
    print()
    #  設置陣列的資料,記得參閱api
    means = clf.cv_results_['mean_test_score']
    stds = clf.cv_results_['std_test_score']
    #  這邊依設置的參數列印出所有參數的得分狀況
    for mean, std, params in zip(means, stds, clf.cv_results_['params']):
        print("%0.3f (+/-%0.03f) for %r"
              % (mean, std * 2, params))
    print()

    print("Detailed classification report:")
    print()
    print("The model is trained on the full development set.")
    print("The scores are computed on the full evaluation set.")
    print()
    y_true, y_pred = y_test, clf.predict(X_test)
    print(classification_report(y_true, y_pred))
    print()

# Note the problem is too easy: the hyperparameter plateau is too flat and the
# output model is the same for precision and recall with ties in quality.
模型結果
Automatically created module for IPython interactive environment
# Tuning hyper-parameters for precision

Best parameters set found on development set:

{'C': 10, 'gamma': 0.001, 'kernel': 'rbf'}

Grid scores on development set:

0.986 (+/-0.016) for {'C': 1, 'gamma': 0.001, 'kernel': 'rbf'}
0.959 (+/-0.029) for {'C': 1, 'gamma': 0.0001, 'kernel': 'rbf'}
0.988 (+/-0.017) for {'C': 10, 'gamma': 0.001, 'kernel': 'rbf'}
0.982 (+/-0.026) for {'C': 10, 'gamma': 0.0001, 'kernel': 'rbf'}
0.988 (+/-0.017) for {'C': 100, 'gamma': 0.001, 'kernel': 'rbf'}
0.982 (+/-0.025) for {'C': 100, 'gamma': 0.0001, 'kernel': 'rbf'}
0.988 (+/-0.017) for {'C': 1000, 'gamma': 0.001, 'kernel': 'rbf'}
0.982 (+/-0.025) for {'C': 1000, 'gamma': 0.0001, 'kernel': 'rbf'}
0.975 (+/-0.014) for {'C': 1, 'kernel': 'linear'}
0.975 (+/-0.014) for {'C': 10, 'kernel': 'linear'}
0.975 (+/-0.014) for {'C': 100, 'kernel': 'linear'}
0.975 (+/-0.014) for {'C': 1000, 'kernel': 'linear'}

Detailed classification report:

The model is trained on the full development set.
The scores are computed on the full evaluation set.

             precision    recall  f1-score   support

          0       1.00      1.00      1.00        89
          1       0.97      1.00      0.98        90
          2       0.99      0.98      0.98        92
          3       1.00      0.99      0.99        93
          4       1.00      1.00      1.00        76
          5       0.99      0.98      0.99       108
          6       0.99      1.00      0.99        89
          7       0.99      1.00      0.99        78
          8       1.00      0.98      0.99        92
          9       0.99      0.99      0.99        92

avg / total       0.99      0.99      0.99       899


# Tuning hyper-parameters for recall

Best parameters set found on development set:

{'C': 10, 'gamma': 0.001, 'kernel': 'rbf'}

Grid scores on development set:

0.986 (+/-0.019) for {'C': 1, 'gamma': 0.001, 'kernel': 'rbf'}
0.957 (+/-0.029) for {'C': 1, 'gamma': 0.0001, 'kernel': 'rbf'}
0.987 (+/-0.019) for {'C': 10, 'gamma': 0.001, 'kernel': 'rbf'}
0.981 (+/-0.028) for {'C': 10, 'gamma': 0.0001, 'kernel': 'rbf'}
0.987 (+/-0.019) for {'C': 100, 'gamma': 0.001, 'kernel': 'rbf'}
0.981 (+/-0.026) for {'C': 100, 'gamma': 0.0001, 'kernel': 'rbf'}
0.987 (+/-0.019) for {'C': 1000, 'gamma': 0.001, 'kernel': 'rbf'}
0.981 (+/-0.026) for {'C': 1000, 'gamma': 0.0001, 'kernel': 'rbf'}
0.972 (+/-0.012) for {'C': 1, 'kernel': 'linear'}
0.972 (+/-0.012) for {'C': 10, 'kernel': 'linear'}
0.972 (+/-0.012) for {'C': 100, 'kernel': 'linear'}
0.972 (+/-0.012) for {'C': 1000, 'kernel': 'linear'}

Detailed classification report:

The model is trained on the full development set.
The scores are computed on the full evaluation set.

             precision    recall  f1-score   support

          0       1.00      1.00      1.00        89
          1       0.97      1.00      0.98        90
          2       0.99      0.98      0.98        92
          3       1.00      0.99      0.99        93
          4       1.00      1.00      1.00        76
          5       0.99      0.98      0.99       108
          6       0.99      1.00      0.99        89
          7       0.99      1.00      0.99        78
          8       1.00      0.98      0.99        92
          9       0.99      0.99      0.99        92

avg / total       0.99      0.99      0.99       899

2017年9月10日 星期日

機器學習_ML_ExtraTreesClassifier(極限樹)

機器學習_ML_ExtraTreesClassifier(極限樹)

Extremely Randomized Trees
原文說明
原文API
極限樹是tree的一種,但是跟隨機森林一樣,都是歸類在整體學習(ensemble)中,不同於隨機森林,隨機森林在隨機產生了樹之後,那個樹會以熵為主去做樹,但極限樹,沒有極限,一切隨緣,以此方式來減少變異數(方差)。
instead of looking for the most discriminative thresholds,
thresholds are drawn at random for each candidate feature
模型的大小:O(M * N * log (N))
M:樹的數量
N:樣本數量
可以再搭配下列參數來控制
min_samples_split, min_samples_leaf, max_leaf_nodes and max_depth.

IMPORT

from sklearn.ensemble import ExtraTreesClassifier

CLASS

ExtraTreesClassifier(n_estimators=10, criterion=’gini’, 
                    max_depth=None, min_samples_split=2, 
                    min_samples_leaf=1, min_weight_fraction_leaf=0.0,
                    max_features=’auto’, max_leaf_nodes=None, 
                    min_impurity_decrease=0.0, min_impurity_split=None,
                    bootstrap=False, oob_score=False, n_jobs=1,
                    random_state=None, verbose=0, warm_start=False, 
                    class_weight=None)

參數說明

The main parameters to adjust when using these methods is n_estimators and max_features

n_estimators

default 10
k值_決策樹樹量
The larger the better(愈大愈好,但跟學習成本是正相關)

criterion

default gini {gini, entropy}
entropy_熵
原文特別說明,這個參數是決策樹才有的!

max_depth

default None
建議None搭配min_samples_split=1,但會需要大量記憶體

min_samples_split

default=1
建議搭配max_depth=None,但會需要大量記憶體

min_samples_leaf

default 1
每一節點的最小樣本數

min_weight_fraction_leaf

default 0
權重總和的最小加權分數,若未設置則權重相同。

max_features

default auto
auto:max_features=sqrt(n_features).
sqrt:max_features=sqrt(n_features).
log2:max_features=log2(n_features).
None:max_features=n_features.
max_features=n_features for regression(極限樹迴歸)
max_features=sqrt(n_features) for classification(極限樹分類)

max_leaf_nodes

default None
最大節點數,未設置就是不限制

min_impurity_decrease

default 0
似乎是個節點門檻值…需要再研究
原文說明來看是該節點與全樣本的比例如果過低,就刪除該節點?
N_t / N * (impurity - N_t_R / N_t * right_impurity
                    - N_t_L / N_t * left_impurity)

min_impurity_split

0.19之後不再用,改用min_impurity_decrease

bootstrap

default False
搭配oob_score=True

oob_score

default False
是否用額外樣本來估算廣義精度
搭配bootsrap=True

n_jobs

default 1
使用多少CPU核心數
-1代表火力全開

random_state

default None
亂數種子

verbose

default 0
過程是否顯示

warm_start

default False
是否用上次的結果來加入計算,或是重新產生樹。
預設是重新產生樹

class_weight

default None
balance:n_samples / (n_classes * np.bincount(y))
balanced_subsample:理論同上,除了根據每棵樹生長的引導樣本計算權重

方法

apply(X)

回傳每個樣本的決策樹索引
array([[ 3,  5,  4, ..., 12,  4,  6],
       [31, 38, 36, ..., 37, 33, 41],
       [34, 40, 40, ..., 37, 33, 42],
       ...,
       [ 3,  6,  4, ..., 14,  4,  6],
       [32, 40, 40, ..., 38, 34, 44],
       [ 2,  4,  2, ...,  3,  1,  2]], dtype=int64)

decision_path(X)

回傳樹的決策路徑,似乎是個物件。
(<105x372 sparse matrix of type '<class 'numpy.int64'>'
        with 5753 stored elements in Compressed Sparse Row format>,
        array([  0, 35,  76, 117, 144, 177, 210, 253, 292, 327, 372],
        dtype=int32))

fit(X, y[, sample_weight])

適合(訓練)資料集

get_params([deep])

取得參數

predict(X)

回傳預測分類

predict_log_proba(X)

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

predict_proba(X)

回傳類別概率(機率、或然率)
可以看到每一筆資料在這個模組中的預測

score(X, y[, sample_weight])

這邊的得分是回傳平均準確率

set_params(**params)

設置參數

屬性

estimators_

產生的樹的列表,看你設定產生幾棵樹就有多少資料

classes_

回傳目標標籤,依範例為[0, 1, 2]

n_classes_

回傳目標標籤個數,依範例為3

feature_importances_

回傳特徵權重
>>> extra_tree.feature_importances_
array([ 0.49439825,  0.50560175])

n_features_

回傳fit的時候用的特徵數,依範例為2

n_outputs_

回傳fit的時候的輸出,依範例為1

oob_score_

oob_decision_function_

範例

from sklearn import datasets
import numpy as np
iris = datasets.load_iris()
X = iris.data[:, [2, 3]]
y = iris.target

#  如果是2.0版的話,from sklearn.model_selection import train_test_split
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test =  train_test_split(
X, y, test_size=0.3, random_state=0)

from sklearn.ensemble import ExtraTreesClassifier
extra_tree = ExtraTreesClassifier(criterion='entropy',
                              n_estimators=10,
                              random_state=1,
                              n_jobs=-1)
                             
extra_tree.fit(X_train, y_train)
extra_tree.score(X_train, y_train)
extra_tree.feature_importances_  #  特徵權重

Python Flask.Blueprint

Python Flask.Blueprint

簡單

Blueprint可用來設置route,專案只要一大,整個api或是web的route就會跟著複雜。
總不可能把所有的route都設置在同一支程式上,這樣子對整個專案的維護性過低。
不過如果你只有一個api的話…記得就放同一支就好了!

範例

主程式
#  __init__.py

from flask import Flask
from manu import testRoute

app = Flask('__name__')
app.register_blueprint(testRoute)

if __name__ == '__main__':
    app.run(debug=True)
生產用route
#  manu.py

from flask import Blueprint
testRoute = Blueprint('testRoute', __name__)

@testRoute.route('/manu/manu1')  #  路由上標名了生產
def testroute():
    return '<h1>You win!</h1>'

@testRoute.route('/manu/manu2')  #  路由上標名了生產
def testroute2():
    return '<h1>You win2!</h1>'

@testRoute.route('/manu/manu3')  #  路由上標名了生產
def testroute3():
    return '<h1>You win3!</h1>'
連結網址
http://127.0.0.1:5000/manu/manu1

加上前綴

你要建構的是一個讓很多route可以清楚分開交通網是吧。
這是一個生產用的route,以後會有財務、業務…等,沒錯吧!
所以我們希望這個路由是區隔而且明確的。
可是你不可能吃飽閒閒每一個路由都寫著’/manu/xxx’,’/manu/yyy/’…
太不科學了,所以我們就會需要用到url_prefix了!
註冊url_prefix有兩個方式,一個是在產生Blueprint物件的時候給,一個是在註冊的時候給!
#  產生物件的時候
testRoute = Blueprint('testRoute', __name__, url_prefix='/manu')
#  註冊blueprint的時候
app.register_blueprint(testRoute, url_prefix='/manu')
基本上,原廠建議是在註冊的時候再給,日後好維護。

範例

要來調整一下我們的程式…
#  __init__.py

from flask import Flask
from manu import testRoute

app = Flask('__name__')
app.register_blueprint(testRoute, url_prefix='/manu')

if __name__ == '__main__':
    app.run(debug=True)
from flask import Blueprint
testRoute = Blueprint('testRoute', __name__)

@testRoute.route('/manu1')  #  路由拿掉剛才標上的生產
def testroute():
    return '<h1>You win!</h1>'

@testRoute.route('/manu2')  #  路由拿掉剛才標上的生產
def testroute2():
    return '<h1>You win2!</h1>'

@testRoute.route('/manu3')  #  路由拿掉剛才標上的生產
def testroute3():
    return '<h1>You win3!</h1>'
連結網址
http://127.0.0.1:5000/manu/manu2
這樣,程式碼是不是優美多了!

Python_Matplotlib

Python_Matplotlib

IMPORT

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

載入資料集

如果想要多點測試數據的話,就自己弄個亂數!
產生500個亂數,再把顏色©部份改成t就可以
numpy可以改天整理好再po上來。
n = 500
x = np.random.normal(0,1,n)
y = np.random.normal(0,1,n)
t = np.arctan2(y,x)
或是
x = [1, 2, 3, 4, 5, 6, 7, 8]
y = [8, 7, 6, 5, 4, 3, 2, 1]

共用設置

標籤、圖面、標題…等產生圖面的時候會共同使用到的!
要用什麼就執行什麼,大概就是疊床架屋的概念,在你執行plt.show()之前,你執行的每一步都會被記錄下來!
要產生網格,那就執行plt.grid(),要隱藏x軸座標,那就執行plt.xticks(())!
要預設就好,你也可以丟給xy給scatter直接show。
plt.scatter(x,
            y, 
            label='Test', 
            color='red', 
            s=25,     
            marker="o")
plt.xlim(0,20)  #  x軸的座標軸範圍
plt.ylim(0,20)  #  y軸的座標軸範圍
plt.xlabel('xlabel')  #  產生x軸的標籤
plt.ylabel('ylabel')  #  產生y軸的標籤
plt.title('Title')  #  產生圖面的標題
plt.legend(loc='upper right')  #  圖標
plt.grid()  #  顯示網格
plt.show()  #  產生圖面

如果故意讓xlim的範圍值小於來源值行不行?

當然行,只是圖看起來就是上面的樣子了!切掉!
所以,可以配合max與min來做座標範圍的設置,或是乾脆不設置了,讓系統自帶也可以!
簡單說,lib的部份專家都寫的很好了,交給lib自己來,不喜歡的再來微調就可以了。
plt.xticks(())  #  隱藏x軸座標
plt.yticks(())  #  隱藏y軸座標

plt.figtext(x,y,'文字',ha='right',va='bottom')
#  圖表上添加文字
#  x:x軸,y:y軸,ha:水平,va:垂直
plt.text(x,y,'文字',fontsize = 12)
#  x:x軸,y:y軸
plt.tight_layout()  #  保證所有元素都會出現圖表上
plt.savefig('aaa.格式')  #  保存圖表

plt.legend

plt.legend用於產生圖標!
透過loc可以調整上下左右中
用法不少,可參閱原文說明
設定plt.legend(loc=‘best’)可以避免遮住圖表線條
plt.legend(loc='best',  #  圖標位置
           framealpha=0.5  #  透明度0-1)

scatter:散布(點)圖

透過散布圖可以很快的發現到數據密度集中度以及分佈,是數據分析的時候常用的一個圖。
在做線性迴歸時會配合原始資料的散布以及那條心目中的線呈現來做一個圖面判斷
x = [1, 2, 3, 4, 5, 6, 7, 8]
y = [8, 7, 6, 5, 4, 3, 2, 1]
plt.scatter(x,
            y,
            label='ScatterPic',
            c='red',      
            s=50,
            marker='X',
            alpha=0.5 ,
            edgecolors='green')
plt.legend()            
plt.show()       

資料多比較有fu
基本上,你不想設定太多的話,就給它xy也是可以直接執行。
但是如果希望透過一點不一樣來呈現,那就是像開頭說的,再依參數微調。

參數說明

基本上參數不止這些,只是挑較常用的說明而以!
x:x軸的座標資料集
y:y軸的座標資料集
label:標籤(搭配plt.legend())
c:點點的顏色
s:點點的大小
marker:點點的圖示
alpha:透明度,介於0-1
edgecolors:外環的顏色

marker:點點的圖示種類

更多的點點在原文連結
代碼 圖示 代碼 圖示
‘o’
‘v’ ‘^’ ![] (https://i.imgur.com/GhxOnXS.png)
‘<’ ‘>’
‘8’ ‘s’
‘p’ ‘*’
‘h’ ‘H’
‘D’ ‘d’
‘P’ ‘X’

bar:直條圖

經典圖,不能不會用!
labels = ['A', 'B', 'C', 'D']  #  直條圖的標籤
foo_val = [10, 3, 5, 7]  #  資料來源
ind = np.arange(len(labels))  #  直條圖的位置(0, 1, 2, 3)
plt.xticks(ind, labels)  #  x軸的座標
plt.bar(left=ind, 
        height=foo_val, 
        width=0.5,
        color='green',
        edgecolor='red')
plt.show()        

圖框的大小記得可以透過plt.xlim(),plt.ylim()來設置!

參數說明

left:設置x的起始座標
height:高度,即數值
width:直條圖寬度
bottom:y軸的初始值
color:直條圖的顏色
edgecolor:直條圖的外圍顏色
參數還有很多,只是常用的拉出來說明而以。

群組直條圖

labels = ['A', 'B', 'C', 'D']  #  直條圖的標籤
foo_val = [10, 3, 5, 7]  #  資料來源
foo_val2 = [5, 4, 3, 2]  #  資料來源2
ind = np.arange(len(labels))  #  直條圖的位置(0, 1, 2, 3)
bar_width=0.4  #  間隔的產生
plt.bar(left=ind-bar_width,   #  讓一個寬度給他先入-0.4,0.6,1.6,2.6
        height=foo_val, 
        width=bar_width,
        color='green',
        edgecolor='red')
plt.bar(left=ind, 
        height=foo_val2, 
        width=bar_width,
        color='blue',
        edgecolor='white')  
plt.show()   

接下來要上標籤
所以再來調整一下!
#  產生y軸標用
def ylabel(Bars): 
    for Bar in Bars:
        height = Bar.get_height()  #  透過迴圈每個bar都加上去
        #  matplotlib.pyplot.text(x, y, s, fontdict=None, withdash=False, **kwargs)
        #  xy是座標,s是文字!透過迴圈每個bar都加上去!
        plt.text(Bar.get_x()+Bar.get_width()/5., 1.02*height, '%s' % float(height))
#  記得每個圖都是一個一個堆出來的吧!        
        
labels = ['A', 'B', 'C', 'D']  #  直條圖的標籤
foo_val = [10, 3, 5, 7]  #  資料來源
foo_val2 = [5, 4, 3, 2]  #  資料來源2
ind = np.arange(len(labels))  #  直條圖的位置(0, 1, 2, 3)
bar_width=0.4  #  間隔的產生
Bars = plt.bar(left=ind-bar_width,   #  讓一個寬度給他先入-0.4,0.6,1.6,2.6
        height=foo_val, 
        width=bar_width,
        color='green',
        edgecolor='red',
        label='GreenBar')
ylabel(Bars)  #  產生座標說明       
Bars = plt.bar(left=ind, 
        height=foo_val2, 
        width=bar_width,
        color='blue',
        edgecolor='white',
        label='BlueBar')   
ylabel(Bars)  #  產生座標說明   
#  調整標籤        
plt.yticks(range(15))  #  拉大y軸
plt.xticks(ind-0.2,labels)  #  位置、標籤
plt.title('Matplotlib Bar')
plt.legend(loc='best')  #  顯示標籤
plt.grid(axis='y', ls=':')  #  只讓y軸有線,並且調整格線
plt.show()   

這樣就人模人樣了!

堆疊直條圖



橫條圖

直線

原文連結
plt.plot(x,
         y,
         marker='x',
         c='red',
         ms=0.5,
         ls='dashdot',
         lw=1)

plt.show()

參數說明

x:1D陣列來源資料
y:1D陣列來源資料
marker:點點的型狀
c:線的顏色
ms:點點的大小
ls:線的型狀
lw:線的寬度
參數還有很多,只是常用的拉出來說明而以。

散布(點)圖矩陣

參數說明

相關矩陣

參數說明

加入子圖表

如果要像股票一樣,有個大表可能是個股,然後小表是目前的股市表現!
#  定義一個大相框
fig = plt.figure(figsize=(8, 4))
#  你要的個股資料
#  左下(0.1, 0.1)與右上(0.8, 0.8)的位置
#  如果設置1就全開紙了
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
#  加入股市表現
ax = fig.add_axes([0.15, 0.15, 0.3, 0.3])
plt.show()

多圖表

其實,不只是在加入子圖表的時候使用,一般情況下也是可以這樣子使用。
又或者,現在在網路看到的大部份範例(含原廠文件)也是這樣子用!
fig, ax = plt.subplots(figsize=(8, 4),  #  大相框尺寸
                       dpi=100,  #  每英吋幾個點
                       tight_layout=True,  #  把所有東西限縮在大相框內
                       linewidth=1,  #  寬
                       edgecolor='r')  #  大相框顏色
在呼叫subplots的時候,會回傳一個有一組axes的figure物件
fig(figure):把它想成是一個有N格相框的『大相框』!
ax(axes或稱軸):把它想成是上面N格相框中的其中一個『相框』!
只是大部份的時候我們用的都是一格相框罷了!
接下來的動作沒有不一樣!
scatter = ax.scatter(x, y, label='TestScatter')
ax.legend(loc='best')
ax.set_title('TestScatter')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.grid(True)
fig.text(0.995,0.01,'test',ha='right',va='bottom')
fig.tight_layout()
plt.show()

所以,當我們明白了,原來figure是一個大相框可以給我放入N張照片的時候,還客氣什麼?
fig, ax = plt.subplots(nrows=3,  #  要三個橫軸
                       ncols=1,  #  要一個直軸
                       sharex=True,  #  是否共用x軸座標
                       sharey=True,  #  是否共用y軸座標
                       figsize=(8,4))
ax0 = ax[0]
ax0.scatter(x,y, label='axes0')
ax0.legend(loc='best')
ax1 = ax[1]
ax1.scatter(x,y, label='axes1')
ax1.legend(loc='best')
ax2 = ax[2]
ax2.scatter(x,y, label='axes2')
ax2.legend(loc='best')
plt.show()

還有沒有其它的方法?
有的!
#  當你做了plt.subplot的時候,你把這個控制權拉到上面呼叫的圖表。
plt.subplot(221)
plt.scatter(x, y, label='221')
plt.legend(loc='best')
plt.subplot(222) 
plt.scatter(x, y, label='222')
plt.legend(loc='best')
plt.subplot(212) 
plt.scatter(x, y, label='211')
plt.legend(loc='best')
plt.show()

差別在於一個是用全域的plt來做操作,一個是以物件導向的方式來操作!
都可以做,挑一個吧。

左右箭頭

官方說明
import matplotlib.pylab as plt
import matplotlib.patches as patches

#  設置一個大相框,大小為8*8
fig1 = plt.figure(figsize=[8,8])
#  加入一張照片
ax1 = fig1.add_subplot(111,aspect = 'equal')
ax1.add_patch(
    patches.Arrow(0.45,0.5,-0.25,0.25,width=0.3,color='green',alpha = 0.5)
    )  #  patches.Arrow(x, y, dx, dy, width=1.0, **kwargs)    
ax1.add_patch(
    patches.Arrow(0.5,0.45,0.25,-0.25,width=0.3,color='red',alpha = 0.5)
    )  #  patches.Arrow(x, y, dx, dy, width=1.0, **kwargs)
plt.show()

參數說明

由x往dx、y往dy方向去指向,所以指左dx是-0.25,指下的dy是-0.25
width為箭頭胖瘦控制
記得下去操作一次感受差異

2017年9月4日 星期一

機器學習_ML_train_test_split

機器學習_ML_train_test_split

切割數據集,做訓練與驗證使用!

IMPORT

from sklearn.model_selection import train_test_split

範例

x:特徵資料集
y:目標資料集
test_size=0.3:代表切了3成去做測試數據集!
random_state:亂數種子,每次設置一樣所得亂數相同!
import pandas as pd
df = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/housing/housing.data', header=None, sep='\s+')

df.columns = ['CRIM', 'ZN', 'INDUS', 'CHAS', 
              'NOX', 'RM', 'AGE', 'DIS', 'RAD', 
              'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV']
#  驗證一下資料有沒有進來
df.head()

x = df[['RM']].values
y = df['MEDV'].values

X_train, X_test, y_train, y_test = train_test_split(X, 
                                                    y, 
                                                    test_size=0.3, 
                                                    random_state=0)

2017年9月3日 星期日

機器學習-ML-k-means

機器學習_ML_K_MEANS

K_MEANS取的是虛擬點,依你所挑的k個值心開始,由虛擬點開始一直迭代計算中心值。
離群值本身對中心點影響性大,適用於大資料集!
本身所採用的是歐幾理德距離,就是我們國高中學的,x1-x2的平方加上y1-y2的平方然後開根號!
  • 從樣本點中隨機挑選k個質心(centroid:連續值的平均)作為初始集群中心
  • 指定每個樣本到它最近的質心
  • 移動質心到被分配給它的樣本點的中心
  • 重複2,3步直到群集分配不再改變,或是達到使用者定義的可容語誤差,或是最大迭代次數。
虛擬點所指為,該點非資料集本身。
相較於init由亂數(random)來決定,另一種方式為k-means++
  • 初始化一個空的集合M來儲存被選取的質心
  • 從輸入樣本中隨機選取第一個質心且指派給M
  • 對於每一個不在M中的樣本計算出對M中所有質心的最小距離平方
  • 使用加權機率分配來隨機選取下一個質心
  • 重覆2,3直到選取了k個質心
  • 以古典k-means演算法完成後續工作
這邊我們發現一個不同是,從輸入樣本中隨機選擇第一個質心M集合, 這代表著k-means++是取實際點。
k-means的一個特性,集群不會重疊,也不具階層性。
In practice, the k-means algorithm is very fast (one of the fastest clustering algorithms available), but it falls in local minima. That’s why it can be useful to restart it several times.
作者提到,多計算幾次是有用的!!

IMPORT

from sklearn.cluster import KMeans

CLASS

KMeans(n_clusters=8, init=’k-means++’, n_init=10, max_iter=300, tol=0.0001, precompute_distances=’auto’, verbose=0, random_state=None, copy_x=True, n_jobs=1, algorithm=’auto’)

參數說明

n_clusters

default 8
集群數目
需事先指定集群數目是k-means限制之一

init

default k-means++ {random, k-means++}
初始質心的選擇方式

n_init

default 10
以隨機選取的質心來執行k-means演算法次數,並以最低SSE的模型來做最後的模型

max_iter

default 300
每次執行的最大迭代次數,在k-means中,如果執行結果收斂的話,是有可能提前中止,而不會執行到最大迭代次數。

tol

default 0.0001
控制集群內誤差平方和的可容許誤差,設定較大的值可有效收斂!

precompute_distances

default auto {‘auto’, ‘True’, ‘False’}
預先計算距離,更快,但需要更大的記憶體空間
auto:不預先計算,當n_samples * n_clusters > 12 million.(1200萬)

verbose

default 0
過程是否顯示

random_state

亂數種子

copy_x

default True
待理解

n_jobs

default 1
使用多少CPU核心數
-1代表火力全開

algorithm

default auto {‘auto’, ‘full’, ‘elkan’}
距離計算的演算法,作法上是建議讓演算法去自動判斷資料的稀疏程度自己選即可。
elkan利用了兩邊之和大於等於第三邊,以及兩邊之差小於第三邊的三角形性質,來減少距離的計算
這部份相關的細節如果有興趣的話,可以再查文獻。

方法

fit(X[, y])

適合(訓練)模型

fit_predict(X[, y])

適合(訓練)模型+預測模型聚類索引

fit_transform(X[, y])

適合(訓練)模型+轉換為聚類距離空間
有transform就可以配合pipeline!!

get_params([deep])

取得模型參數

predict(X)

預測模型聚類索引

score(X[, y])

不是很理解,x與k-means相對值?

set_params(**params)

設置模型參數

transform(X)

轉換為聚類距離空間

屬性

cluster_centers_

計算之後的質心位置

inertia_

集群內誤差平方和
可用來做轉折判斷法的依據

labels_

每個點的標籤

範例

#  載入scikit-learn資料集範例資料
from sklearn.datasets import make_blobs
X, y = make_blobs(n_samples=150,
                  n_features=2,
                  centers=3,
                  cluster_std=0.5,
                  shuffle=True,
                  random_state=0)
                  
#  實作
from sklearn.cluster import KMeans
km = KMeans(n_clusters=3,
            init='random',
            n_init=10,
            max_iter=300,
            tol=1e-04,
            random_state=0)
y_km = km.fit_predict(X)

#  圖形化
plt.scatter(X[y_km == 0, 0],
            X[y_km == 0, 1],
            s=50,
            c='lightgreen',
            marker='s',
            label='cluster 1')
            
plt.scatter(X[y_km == 1, 0],
            X[y_km == 1, 1],
            s=50,
            c='orange',
            marker='o',
            label='cluster 2')
            
plt.scatter(X[y_km == 2, 0],
            X[y_km == 2, 1],
            s=50,
            c='lightblue',
            marker='v',
            label='cluster 3')
#  質心的點            
plt.scatter(km.cluster_centers_[:, 0],
            km.cluster_centers_[:, 1],
            s=250,
            marker='*',
            c='red',
            label='centroids')
plt.legend()
plt.grid()
plt.show()