---
# System prepended metadata

title: Data Mining

---

# Data Mining

> [TOC]



---

## project 要求
![](https://i.imgur.com/Vu5J0Y3.png)
![](https://i.imgur.com/IPlxsS6.png)


---

## Data description
### 原始data
![](https://i.imgur.com/ougAcTV.png)

#### feature
* customer_id
* credit_score
* country
* gender
* age
* tenure
* balance
* products_number
* credit_card
* active_member
* estimated_salary
#### target
* churn: 0表示顧客尚未離開，1表示已離開。
共11個特徵，1個預測目標

### Analysis Chart

![](https://i.imgur.com/o3Z0tPX.png) 
country
![](https://i.imgur.com/fnyKG79.png)
gender
![](https://i.imgur.com/Pk76oEG.png)
age
![](https://i.imgur.com/7JeT9qb.png)

tenure
![](https://i.imgur.com/c6EGU7q.png)

products_number

![](https://i.imgur.com/gWdUDbj.png)


active_member
![](https://i.imgur.com/Bf8BIUO.png)

---

## Data preprocessing
要訓練模型前，需要先將原始data當中文字轉換成數值，並將churn取出成為預測目標,customer_id對分類沒幫助也取出。
```
data['country'] = data['country'].apply(lambda x:1 if x == 'Germany' else x)
data['country'] = data['country'].apply(lambda x:2 if x == 'Spain' else x)
data['country'] = data['country'].apply(lambda x:3 if x == 'France' else x)
data['gender'] = data['gender'].apply(lambda x:1 if x == 'Male' else 0)

X = data.drop(labels=['churn','customer_id'],axis=1) 
```
1. country: 
    Germany->1
    Spain->2
    France->3
2. gender: male->1
		 female->0
3. 去掉churn和customer_id,churn作為預測目標。

![](https://i.imgur.com/FAFdmQU.png)

再來做資料切割。切割成測試集0.7，實驗集0.3。
![](https://i.imgur.com/dvmCLlY.png)

切割完後便可開始訓練模型。

---

## The classifier-Decision Tree 決策樹

定義:
是在已知各種情況發生機率的基礎上，通過構成決策樹來求取淨現值的期望值大於等於零的機率，評價項目風險，判斷其可行性的決策分析方法，是直觀運用機率分析的一種圖解法。

### Create Model
![](https://i.imgur.com/oiIAKmA.png)

#### parameter
1. Criterion 亂度評估標準

    **評估分割資訊量**
    Information Gain 透過從訓練資料找出規則，讓每一個決策能夠使訊息增益最大化。其算法主要是計算熵(entropy)，因此經由決策樹分割後的資訊量要越小越好。而 Gini 的數值越大代表序列中的資料亂，數值皆為 0~1 之間，其中 0 代表該特徵在序列中是完美的分類。常見的資訊量評估方法有兩種：資訊獲利 (Information Gain) 以及 Gini 不純度 (Gini Impurity)。
    
    **Gini 不純度 (Gini Impurity):**
    
    ![](https://i.imgur.com/uWMubWB.png)
    ![](https://i.imgur.com/UAGY5oq.png)

    是一種亂度的衡量方式，它的數字越大代表序列中的資料越混亂。公式如下所示，其中 p 代表是的機率、q 為代表否的機率。我們可以從圖中範例很清楚地知道當所有的資料都被分類一致的時候混亂程度即為 0，當資料各有一半不同時混亂程度即為 0.5。

    **熵 (Entropy):**
    ![](https://i.imgur.com/ywMdaky.png)
    ![](https://i.imgur.com/mM9PnqQ.png)

    熵 (Entropy) 是計算 Information Gain 的一種方法。公式中 p 代表是的機率、q 代表否的機率。當所有的資料都被分類一致的時候 Entropy 即為 0，當資料各有一半不同時 Entropy 即為 1。
    
    這次project我兩個都有使用。

2. Max_depth  最大深度
    測試出來後，根據accuarcy我entropy使用maxdepth=5，gini使用maxdepth=6。
![](https://i.imgur.com/vfuf8qs.png)
![](https://i.imgur.com/00QbtSQ.png)
![](https://i.imgur.com/EsK415S.png)

    
3. Random_state 亂數種子
    Random_states 設定成不同值時，會得到不同數據的切分。為了得到和先前一樣的結果，因此將random_state 固定設為 42。
    
4. Splitter 特徵劃分點選擇標準
    可設成best 或是 random。測試出來best accuarcy較高，所以固定為best




### Training
parameter都設定完後便可訓練模型。

![](https://i.imgur.com/Ns4Hadw.png)


### Accuracy(10-fold cross-validation)
#### gini
為了避免依賴某一特定的訓練和測試資料產生偏差，以10-fold cross-validation(交叉驗證)來驗證準確率。
```
scores = cross_val_score(decisionTreeModel_g,X,y,cv=10,scoring='accuracy')
print('10scores:',scores)
print('mean:',scores.mean()*100,'%')
```
![](https://i.imgur.com/lI5Q8qg.png)


#### entropy
![](https://i.imgur.com/WyLDdry.png)




### 視覺化
```
from six import StringIO  
import pydotplus
from google.colab import files
from sklearn.tree import export_graphviz
dot_data = StringIO()
export_graphviz(decisionTreeModel, out_file=dot_data, 
                   feature_names=index,
                   class_names=['no', 'yes'],  
                   filled=True, rounded=True,  
                   special_characters=True)  
graph = graphviz.Source(dot_data) 

graph = pydotplus.graph_from_dot_data(dot_data.getvalue())  
graph.write_png('my_decision_tree.png')
files.download('my_decision_tree.png')
```
#### gini
![](https://i.imgur.com/qF7anaE.png)
(原圖)
![](https://i.imgur.com/fVBqI5J.png)
(裁切)
#### entropy
![](https://i.imgur.com/IcuWmMk.png)
(原圖)
![](https://i.imgur.com/mA3xm3n.png)
(裁切)

圖上顯示出了決策樹在不同的參數下是如何分支。
橘色表class=no，也就是churn=0；藍色表class=yes，也就是churn=1；顏色越深表value差越大。

---

## The classifier-k-Nearest Neighbors K-近鄰演算法
定義:
    k是一個用戶定義的常數。一個沒有類別標籤的向量（查詢或測試點）將被歸類為最接近該點的k個樣本點中最頻繁使用的一類。

### Create Model
![](https://i.imgur.com/szStCSo.png)

#### parameter

1. n_neighbors k值

```
# 選擇 k # best k值會在data量20%內
range = np.arange(1, round(0.2 * X_train.shape[0]) + 1)
accuracies = []
for i in range:
    knn = neighbors.KNeighborsClassifier(n_neighbors = i)
    knnModel = knn.fit(X_train, y_train)
    test_y_predicted = knnModel.predict(X_test)
    accuracy = metrics.accuracy_score(y_test, test_y_predicted)
    accuracies.append(accuracy)
```
![](https://i.imgur.com/5Mxkpd3.png)
藉由程式可得知最佳準確率位於k值為20時。


2. weights
    可選擇選擇權重：'uniform' 或 'distance'

### Training
parameter都設定完後便可訓練模型。

![](https://i.imgur.com/DTTm0oR.png)

### Accuracy(10-fold cross-validation)
為了避免依賴某一特定的訓練和測試資料產生偏差，以10-fold cross-validation(交叉驗證)來驗證準確率。
```
scores = cross_val_score(knnModel, X, y, cv=10, scoring='accuracy')
print('10scores:',scores)
print('mean:',scores.mean()*100,'%')
```
weights = 'uniform'
![](https://i.imgur.com/DxNcKnn.png)

weights = 'distance'
![](https://i.imgur.com/yCsFTBV.png)


---

## Discussions
### Performance evaluation 
![](https://i.imgur.com/d4K3tNp.png)



### 嘗試改進
#### 方法:去除重要性低的標籤
1. gini
    ![](https://i.imgur.com/4cDcXKD.png)
    ![](https://i.imgur.com/16wP7gZ.png)
    ![](https://i.imgur.com/oZ1WZiC.png)


2. entropy
    ![](https://i.imgur.com/OJQL0mg.png)
    ![](https://i.imgur.com/P68XD7b.png)
    ![](https://i.imgur.com/aT15HdS.png)


3. knn
    KNNModel的分類方法，是利用k個最近的鄰居來判定新的資料是在哪一群。
    步驟為:
        1.決定k值
        2.求每個鄰居跟自己之間的距離
        3.找出跟自己最近的 k 個鄰居，查看哪一組鄰居數量最多，就加入哪一組
        
    因此對特徵重要度的算法跟決策樹不相同，無法使用:feature_importances_
---

## Conclusion

1. Decision Tree 相比起 knn有更佳的準確度
2. 針對Decision Tree 的部分，去除重要程度較低的標籤，對於準確率沒有明顯的增長，其他改進方法可能有:
* 資料標準化
* 剪枝
* 參數調整
3. KNN方面:
* 參數調整，如:
        1.n_neighbors k值: 設定鄰居的數量(k)，選取最近的k個點。
        2.algorithm: 搜尋數演算法。{'auto'，'ball_tree'，'kd_tree'，'brute'}，可選。
        3.metric: 計算距離的方式，預設為歐幾里得距離。
---


> [name=鍾承恩]