一文帶你讀懂線性分類器

本文爲 AI 研習社編譯的技術博客,原標題 :

Linear Classifier

作者 | Thomas Pernet

翻譯 | 鄧普斯•傑弗、塗世文、Disillusion

校對 | 鄧普斯•傑弗 審覈| 醬番梨 整理 | 菠蘿妹

原文鏈接:

https://medium.com/@thomaspernet/linear-classifier-aa3ccec96efa

什麼是線性分類器?

在有監督學習中,最主要的兩種學習任務是 迴歸(regression) 和 分類(classification),而其中 線性迴歸 和 線性分類 最爲常見。線性迴歸是預測某一個具體的值,而線性分類是數據所屬類別進行預測。這裏,我們主要關注線性分類問題。

一般來說,幾乎 80% 機器學習任務可以看作是某種分類問題。分類,即給定一個輸入的集合,分類器致力於預測每一個類別的概率。類別標記(也被稱爲 應變量或依賴變量)是一個離散的值,表示某個類別。

  1. 如果數據中的 Label 只有兩個類別,那麼就屬於二分類問題,相應的分類器被稱爲 二分類器。

  2. 多分類器解決 Label 種類多於兩種類別的分類問題。

譬如,預測顧客是否會進行二次購買便是一個典型的二分類問題。而識別圖片中出現動物則是屬於多分類問題,因爲實際情況中動物有很多種。

本文的理論部分主要關注於二分類問題。未來我們也會推出關於多分類的內容,敬請期待!

二分類器是如何工作的?

在前面的教程中你已經瞭解到函數由兩類變量組成,一個應變量和一組特徵(自變量)。在線性迴歸中,應變量是一個沒有範圍的實數。主要目標是通過最小化均方誤差來預測其值。

對於二分類任務,標籤可以有兩個可能的整數值。在大多數情況下,要麼是[0,1]要麼是[1,2]。

例如,如果目標是預測客戶是否會購買產品。標籤可爲如下:

  • Y = 1(客戶購買了產品)

  • Y = 0 (客戶沒有購買產品)

該模型使用特徵X將每個客戶分類到他最有可能的所屬類別,即是潛在購買者,或否。

成功的概率用邏輯迴歸計算。該算法將根據特徵X計算出一個概率,並在該概率大於50%時預測成功。概率的算式如下:

θ是權重的集合,x是特徵,b是偏差

該函數可進一步分爲兩部分:

  • 線性模型

  • 邏輯函數

線性模型

你已經熟悉了計算權重的方法。權重計算使用點積:θ^ Tx + b

Y是所有特徵x_i的線性函數。如果模型沒有特徵,則預測結果爲偏差b。

權值表示特徵x_i與標籤y之間相關性的方向。正相關增加了正類的概率,而負相關使概率更接近於0(即負類)。

線性模型只返回實數,與區間[0,1]的概率測度不一致。因此需要邏輯函數將線性模型輸出轉換爲概率。

邏輯函數

邏輯函數,亦稱sigmoid函數,爲s形,且輸出總是在0和1之間。

將線性迴歸的輸出代入sigmoid函數是很容易的。它產生一個概率在0和1之間的新數字。

分類器可以將概率轉化爲類

  • 0到0.49之間的值分到0類

  • 從0.5到1之間的值分到1類

如何度量顯性分類器的性能?

準確度:

分類器的整體性能是用準確度量來衡量的。準確度收集所有正確值除以觀測總數。例如,精度值爲80%意味着模型在80%的情況下是正確的。

您可以注意到這個度量的一個缺點,特別是對於不平衡樣本分類情況。當每組的觀測次數不相等時,就會出現不平衡數據集。比如說,你試圖用logistics函數來分類一個罕見的事件。假設分類器試圖估計疾病後患者的死亡。在數據中,5%的病人去世了。您可以訓練分類器來預測死亡人數,並使用準確度量來評估性能。如果分類器預測整個數據集的死亡爲0,那麼則95%的情況下是正確的。(也就是說,你的分類器可以直接判定都是不死亡,就可以實現非常高的準確度)

混淆矩陣:

評估分類器性能的更好方法是查看混淆矩陣。

想象的混亂矩陣的準確度進行比較的當前和預測的分類器分類。組成:二進制混淆矩陣法:

  1. TP: 真正:正確預測爲實際正的預測值

  2. FP:預測值錯誤地預測了實際的正值。也就是說,預測爲正值的負值

  3. FN:假負:預測爲負的正值

  4. TN:真負:正確預測爲實際負的預測值

從混淆矩陣可以很容易地比較實際標籤結果和預測標籤結果。

精確度和靈敏度

混淆矩陣可以很好地洞察真陽性和假陽性。在某些情況下,是一個更簡潔的度量。

精確度

精準度顯示正類的精度。它衡量了正類預測的正確程度。

當分類器對所有正值進行完全分類時,最大得分爲1。精確度本身並不是很有幫助,因爲它忽略了負類。度量通常與召回成對出現。回憶也被稱爲敏感性或真陽性率。

靈敏性
靈敏度計算正確檢測到的正類的比率。這個指標給出了模型識別正類的能力。

tensorflow實現線性分類器

對於本教程,我們將使用人口普查數據集。目的是使用人口普查數據集中的變量來預測收入水平。注意,收入是一個二元變量。

  1. 如果收入大於50K,值爲1

  2. 如果收入小於50K,則爲0。

這個變量是你的類別標籤

該數據集包括八個分類變量:

  1. 工作場所

  2. 教育

  3. 婚姻的

  4. 職業

  5. 關係

  6. 種族

  7. 性別

  8. 國家

此外,六個連續變量:

  1. 年齡

  2. FNLWgt

  3. 教育數字

  4. 資本收益

  5. 資本損失

  6. 小時\周

通過這個例子,您將瞭解如何用張量流估計訓練線性分類器,以及如何提高準確度指標。

我們將按以下步驟進行:

第一步:導入數據

第二步:數據轉換

第三步:訓練分類器

第四步:改進模型

第5步:超參數:Lasso & Ridge

開始分佈介紹:

步驟1:導入數據

首先導入教程中使用的庫。

導入TensorFlow as tf \ import pandas as pd

接下來,從UCI存檔導入數據並定義列名稱。您將使用列來命名pandas dataframe。

請注意,您將使用Pandas dataframe來訓練分類器。

import pandas as pd
import tensorflow as tf
## Define path data
COLUMNS = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital',
          'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss',
          'hours_week', 'native_country', 'label']
PATH = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data"
PATH_test = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.test"

/Users/Thomas/anaconda3/envs/hello-tf/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: compiletime version 3.5 of module 'tensorflow.python.framework.fast_tensor_util' does not match runtime version 3.6
 return f(*args, **kwds)

在線存儲的數據已經在訓練組和測試組之間進行了劃分。

df_train = pd.read_csv(PATH, skipinitialspace=True, names = COLUMNS, index_col=False)
df_test = pd.read_csv(PATH_test,skiprows = 1, skipinitialspace=True, names = COLUMNS, index_col=False)

訓練數據集合包含32561組數據,測試數據集中包含16281組數據;

print(df_train.shape, df_test.shape)
print(df_train.dtypes)

(32561, 15) (16281, 15)
age                int64
workclass         object
fnlwgt             int64
education         object
education_num      int64
marital           object
occupation        object
relationship      object
race              object
sex               object
capital_gain       int64
capital_loss       int64
hours_week         int64
native_country    object
label             object
dtype: object

TensorFlow需要一個布爾值來訓練分類器。您需要將值從字符串轉換爲整數。標籤存儲爲一個對象,但是,您需要將其轉換爲一個數值。下面的代碼創建一個字典,其中包含要轉換的值,並在列項上循環。請注意,您執行此操作兩次,一次針對訓練數據集,一次用於測試數據集;

label = {'<=50K': 0,'>50K': 1}
df_train.label = [label[item] for item in df_train.label]
label_t = {'<=50K.': 0,'>50K.': 1}
df_test.label = [label_t[item] for item in df_test.label]

訓練數據中,50K以下收入24720人,以上收入7841人。測試集的比率幾乎相同。有關更多信息,請參閱本教程中的方面。

print(df_train["label"].value_counts())
### The model will be correct in atleast 70% of the case
print(df_test["label"].value_counts())
## Unbalanced label
print(df_train.dtypes)

0    24720
1     7841
Name: label, dtype: int64
0    12435
1     3846
Name: label, dtype: int64
age                int64
workclass         object
fnlwgt             int64
education         object
education_num      int64
marital           object
occupation        object
relationship      object
race              object
sex               object
capital_gain       int64
capital_loss       int64
hours_week         int64
native_country    object
label              int64
dtype: object

第二步:數據轉化

在用TensorFlow訓練線性分類器之前,需要執行幾個步驟。您需要準備要包含在模型中的特徵。在基準迴歸中,您將使用原始數據而不應用任何轉換。

估計器需要有一個特徵列表來訓練模型。因此,列的數據需要轉換爲張量。

一個好的實踐是根據特徵的類型定義兩個特徵列表,然後將它們傳遞到估計器的特徵列中。

您將從轉換連續特性開始,然後用分類數據定義一個bucket。

數據集的特徵有兩種格式:

  1. 整數

  2. 對象

每個特徵都根據其類型在接下來的兩個變量中列出。

## Add features to the bucket: 
### Define continuous list
CONTI_FEATURES  = ['age', 'fnlwgt','capital_gain', 'education_num', 'capital_loss', 'hours_week']
### Define the categorical list
CATE_FEATURES = ['workclass', 'education', 'marital', 'occupation', 'relationship', 'race', 'sex', 'native_country']

Feature_column 裝配了一個對象numeric_column,以幫助將連續變量轉換爲張量。在下面的代碼中,您可以將CONTI_FEATURES 特徵中的所有變量轉換爲具有數值的張量。這對於構建模型是必需的。所有的自變量都需要轉換成合適的張量類型。

下面我們編寫一個代碼,讓您瞭解feature_column.numeric_column 後面發生了什麼。我們將打印轉換後的值用於解釋,因此不需要理解Python代碼。您可以參考官方文檔瞭解這些代碼。

def print_transformation(feature = "age", continuous = True, size = 2): 
   #X = fc.numeric_column(feature)
   ## Create feature name
   feature_names = [
   feature]

## Create dict with the data
   d = dict(zip(feature_names, [df_train[feature]]))
   ## Convert age
   if continuous == True:
       c = tf.feature_column.numeric_column(feature)
       feature_columns = [c]
   else: 
       c = tf.feature_column.categorical_column_with_hash_bucket(feature, hash_bucket_size=size) 
       c_indicator = tf.feature_column.indicator_column(c)
       feature_columns = [c_indicator]
   
## Use input_layer to print the value
   input_layer = tf.feature_column.input_layer(
       features=d,
       feature_columns=feature_columns
       )
   ## Create lookup table
   zero = tf.constant(0, dtype=tf.float32)
   where = tf.not_equal(input_layer, zero)
   ## Return lookup tble
   indices = tf.where(where)
   values = tf.gather_nd(input_layer, indices)
   ## Initiate graph
   sess = tf.Session()
   ## Print value
   print(sess.run(input_layer))

print_transformation(feature = "age", continuous = True)

[[39.]
[50.]
[38.]
...
[58.]
[22.]
[52.]]

這些值與df_train中的值完全相同

continuous_features = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES]

根據TensorFlow文檔,有不同的方法來轉換分類數據。如果某個功能的詞彙表是已知的,並且沒有足夠的值,則可以使用“詞彙表”創建“分類”列用categorical_column_with_vocabulary_list。它將爲所有唯一詞彙表分配一個ID。

例如,如果變量狀態有三個不同的值:

  1. 丈夫

  2. 妻子

  3. 單身

然後三個ID將被屬性化。例如,丈夫將擁有ID 1,妻子ID 2等等。

爲了便於說明,可以使用此代碼在TensorFlow中將對象變量轉換爲分類列。

特徵性別只能有兩個價值:男性或女性。當我們轉換特徵性時,TensorFlow將創建兩個新列,一個用於男性,一個用於女性。如果性別等於男性,那麼新的列“男性”將等於1,而“女性”將等於0。此示例顯示在下表中:

tensorflow中:

print_transformation(feature = “sex”, continuous = False, size = 2)

relationship = tf.feature_column.categorical_column_with_vocabulary_list(
   'relationship', [
       'Husband', 'Not-in-family', 'Wife', 'Own-child', 'Unmarried',
       'Other-relative'])

下面,我們添加了python代碼來打印編碼。同樣,您不需要理解代碼,目的是看到轉換

但是,轉換數據的一種更快的方法是使用方法:categorical_column_with_hash_bucket。改變稀疏矩陣中的字符串變量是有用的。稀疏矩陣是一個基本上爲零的矩陣。您只需要指定存儲桶的數量和鍵列。桶數是TensorFlow可以創建的最大組數。鍵列只是要轉換的列的名稱。

在下面的代碼中,您將在所有分類功能上創建一個循環。

categorical_features = [tf.feature_column.categorical_column_with_hash_bucket(k, hash_bucket_size=1000) for k in CATE_FEATURES]

第三步:訓練分類器

tensorflow目前爲線性迴歸和線性分類提供了一個estimator。

  1. 線性迴歸:LinearRegressor

  2. 線性分類:LinearClassifier

線性分類器的語法與線性迴歸教程中的語法相同,除了一個參數n_class。您需要定義特徵列、模型目錄,並與線性迴歸器進行比較;您已經定義了類的數量。對於邏輯迴歸,類的數目等於2。

模型將計算包含在continuous_features and categorical_features 的特徵列的權重。

model = tf.estimator.LinearClassifier(
   n_classes = 2,
   model_dir="ongoing/train", 
   feature_columns=categorical_features+ continuous_features)
INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'ongoing/train', '_tf_random_seed': Non

既然定義了分類器,就可以創建輸入函數。該方法與線性迴歸器教程中的方法相同。在這裏,您使用128的批量大小,然後對數據進行無序處理。

FEATURES = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital', 'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss', 'hours_week', 'native_country']
LABEL= 'label'
def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True):
   return tf.estimator.inputs.pandas_input_fn(
      x=pd.DataFrame({k: data_set[k].values for k in FEATURES}),
      y = pd.Series(data_set[LABEL].values),
      batch_size=n_batch,   
      num_epochs=num_epochs,
      shuffle=shuffle)

您可以使用線性估計所需的參數創建一個函數,即epoch數、batches數和shuffle處理數據集或註釋。由於使用pandas方法將數據傳遞到模型中,因此需要將x變量定義爲pandas dataframe。請注意,您將循環訪問存儲在FEATURES中的所有數據。

讓我們用對象model.train來訓練模型。您可以使用先前定義的函數向模型提供適當的值。請注意,您將批大小設置爲128,並且將epoch數設置爲none。模型將經過一千多步的訓練。

model.train(input_fn=get_input_fn(df_train, 
                                     num_epochs=None,
                                     n_batch = 128,
                                     shuffle=False),
                                     steps=1000)
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 0 into ongoing/train/model.ckpt.
INFO:tensorflow:loss = 88.722855, step = 1
INFO:tensorflow:global_step/sec: 95.9134
INFO:tensorflow:loss = 52583.64, step = 101 (1.044 sec)
INFO:tensorflow:global_step/sec: 167.726
INFO:tensorflow:loss = 25203.816, step = 201 (0.596 sec)
INFO:tensorflow:global_step/sec: 162.827
INFO:tensorflow:loss = 54924.312, step = 301 (0.614 sec)
INFO:tensorflow:global_step/sec: 226.156
INFO:tensorflow:loss = 68509.31, step = 401 (0.443 sec)
INFO:tensorflow:global_step/sec: 143.237
INFO:tensorflow:loss = 9151.754, step = 501 (0.701 sec)
INFO:tensorflow:global_step/sec: 140.458
INFO:tensorflow:loss = 34576.06, step = 601 (0.710 sec)
INFO:tensorflow:global_step/sec: 131.307
INFO:tensorflow:loss = 36047.117, step = 701 (0.764 sec)
INFO:tensorflow:global_step/sec: 150.417
INFO:tensorflow:loss = 22608.148, step = 801 (0.665 sec)
INFO:tensorflow:global_step/sec: 162.276
INFO:tensorflow:loss = 22201.918, step = 901 (0.615 sec)
INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train/model.ckpt.
INFO:tensorflow:Loss for final step: 5444.363.

<tensorflow.python.estimator.canned.linear.LinearClassifier at 0xb202e4668>

請注意,損失隨後在最後100個步驟中減少,即從901減少到1000。

一千次迭代後的最終損失是5444。您可以在測試集中估計您的模型並查看性能。要評估模型的性能,需要使用對象evaluate。您向模型提供測試集,並將epoch的數目設置爲1,即數據將只輸入模型一次。

model.evaluate(input_fn=get_input_fn(df_test, 
                                     num_epochs=1,
                                     n_batch = 128,
                                     shuffle=False),
                                     steps=1000)
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-08-29-19:10:30
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from ongoing/train/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [100/1000]
INFO:tensorflow:Finished evaluation at 2018-08-29-19:10:33
INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.7615626, accuracy_baseline = 0.76377374, auc = 0.63300294, auc_precision_recall = 0.50891197, average_loss = 47.12155, global_step = 1000, label/mean = 0.23622628, loss = 5993.6406, precision = 0.49401596, prediction/mean = 0.18454961, recall = 0.38637546
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1000: on

{'accuracy': 0.7615626,
'accuracy_baseline': 0.76377374,
'auc': 0.63300294,
'auc_precision_recall': 0.50891197,
'average_loss': 47.12155,
'label/mean': 0.23622628,
'loss': 5993.6406,
'precision': 0.49401596,
'prediction/mean': 0.18454961,
'recall': 0.38637546,
'global_step': 1000}

TensorFlow返回理論部分中學習的所有度量指標。不出所料,由於標籤不平衡,精度很高。實際上,模型的性能比隨機猜測略好。假設該模型預測所有收入低於50K的家庭,那麼該模型的準確率爲70%。仔細分析,你會發現預測和召回都很低。

第四部:模型改進

既然你有了一個基準模型,你可以嘗試改進它,也就是說,提高精確度。在前面的教程中,您學習瞭如何通過交互項提高預測能力。在本教程中,您將通過向迴歸添加一個多項式項。

當數據存在非線性時,多項式迴歸是有用的。有兩種方法可以捕獲數據中的非線性。

  1. 增加多項式項

  2. 將連續變量變爲離散變量

多項式項

從下圖中,您可以看到什麼是多項式迴歸。它是一個具有不同冪次的x變量的方程。二次多項式迴歸有兩個變量,x和x的平方。三度有三個變量,x、x^ 2、\和\x^ 3

下面,我們構造了一個有兩個變量的圖,x和y。很明顯,這種關係不是線性的。如果我們添加線性迴歸,我們可以看到模型無法捕獲模式(左圖)。
現在,從下面的圖片看左邊的圖片,我們在迴歸中添加了五項。

這個模型現在可以更好地捕捉模式。這是多項式迴歸的強大。

讓我們回到我們的例子。年齡與收入沒有線性關係。由於兒童或年輕人不工作,早年的收入可能接近零。然後它在工作年齡上增加,在退休期間減少。它通常是一個倒U形。捕獲這種模式的一種方法是在迴歸中添加一個二次項。

讓我們看看它是否提高了精確度。
您需要將這個新特性添加到數據集和連續特性列表中。

在訓練和測試數據集中添加新的變量,這樣編寫函數就更方便了。

def square_var(df_t, df_te, var_name = 'age'):
     df_t['new'] = df_t[var_name].pow(2) 
     df_te['new'] = df_te[var_name].pow(2) 
     return df_t, df_te

函數有3個參數:

  • 定義訓練集

  • 定義測試集

  • var_name='age':定義要轉換的變量

您可以使用對象POW(2)來調整可變年齡。請注意,新變量名爲“new”

現在編寫了函數square_var,就可以創建新的數據集。

df_train_new, df_test_new = square_var(df_train, df_test, var_name = 'age')

如下所示,數據集多了一個新的特徵:

print(df_train_new.shape, df_test_new.shape)

(32561, 16) (16281, 16)

平方變量在數據集中稱爲new。您需要將其添加到連續功能列表中。

CONTI_FEATURES_NEW  = ['age', 'fnlwgt','capital_gain', 'education_num', 'capital_loss', 'hours_week', 'new']
continuous_features_new = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES_NEW]

請注意,更改了圖形的目錄。不能在同一目錄中訓練不同的模型。這意味着,你需要改變參數 model_dir。如果不這樣做,TensorFlow將拋出一個錯誤。

model_1 = tf.estimator.LinearClassifier(
   model_dir="ongoing/train1", 
   feature_columns=categorical_features+ continuous_features_new)
INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'ongoing/train1', '_tf_random_seed': No

FEATURES_NEW = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital', 'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss', 'hours_week', 'native_country', 'new']
def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True):
   return tf.estimator.inputs.pandas_input_fn(
      x=pd.DataFrame({k: data_set[k].values for k in FEATURES_NEW}),
      y = pd.Series(data_set[LABEL].values),
      batch_size=n_batch,   
      num_epochs=num_epochs,
      shuffle=shuffle)

現在分類器是用新的數據集設計的,那麼就可以訓練和評估模型了。

model_1.train(input_fn=get_input_fn(df_train, 
                                     num_epochs=None,
                                     n_batch = 128,
                                     shuffle=False),
                                     steps=1000)
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 0 into ongoing/train1/model.ckpt.
INFO:tensorflow:loss = 88.722855, step = 1
INFO:tensorflow:global_step/sec: 65.4699
INFO:tensorflow:loss = 70077.66, step = 101 (1.533 sec)
INFO:tensorflow:global_step/sec: 166.451
INFO:tensorflow:loss = 49522.082, step = 201 (0.599 sec)
INFO:tensorflow:global_step/sec: 172.15
INFO:tensorflow:loss = 107120.57, step = 301 (0.577 sec)
INFO:tensorflow:global_step/sec: 135.673
INFO:tensorflow:loss = 12814.152, step = 401 (0.741 sec)
INFO:tensorflow:global_step/sec: 147.318
INFO:tensorflow:loss = 19573.898, step = 501 (0.675 sec)
INFO:tensorflow:global_step/sec: 205.764
INFO:tensorflow:loss = 26381.986, step = 601 (0.486 sec)
INFO:tensorflow:global_step/sec: 188.238
INFO:tensorflow:loss = 23417.719, step = 701 (0.531 sec)
INFO:tensorflow:global_step/sec: 226.805
INFO:tensorflow:loss = 23946.049, step = 801 (0.441 sec)
INFO:tensorflow:global_step/sec: 183.742
INFO:tensorflow:loss = 3309.5786, step = 901 (0.544 sec)
INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train1/model.ckpt.
INFO:tensorflow:Loss for final step: 28861.898.

<tensorflow.python.estimator.canned.linear.LinearClassifier at 0xb20308ba8>

model_1.evaluate(input_fn=get_input_fn(df_test_new, 
                                     num_epochs=1,
                                     n_batch = 128,
                                     shuffle=False),
                                     steps=1000)
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-08-29-19:10:49
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from ongoing/train1/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [100/1000]
INFO:tensorflow:Finished evaluation at 2018-08-29-19:10:51
INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.7944229, accuracy_baseline = 0.76377374, auc = 0.6093755, auc_precision_recall = 0.54885805, average_loss = 111.0046, global_step = 1000, label/mean = 0.23622628, loss = 14119.265, precision = 0.6682401, prediction/mean = 0.09116262, recall = 0.2576703
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1000:

{'accuracy': 0.7944229,
'accuracy_baseline': 0.76377374,
'auc': 0.6093755,
'auc_precision_recall': 0.54885805,
'average_loss': 111.0046,
'label/mean': 0.23622628,
'loss': 14119.265,
'precision': 0.6682401,
'prediction/mean': 0.09116262,
'recall': 0.2576703,
'global_step': 1000}

平方變量將精度從0.76提高到0.79。讓我們看看是否可以通過將bucketization和interaction項組合在一起做得更好。

Bucketization and interaction

正如您之前看到的,線性分類器無法正確捕獲年齡收入模式。這是因爲它爲每個特性學習一個權重。爲了使分類器更容易,您可以做的一件事是將特徵存儲起來。Bucketing根據數字特徵所處的範圍將其轉換爲若干特定特徵,這些新特徵中的每一個都指示一個人的年齡是否在該範圍內。
利用這些新特性,線性模型可以通過學習每個桶的不同權重來捕獲關係。
在TensorFlow中,它是用bucketized_column完成的。您需要在邊界中添加值的範圍。

age = tf.feature_column.numeric_column('age')
age_buckets = tf.feature_column.bucketized_column(
   age, boundaries=[18, 25, 30, 35, 40, 45, 50, 55, 60, 65])

你已經知道年齡與收入是非線性的。另一種改進模型的方法是通過interaction。在TensorFlow這個詞中,它是特徵交叉。特徵交叉是創建現有特徵組合的新特徵的一種方法,這對於無法對特徵之間的交互進行建模的線性分類器很有幫助。

你可以用教育這樣的另一個特徵來劃分年齡。也就是說,有些羣體的收入可能很高,而其他羣體的收入可能很低(例如博士生)。

education_x_occupation = [tf.feature_column.crossed_column(
   ['education', 'occupation'], hash_bucket_size=1000)]
age_buckets_x_education_x_occupation = [tf.feature_column.crossed_column(
   [age_buckets, 'education', 'occupation'], hash_bucket_size=1000)]

要創建交叉特徵列,請使用帶變量的crossed_column在括號中交叉。散列桶大小表示最大的交叉可能性。要在變量之間創建交互(至少有一個變量需要分類),可以使用tf.feature_column.crossed_column。要使用此對象,需要在方括號中添加要交叉的變量和第二個參數bucket size。bucket size是變量中可能的最大組數。這裏你把它設爲1000,因爲你不知道年齡組的確切數目。

在將其添加到功能列之前需要平方。您還可以將新特性添加到特性列,並準備estimator。

base_columns = [
   age_buckets,
]
model_imp = tf.estimator.LinearClassifier(
   model_dir="ongoing/train3", 
   feature_columns=categorical_features+base_columns+education_x_occupation+

INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'ongoing/train3', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0xb20ef8550>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

FEATURES_imp = ['age','workclass', 'education', 'education_num', 'marital',
               'occupation', 'relationship', 'race', 'sex', 'native_country', 'new']

def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True):
   return tf.estimator.inputs.pandas_input_fn(
      x=pd.DataFrame({k: data_set[k].values for k in FEATURES_imp}),
      y = pd.Series(data_set[LABEL].values),
      batch_size=n_batch,   
      num_epochs=num_epochs,
      shuffle=shuffle)

您已經準備好評估新模型,看看它是否提高了精度。

model_imp.train(input_fn=get_input_fn(df_train_new, 
                                     num_epochs=None,
                                     n_batch = 128,
                                     shuffle=False),
                                     steps=1000)
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 0 into ongoing/train3/model.ckpt.
INFO:tensorflow:loss = 88.722855, step = 1
INFO:tensorflow:global_step/sec: 110.894
INFO:tensorflow:loss = 50.334488, step = 101 (0.905 sec)
INFO:tensorflow:global_step/sec: 204.578
INFO:tensorflow:loss = 56.153225, step = 201 (0.489 sec)
INFO:tensorflow:global_step/sec: 201.008
INFO:tensorflow:loss = 45.792007, step = 301 (0.495 sec)
INFO:tensorflow:global_step/sec: 145.813
INFO:tensorflow:loss = 37.485672, step = 401 (0.688 sec)
INFO:tensorflow:global_step/sec: 255.157
INFO:tensorflow:loss = 56.48449, step = 501 (0.390 sec)
INFO:tensorflow:global_step/sec: 196.914
INFO:tensorflow:loss = 32.528934, step = 601 (0.507 sec)
INFO:tensorflow:global_step/sec: 190.965
INFO:tensorflow:loss = 37.438057, step = 701 (0.529 sec)
INFO:tensorflow:global_step/sec: 162.964
INFO:tensorflow:loss = 61.1075, step = 801 (0.610 sec)
INFO:tensorflow:global_step/sec: 202.747
INFO:tensorflow:loss = 44.69645, step = 901 (0.494 sec)
INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train3/model.ckpt.
INFO:tensorflow:Loss for final step: 44.18133.

<tensorflow.python.estimator.canned.linear.LinearClassifier at 0xb21883e80>

model_imp.evaluate(input_fn=get_input_fn(df_test_new, 
                                     num_epochs=1,
                                     n_batch = 128,
                                     shuffle=False),
                                     steps=1000)
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-08-29-19:11:05
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from ongoing/train3/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [100/1000]
INFO:tensorflow:Finished evaluation at 2018-08-29-19:11:06
INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.8358209, accuracy_baseline = 0.76377374, auc = 0.88401634, auc_precision_recall = 0.69599575, average_loss = 0.35122654, global_step = 1000, label/mean = 0.23622628, loss = 44.67437, precision = 0.68986726, prediction/mean = 0.23320661, recall = 0.55408216
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1000: ongoing/trai

{'accuracy': 0.8358209,
'accuracy_baseline': 0.76377374,
'auc': 0.88401634,
'auc_precision_recall': 0.69599575,
'average_loss': 0.35122654,
'label/mean': 0.23622628,
'loss': 44.67437,
'precision': 0.68986726,
'prediction/mean': 0.23320661,
'recall': 0.55408216,
'global_step': 1000}

新的準確度是83.58%。它比以前的模型高4%。
最後,您可以添加一個正則化項來防止過度擬合。

想要繼續查看該篇文章相關鏈接和參考文獻?

長按鏈接點擊打開或點擊一文帶你讀懂線性分類器

https://ai.yanxishe.com/page/TextTranslation/1289

AI研習社每日更新精彩內容,觀看更多精彩內容:

盤點圖像分類的竅門

深度學習目標檢測算法綜述

生成模型:基於單張圖片找到物體位置

AutoML :無人駕駛機器學習模型設計自動化

等你來譯:

如何在神經NLP處理中引用語義結構

你睡着了嗎?不如起來給你的睡眠分個類吧!

高級DQNs:利用深度強化學習玩吃豆人遊戲

深度強化學習新趨勢:谷歌如何把好奇心引入強化學習智能體

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章