再探決策樹算法之利用sklearn進行決策樹實戰


sklearn模塊提供了決策樹的解決方案,不用自己去造輪子了(不會造,感覺略復雜):

下面是筆記:

Sklearn.tree參數介紹及使用建議 參數介紹及使用建議
官網: http://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html class sklearn.tree.DecisionTreeClassifier(criterion='gini', splitter='best', max_depth=None, min_samples_split=2,min_samples_leaf=1, max_features=None, random_state=None, min_density=None, compute_importances=None,max_leaf_nodes=None)
比較重要的參數:
criterion :規定了該決策樹所采用的的最佳分割屬性的判決方法,有兩種:“gini”,“entropy”。
max_depth :限定了決策樹的最大深度,對於防止過擬合非常有用。
min_samples_leaf :限定了葉子節點包含的最小樣本數,這個屬性對於防止上文講到的數據碎片問題很有作用
模塊中一些重要的屬性方法:
n_classes_ :決策樹中的類數量。
classes_ :返回決策樹中的所有種類標簽。
feature_importances_ :feature的重要性,值越大那么越重要。
fit(X, y, sample_mask=None, X_argsorted=None, check_input=True, sample_weight=None) 將數據集x,和標簽集y送入分類器進行訓練,這里要注意一個參數是:sample_weright,它和樣本的數量一樣長,所攜帶的是每個樣本的權重。
get_params(deep=True) 得到決策樹的各個參數。
set_params(**params) 調整決策樹的各個參數。
predict(X) 送入樣本X,得到決策樹的預測。可以同時送入多個樣本。
transform(X, threshold=None) 返回X的較重要的一些feature,相當於裁剪數據。
score(X, y, sample_weight=None) 返回在數據集X,y上的測試分數,正確率。
使用建議
1. 當我們數據中的feature較多時,一定要有足夠的數據量來支撐我們的算法,不然的話很容易overfitting
2. PCA是一種避免高維數據overfitting的辦法。
3. 從一棵較小的樹開始探索,用export方法打印出來看看。
4. 善用max_depth參數,緩慢的增加並測試模型,找出最好的那個depth。
5. 善用min_samples_split和min_samples_leaf參數來控制葉子節點的樣本數量,防止overfitting。
6. 平衡訓練數據中的各個種類的數據,防止一個種類的數據dominate。

 

后面開始實戰:

#-*-coding:utf-8 -*-
from sklearn import tree
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import classification_report
from sklearn.cross_validation import train_test_split
import numpy as np

#讀取數據
data=[]
labels=[]
#根據text里的數據格式將數據寫到list里
with open('C:\Users\cchen\Desktop\sample.txt','r') as f:
    for line in f:
        linelist=line.split(' ')
        data.append([float(el) for el in linelist[:-1]])
        labels.append(linelist[-1].strip())
# print data
# [[1.5, 50.0], [1.5, 60.0], [1.6, 40.0], [1.6, 60.0], [1.7, 60.0], [1.7, 80.0], [1.8, 60.0], [1.8, 90.0], [1.9, 70.0], [1.9, 80.0]]
# print labels
x=np.array(data)
labels=np.array(labels)
# print labels
# ['thin' 'fat' 'thin' 'fat' 'thin' 'fat' 'thin' 'fat' 'thin' 'fat']
y=np.zeros(labels.shape)
# print y
# [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
# print labels=='fat'
# [False  True False  True False  True False  True False  True]
# 這個替換的方法很巧妙,可以一學,利用布爾值來給list賦值。要是我的話就要寫個循環了。
y[labels=='fat']=1
# print y
# [ 0.  1.  0.  1.  0.  1.  0.  1.  0.  1.]
#拆分訓練數據和測試數據,把20%的當做測試數據,其實我感覺直接分片就可以的,不過這樣比較高大上一點
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2)
#使用信息熵作為划分標准,對決策樹進行訓練
clf=tree.DecisionTreeClassifier(criterion='entropy')
# print clf
# DecisionTreeClassifier(class_weight=None, criterion='entropy', max_depth=None,
#             max_features=None, max_leaf_nodes=None,
#             min_impurity_split=1e-07, min_samples_leaf=1,
#             min_samples_split=2, min_weight_fraction_leaf=0.0,
#             presort=False, random_state=None, splitter='best')
clf.fit(x_train,y_train)
#把決策樹寫入文件
with open(r'C:\Users\cchen\Desktop\tree.dot','w+') as f:
    f=tree.export_graphviz(clf,out_file=f)
# digraph Tree {
# node [shape=box] ;
# 0 [label="X[1] <= 70.0\nentropy = 0.9544\nsamples = 8\nvalue = [3, 5]"] ;
# 1 [label="X[0] <= 1.65\nentropy = 0.971\nsamples = 5\nvalue = [3, 2]"] ;
# 0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
# 2 [label="X[1] <= 55.0\nentropy = 0.9183\nsamples = 3\nvalue = [1, 2]"] ;
# 1 -> 2 ;
# 3 [label="entropy = 0.0\nsamples = 1\nvalue = [1, 0]"] ;
# 2 -> 3 ;
# 4 [label="entropy = 0.0\nsamples = 2\nvalue = [0, 2]"] ;
# 2 -> 4 ;
# 5 [label="entropy = 0.0\nsamples = 2\nvalue = [2, 0]"] ;
# 1 -> 5 ;
# 6 [label="entropy = 0.0\nsamples = 3\nvalue = [0, 3]"] ;
# 0 -> 6 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
# }
#系數反應每個特征值的影響力
# print clf.feature_importances_
# [ 0.3608012  0.6391988],可以看到身高系數影響較大
#測試結果打印
anwser=clf.predict(x_train)
# print x_train
print anwser
# [ 1.  0.  1.  0.  1.  0.  1.  0.]
print y_train
# [ 1.  0.  1.  0.  1.  0.  1.  0.]
print np.mean(anwser==y_train)
# 1.0 很准,畢竟用的是訓練的數據
#讓我們用測試的數據來看看
anwser=clf.predict(x_test)
print anwser
# [ 0.  0.]
print y_test
# [ 0.  0.]
print np.mean(anwser==y_test)
# 1.0 也很准
#這個是教程里的注釋,我沒碰到
#准確率與召回率 #准確率:某個類別在測試結果中被正確測試的比率 #召回率:某個類別在真實結果中被正確預測的比率 #測試結果:array([ 0., 1., 0., 1., 0., 1., 0., 1., 0., 0.]) #真實結果:array([ 0., 1., 0., 1., 0., 1., 0., 1., 0., 1.]) #分為thin的准確率為0.83。是因為分類器分出了6個thin,其中正確的有5個,因此分為thin的准確率為5/6=0.83。 #分為thin的召回率為1.00。是因為數據集中共有5個thin,而分類器把他們都分對了(雖然把一個fat分成了thin!),召回率5/5=1。 #分為fat的准確率為1.00。不再贅述。 #分為fat的召回率為0.80。是因為數據集中共有5個fat,而分類器只分出了4個(把一個fat分成了thin!),召回率4/5=0.80。 #本例中,目標是盡可能保證找出來的胖子是真胖子(准確率),還是保證盡可能找到更多的胖子(召回率)。
precision,recall,thresholds=precision_recall_curve(y_train,clf.predict(x_train))
print precision,recall,thresholds
# [ 1.  1.] [ 1.  0.] [ 1.]
anwser=clf.predict_proba(x)[:,1]
print classification_report(y,anwser,target_names=['thin','fat'])
#              precision    recall  f1-score   support

       # thin       1.00      1.00      1.00         5
       #  fat       1.00      1.00      1.00         5
#
#  avg / total       1.00      1.00      1.00        10

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM