作者 | Thomas Pernet 翻譯 | 鄧普斯·杰弗、涂世文、Disillusion
什么是線性分類器? 在有監(jiān)督學習中,最主要的兩種學習任務是 回歸(regression) 和 分類(classification),而其中 線性回歸 和 線性分類 最為常見。線性回歸是預測某一個具體的值,而線性分類是數(shù)據(jù)所屬類別進行預測。這里,我們主要關注線性分類問題。 一般來說,幾乎 80% 機器學習任務可以看作是某種分類問題。分類,即給定一個輸入的集合,分類器致力于預測每一個類別的概率。類別標記(也被稱為 應變量或依賴變量)是一個離散的值,表示某個類別。 如果數(shù)據(jù)中的 Label 只有兩個類別,那么就屬于二分類問題,相應的分類器被稱為 二分類器。 多分類器解決 Label 種類多于兩種類別的分類問題。
譬如,預測顧客是否會進行二次購買便是一個典型的二分類問題。而識別圖片中出現(xiàn)動物則是屬于多分類問題,因為實際情況中動物有很多種。 本文的理論部分主要關注于二分類問題。未來我們也會推出關于多分類的內容,敬請期待!
在前面的教程中你已經了解到函數(shù)由兩類變量組成,一個應變量和一組特征(自變量)。在線性回歸中,應變量是一個沒有范圍的實數(shù)。主要目標是通過最小化均方誤差來預測其值。 對于二分類任務,標簽可以有兩個可能的整數(shù)值。在大多數(shù)情況下,要么是[0,1]要么是[1,2]。 例如,如果目標是預測客戶是否會購買產品。標簽可為如下: Y = 1(客戶購買了產品) Y = 0 (客戶沒有購買產品)
該模型使用特征X將每個客戶分類到他最有可能的所屬類別,即是潛在購買者,或否。 成功的概率用邏輯回歸計算。該算法將根據(jù)特征X計算出一個概率,并在該概率大于50%時預測成功。概率的算式如下:
θ是權重的集合,x是特征,b是偏差 該函數(shù)可進一步分為兩部分:
線性模型 你已經熟悉了計算權重的方法。權重計算使用點積:θ^ Tx + b Y是所有特征x_i的線性函數(shù)。如果模型沒有特征,則預測結果為偏差b。 權值表示特征x_i與標簽y之間相關性的方向。正相關增加了正類的概率,而負相關使概率更接近于0(即負類)。 線性模型只返回實數(shù),與區(qū)間[0,1]的概率測度不一致。因此需要邏輯函數(shù)將線性模型輸出轉換為概率。
邏輯函數(shù) 邏輯函數(shù),亦稱sigmoid函數(shù),為s形,且輸出總是在0和1之間。 
將線性回歸的輸出代入sigmoid函數(shù)是很容易的。它產生一個概率在0和1之間的新數(shù)字。 分類器可以將概率轉化為類 0到0.49之間的值分到0類 從0.5到1之間的值分到1類
準確度: 分類器的整體性能是用準確度量來衡量的。準確度收集所有正確值除以觀測總數(shù)。例如,精度值為80%意味著模型在80%的情況下是正確的。 
您可以注意到這個度量的一個缺點,特別是對于不平衡樣本分類情況。當每組的觀測次數(shù)不相等時,就會出現(xiàn)不平衡數(shù)據(jù)集。比如說,你試圖用logistics函數(shù)來分類一個罕見的事件。假設分類器試圖估計疾病后患者的死亡。在數(shù)據(jù)中,5%的病人去世了。您可以訓練分類器來預測死亡人數(shù),并使用準確度量來評估性能。如果分類器預測整個數(shù)據(jù)集的死亡為0,那么則95%的情況下是正確的。(也就是說,你的分類器可以直接判定都是不死亡,就可以實現(xiàn)非常高的準確度)
混淆矩陣: 評估分類器性能的更好方法是查看混淆矩陣。 
想象的混亂矩陣的準確度進行比較的當前和預測的分類器分類。組成:二進制混淆矩陣法: TP: 真正:正確預測為實際正的預測值 FP:預測值錯誤地預測了實際的正值。也就是說,預測為正值的負值 FN:假負:預測為負的正值 TN:真負:正確預測為實際負的預測值
從混淆矩陣可以很容易地比較實際標簽結果和預測標簽結果。
精確度和靈敏度 混淆矩陣可以很好地洞察真陽性和假陽性。在某些情況下,是一個更簡潔的度量。 精確度 精準度顯示正類的精度。它衡量了正類預測的正確程度。 
當分類器對所有正值進行完全分類時,最大得分為1。精確度本身并不是很有幫助,因為它忽略了負類。度量通常與召回成對出現(xiàn)?;貞浺脖环Q為敏感性或真陽性率。
靈敏性 靈敏度計算正確檢測到的正類的比率。這個指標給出了模型識別正類的能力。 
對于本教程,我們將使用人口普查數(shù)據(jù)集。目的是使用人口普查數(shù)據(jù)集中的變量來預測收入水平。注意,收入是一個二元變量。 如果收入大于50K,值為1 如果收入小于50K,則為0。
這個變量是你的類別標簽 該數(shù)據(jù)集包括八個分類變量: 工作場所 教育 婚姻的 職業(yè) 關系 種族 性別 國家
此外,六個連續(xù)變量: 年齡 FNLWgt 教育數(shù)字 資本收益 資本損失 小時\周
通過這個例子,您將了解如何用張量流估計訓練線性分類器,以及如何提高準確度指標。 我們將按以下步驟進行: 第一步:導入數(shù)據(jù) 第二步:數(shù)據(jù)轉換 第三步:訓練分類器 第四步:改進模型 第5步:超參數(shù):Lasso & Ridge
開始分布介紹: 步驟1:導入數(shù)據(jù) 首先導入教程中使用的庫。 導入TensorFlow as tf \ import pandas as pd 接下來,從UCI存檔導入數(shù)據(jù)并定義列名稱。您將使用列來命名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./ml/machine-learning-databases/adult/adult.data' PATH_test = 'https://archive.ics./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)
在線存儲的數(shù)據(jù)已經在訓練組和測試組之間進行了劃分。 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) 訓練數(shù)據(jù)集合包含32561組數(shù)據(jù),測試數(shù)據(jù)集中包含16281組數(shù)據(jù); 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需要一個布爾值來訓練分類器。您需要將值從字符串轉換為整數(shù)。標簽存儲為一個對象,但是,您需要將其轉換為一個數(shù)值。下面的代碼創(chuàng)建一個字典,其中包含要轉換的值,并在列項上循環(huán)。請注意,您執(zhí)行此操作兩次,一次針對訓練數(shù)據(jù)集,一次用于測試數(shù)據(jù)集; 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]
訓練數(shù)據(jù)中,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
第二步:數(shù)據(jù)轉化 在用TensorFlow訓練線性分類器之前,需要執(zhí)行幾個步驟。您需要準備要包含在模型中的特征。在基準回歸中,您將使用原始數(shù)據(jù)而不應用任何轉換。 估計器需要有一個特征列表來訓練模型。因此,列的數(shù)據(jù)需要轉換為張量。 一個好的實踐是根據(jù)特征的類型定義兩個特征列表,然后將它們傳遞到估計器的特征列中。 您將從轉換連續(xù)特性開始,然后用分類數(shù)據(jù)定義一個bucket。 數(shù)據(jù)集的特征有兩種格式: 整數(shù) 對象
每個特征都根據(jù)其類型在接下來的兩個變量中列出。 ## 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,以幫助將連續(xù)變量轉換為張量。在下面的代碼中,您可以將CONTI_FEATURES 特征中的所有變量轉換為具有數(shù)值的張量。這對于構建模型是必需的。所有的自變量都需要轉換成合適的張量類型。 下面我們編寫一個代碼,讓您了解feature_column.numeric_column 后面發(fā)生了什么。我們將打印轉換后的值用于解釋,因此不需要理解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]
根據(jù)TensorFlow文檔,有不同的方法來轉換分類數(shù)據(jù)。如果某個功能的詞匯表是已知的,并且沒有足夠的值,則可以使用“詞匯表”創(chuàng)建“分類”列用categorical_column_with_vocabulary_list。它將為所有唯一詞匯表分配一個ID。 例如,如果變量狀態(tài)有三個不同的值: 丈夫 妻子 單身
然后三個ID將被屬性化。例如,丈夫將擁有ID 1,妻子ID 2等等。 為了便于說明,可以使用此代碼在TensorFlow中將對象變量轉換為分類列。 特征性別只能有兩個價值:男性或女性。當我們轉換特征性時,TensorFlow將創(chuàng)建兩個新列,一個用于男性,一個用于女性。如果性別等于男性,那么新的列“男性”將等于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代碼來打印編碼。同樣,您不需要理解代碼,目的是看到轉換 但是,轉換數(shù)據(jù)的一種更快的方法是使用方法:categorical_column_with_hash_bucket。改變稀疏矩陣中的字符串變量是有用的。稀疏矩陣是一個基本上為零的矩陣。您只需要指定存儲桶的數(shù)量和鍵列。桶數(shù)是TensorFlow可以創(chuàng)建的最大組數(shù)。鍵列只是要轉換的列的名稱。 在下面的代碼中,您將在所有分類功能上創(chuàng)建一個循環(huán)。 categorical_features = [tf.feature_column.categorical_column_with_hash_bucket(k, hash_bucket_size=1000) for k in CATE_FEATURES]
第三步:訓練分類器 tensorflow目前為線性回歸和線性分類提供了一個estimator。 線性回歸:LinearRegressor 線性分類:LinearClassifier
線性分類器的語法與線性回歸教程中的語法相同,除了一個參數(shù)n_class。您需要定義特征列、模型目錄,并與線性回歸器進行比較;您已經定義了類的數(shù)量。對于邏輯回歸,類的數(shù)目等于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 既然定義了分類器,就可以創(chuàng)建輸入函數(shù)。該方法與線性回歸器教程中的方法相同。在這里,您使用128的批量大小,然后對數(shù)據(jù)進行無序處理。 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)
您可以使用線性估計所需的參數(shù)創(chuàng)建一個函數(shù),即epoch數(shù)、batches數(shù)和shuffle處理數(shù)據(jù)集或注釋。由于使用pandas方法將數(shù)據(jù)傳遞到模型中,因此需要將x變量定義為pandas dataframe。請注意,您將循環(huán)訪問存儲在FEATURES中的所有數(shù)據(jù)。 讓我們用對象model.train來訓練模型。您可以使用先前定義的函數(shù)向模型提供適當?shù)闹?。請注意,您將批大小設置為128,并且將epoch數(shù)設置為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的數(shù)目設置為1,即數(shù)據(jù)將只輸入模型一次。 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%。仔細分析,你會發(fā)現(xiàn)預測和召回都很低。
第四部:模型改進 既然你有了一個基準模型,你可以嘗試改進它,也就是說,提高精確度。在前面的教程中,您學習了如何通過交互項提高預測能力。在本教程中,您將通過向回歸添加一個多項式項。 當數(shù)據(jù)存在非線性時,多項式回歸是有用的。有兩種方法可以捕獲數(shù)據(jù)中的非線性。 增加多項式項 將連續(xù)變量變?yōu)殡x散變量
多項式項 從下圖中,您可以看到什么是多項式回歸。它是一個具有不同冪次的x變量的方程。二次多項式回歸有兩個變量,x和x的平方。三度有三個變量,x、$x^ 2、\和\x^ 3$ 
下面,我們構造了一個有兩個變量的圖,x和y。很明顯,這種關系不是線性的。如果我們添加線性回歸,我們可以看到模型無法捕獲模式(左圖)。 現(xiàn)在,從下面的圖片看左邊的圖片,我們在回歸中添加了五項。 
這個模型現(xiàn)在可以更好地捕捉模式。這是多項式回歸的強大。 
讓我們回到我們的例子。年齡與收入沒有線性關系。由于兒童或年輕人不工作,早年的收入可能接近零。然后它在工作年齡上增加,在退休期間減少。它通常是一個倒U形。捕獲這種模式的一種方法是在回歸中添加一個二次項。
讓我們看看它是否提高了精確度。 您需要將這個新特性添加到數(shù)據(jù)集和連續(xù)特性列表中。
在訓練和測試數(shù)據(jù)集中添加新的變量,這樣編寫函數(shù)就更方便了。 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 函數(shù)有3個參數(shù):
定義訓練集 定義測試集 var_name='age':定義要轉換的變量
您可以使用對象POW(2)來調整可變年齡。請注意,新變量名為“new”
現(xiàn)在編寫了函數(shù)square_var,就可以創(chuàng)建新的數(shù)據(jù)集。 df_train_new, df_test_new = square_var(df_train, df_test, var_name = 'age')
如下所示,數(shù)據(jù)集多了一個新的特征: print(df_train_new.shape, df_test_new.shape) 平方變量在數(shù)據(jù)集中稱為new。您需要將其添加到連續(xù)功能列表中。 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] 請注意,更改了圖形的目錄。不能在同一目錄中訓練不同的模型。這意味著,你需要改變參數(shù) 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) 現(xiàn)在分類器是用新的數(shù)據(jù)集設計的,那么就可以訓練和評估模型了。 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根據(jù)數(shù)字特征所處的范圍將其轉換為若干特定特征,這些新特征中的每一個都指示一個人的年齡是否在該范圍內。 利用這些新特性,線性模型可以通過學習每個桶的不同權重來捕獲關系。 在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這個詞中,它是特征交叉。特征交叉是創(chuàng)建現(xiàn)有特征組合的新特征的一種方法,這對于無法對特征之間的交互進行建模的線性分類器很有幫助。 你可以用教育這樣的另一個特征來劃分年齡。也就是說,有些群體的收入可能很高,而其他群體的收入可能很低(例如博士生)。 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)] 要創(chuàng)建交叉特征列,請使用帶變量的crossed_column在括號中交叉。散列桶大小表示最大的交叉可能性。要在變量之間創(chuàng)建交互(至少有一個變量需要分類),可以使用tf.feature_column.crossed_column。要使用此對象,需要在方括號中添加要交叉的變量和第二個參數(shù)bucket size。bucket size是變量中可能的最大組數(shù)。這里你把它設為1000,因為你不知道年齡組的確切數(shù)目。 在將其添加到功能列之前需要平方。您還可以將新特性添加到特性列,并準備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%。 最后,您可以添加一個正則化項來防止過度擬合。
|