Tensorflow-FeutureColumns-數(shù)據(jù)格式-機(jī)器學(xué)習(xí)

這篇文章主要介紹tensorflow對(duì)數(shù)據(jù)的處理知識(shí):特征列feature columns娇豫。

特征列FeatureColumns

特征列是指一組數(shù)據(jù)的相關(guān)特征匙姜,包含了數(shù)據(jù)的相關(guān)類型和長(zhǎng)度等信息。
在前面的鳶尾花案例中冯痢,我們使用了下面的代碼拼合特征列,你可以在iris項(xiàng)目中添加新的測(cè)試文件test.py并運(yùn)行它觀看輸出效果:

import os
import pandas as pd
import tensorflow as tf

FUTURES = ['SepalLength', 'SepalWidth','PetalLength', 'PetalWidth', 'Species']
SPECIES = ['Setosa', 'Versicolor', 'Virginica']

#格式化數(shù)據(jù)文件的目錄地址
dir_path = os.path.dirname(os.path.realpath(__file__))
train_path=os.path.join(dir_path,'iris_training.csv')
test_path=os.path.join(dir_path,'iris_test.csv')

#載入訓(xùn)練數(shù)據(jù)
train = pd.read_csv(train_path, names=FUTURES, header=0)
train_x, train_y = train, train.pop('Species')

#載入測(cè)試數(shù)據(jù)
test = pd.read_csv(test_path, names=FUTURES, header=0)
test_x, test_y = test, test.pop('Species')

#拼合特征列
feature_columns = []
for key in train_x.keys():
    feature_columns.append(tf.feature_column.numeric_column(key=key))

print(feature_columns);

以上代碼輸出如下內(nèi)容(整理后)

[
    _NumericColumn(key='SepalLength', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None),
    _NumericColumn(key='SepalWidth', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None), 
    _NumericColumn(key='PetalLength', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None), 
    _NumericColumn(key='PetalWidth', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None)
]

feature_columns = []氮昧,它是一個(gè)列表,被添加append了多個(gè)包含了多個(gè)feature_column.numeric_column()方法生成的特征列浦楣,每個(gè)特征列包含五個(gè)字段:

  • 關(guān)鍵字key袖肥,用來(lái)標(biāo)識(shí)每一列的名稱,避免混淆振劳。
  • 形狀shape, 數(shù)據(jù)的形狀椎组,見(jiàn)下面。
  • 默認(rèn)值default_value历恐。
  • 數(shù)據(jù)類型dtype寸癌,默認(rèn)是浮點(diǎn)小數(shù)tf.float32。
  • 標(biāo)準(zhǔn)化函數(shù)normalizer_fn弱贼,可以對(duì)每個(gè)每行數(shù)據(jù)進(jìn)行處理蒸苇。

形狀shape

關(guān)于shape,比如shape=3表示[r,g,b]類型的三元列表吮旅,類似[0,100,255]溪烤。shape=[4,3]表示下圖的4行3列的矩陣,類似[[1,0,0] [0,1,0] [0,0,1] [0,0,0]]。

4x3矩陣:4行3列

在python中還有一類和方括號(hào)[]列表類似的數(shù)據(jù)格式:小括號(hào)元組()檬嘀。元組基本上就是每個(gè)元素都不重復(fù)的列表槽驶。
但是這里就有一個(gè)問(wèn)題,mylist=(3)這句話到底是生成(3)這樣的元組呢鸳兽,還是生成一個(gè)類似(x,y,z)有三個(gè)元素的元組呢掂铐?答案是后者!
如果需要生成只包含3這個(gè)數(shù)字的元組贸铜,你需要在3后面強(qiáng)加一個(gè)逗號(hào):
mylist=(3,)


轉(zhuǎn)化過(guò)程

我們把這段for循環(huán)改一下堡纬,把train_x,train_x.keys()和key以及轉(zhuǎn)化完畢的特征列column打印出來(lái)蒿秦,仔細(xì)看看數(shù)據(jù)的變化過(guò)程:

feature_columns = []
print(train_x);
print(train_x.keys());
for key in train_x.keys():
    print(key);
    print(tf.feature_column.numeric_column(key=key));
    feature_columns.append(tf.feature_column.numeric_column(key=key))

它們的情況:

  • iris_training.csv是我們的原始數(shù)據(jù)烤镐,如下,具體情況之前文章詳細(xì)解說(shuō)過(guò):
120,4,setosa,versicolor,virginica
6.4,2.8,5.6,2.2,2
5.0,2.3,3.3,1.0,1
4.9,2.5,4.5,1.7,2
4.9,3.1,1.5,0.1,0
...
  • train_x是pandas模塊讀取的csv數(shù)據(jù)棍鳖,使用pd.read_csv()方法炮叶,得到的是120行乘以4列的數(shù)據(jù)表[120 rows x 4 columns]
     SepalLength  SepalWidth  PetalLength  PetalWidth
0            6.4         2.8          5.6         2.2
1            5.0         2.3          3.3         1.0
2            4.9         2.5          4.5         1.7
...
[120 rows x 4 columns]
  • train_x.keys()包含了四個(gè)關(guān)鍵字和一個(gè)數(shù)據(jù)類型對(duì)象dtype
Index(['SepalLength', 'SepalWidth', 'PetalLength', 'PetalWidth'], dtype='object')
  • key是關(guān)鍵字名稱,numeric_column(key=key)得到的單個(gè)特征列和上面展示的一樣
SepalLength
_NumericColumn(key='SepalLength', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None)

數(shù)據(jù)流程

在之前的鳶尾花案例中渡处,我們從csv讀取數(shù)據(jù)镜悉,組織成為特征列feature_columns并編寫了喂食數(shù)據(jù)的函數(shù)input_fn,然后利用特征列創(chuàng)建了qiu zh器中的深度神經(jīng)網(wǎng)絡(luò)分類器estimator.DNNClassifier医瘫,然后利用喂食函數(shù)input_fn把讀取的數(shù)據(jù)喂食到DNNClassifier中進(jìn)行訓(xùn)練侣肄、評(píng)估和預(yù)測(cè)。


數(shù)值列numeric_column

我們?cè)谏厦媸褂玫木褪菙?shù)值列numeric_column醇份,它的默認(rèn)格式如下

numeric_column(
    key,
    shape=(1,),
    default_value=None,
    dtype=tf.float32,
    normalizer_fn=None
)

你可以用下面的代碼測(cè)試:

import tensorflow as tf

price = {'price': [[1.], [2.], [3.], [4.]]}  # 4行樣本

column = tf.feature_column.numeric_column('price', normalizer_fn=lambda x:x+2)
tensor = tf.feature_column.input_layer(price,[column])

with tf.Session() as session:
    print(session.run([tensor]))

將會(huì)輸出以下內(nèi)容稼锅,每個(gè)數(shù)值都被+2處理了:

[array([[3.],
       [4.],
       [5.],
       [6.]], dtype=float32)]

分箱列Bucketized column

分箱是指把一個(gè)連續(xù)的數(shù)字范圍分成幾段,比如我們經(jīng)常說(shuō)的【80后僚纷,90后矩距,00后,10后】這些就是把一個(gè)連續(xù)的年份(1980~現(xiàn)在2018)分成了4段怖竭,我們把這些年份分別寫在39張卡片上锥债,然后準(zhǔn)備四個(gè)箱子,分別標(biāo)上【0號(hào)箱80后】【1號(hào)箱90后】【2號(hào)箱00后】【3號(hào)箱10后】痊臭,卡片1980~1989放入【0號(hào)箱】哮肚,卡片1990~1999放入【1號(hào)箱】...


為什么這樣做?

在我們分箱之前广匙,我們的用excel填寫100個(gè)人的出生年代绽左,那么會(huì)是

  years
0  1988
1  1999
2  2013
3  2004
...

如果我們要用這些數(shù)據(jù)分析90后的身高分布情況,那么這樣的數(shù)據(jù)看起來(lái)就比較麻煩艇潭。而分箱后的數(shù)據(jù)就好多了,我們用0表示80后,1表示90后蹋凝,2表示00后鲁纠,3表示10后:

  years
0  0  #1988
1  1  #1999
2  3  #2013
3  2  #2004
...

我們繼續(xù)更進(jìn)一步,比起簡(jiǎn)單的數(shù)字鳍寂,Tensorflow更喜歡列表類型改含,更善于從列表或矩陣中估算出變化規(guī)律。
共有4段年代迄汛,我們表示為包含4個(gè)元素的列表[y0,y1,y2,y3],80后第一個(gè)元素中招捍壤,標(biāo)記為[1,0,0,0];90后第二個(gè)元素中招鞍爱,[0,1,0,0],以此類推鹃觉,我們得到

0  [1,0,0,0]  #1988
1  [0,1,0,0]  #1999
2  [0,0,0,1]  #2013
3  [0,0,1,0]  #2004

在這個(gè)例子中,我們把1980~now年份用3個(gè)邊界(1990睹逃,2000盗扇,2010)劃為4段(假設(shè)我們的數(shù)據(jù)不存在早于1980出生的人),我們可以使用下面的代碼進(jìn)行測(cè)試:

import tensorflow as tf

years = {'years': [1999,2013,1987,2005]}  

years_fc = tf.feature_column.numeric_column('years')
column = tf.feature_column.bucketized_column(years_fc, [1990, 2000, 2010])

tensor = tf.feature_column.input_layer(years, [column])

with tf.Session() as session:
    print(session.run([tensor]))

運(yùn)行得到下面的輸出沉填,可以看到每一個(gè)年份的列表對(duì)應(yīng)的元素變成了1疗隶,而其他元素為0:

[array([[0., 1., 0., 0.],  #1999
       [0., 0., 0., 1.],  #2013
       [1., 0., 0., 0.],  #1987
       [0., 0., 1., 0.]],  #2005
       dtype=float32)]

Bucketized也被稱作分桶,在這里參考谷歌官方說(shuō)法統(tǒng)一稱為分箱翼闹。


關(guān)于獨(dú)熱編碼one-hot

顧名思義斑鼻,在上面的列表中[0,1,0,0]中只有第二個(gè)元素為1,熱起來(lái)了猎荠,其他元素都是0坚弱。所以叫獨(dú)熱。

可以這樣說(shuō)法牲,如果某個(gè)特征有M種可能史汗,而我們有三個(gè)數(shù)據(jù)[m1,m2,m3],可以把它變成一個(gè)由0和1組成3xM的二維矩陣,類似下圖:

分箱特征欄Bucketized column就是把一維的普通列表變成了二維矩陣拒垃,升維了停撞!

為什么會(huì)這樣做?不是把數(shù)據(jù)復(fù)雜化了嗎悼瓮?
其實(shí)是把數(shù)據(jù)簡(jiǎn)化了戈毒,獨(dú)熱之后我們只剩下0或1,1只是代表一個(gè)位置横堡,并不關(guān)注這一行具體代表什么含義埋市。

首先,升維往往能讓數(shù)據(jù)直接的關(guān)系更加清楚命贴,更易于找到規(guī)律道宅。其次食听,也是更重要的,分箱之后可以讓無(wú)序數(shù)據(jù)之間關(guān)系更加正確污茵。

比如我們有三種商品分類樱报,['服裝','食品','化妝品'],如果我們只是把它轉(zhuǎn)化為[0,1,2]泞当,那么我們?nèi)绻趲缀慰臻g中計(jì)算它們之間的距離關(guān)系迹蛤,三個(gè)類別代表線段上的三個(gè)點(diǎn),我們會(huì)得到服裝距離食品是1-0=1襟士,食品距離化妝品是2-1=1盗飒,而服裝距離化妝品是2-0=2;計(jì)算機(jī)就會(huì)誤以為化妝品和服裝關(guān)系很遠(yuǎn)陋桂。但實(shí)際上這毫無(wú)依據(jù)逆趣,這種錯(cuò)誤關(guān)系完全是由于我們的數(shù)據(jù)格式引發(fā)的。


直線上兩點(diǎn)間距離公式

再看分箱后的結(jié)果章喉,三種類別變?yōu)榉b[1,0,0],食品[0,1,0],化妝品[0,0,1],它們代表三維空間中的三個(gè)點(diǎn)汗贫,利用距離平方等于每個(gè)維度平方之和,我們得到它們?nèi)咧g的距離都是根號(hào)2秸脱,完全相等落包,沒(méi)有任何偏倚。


空間中兩點(diǎn)間距離公式

分類識(shí)別列Categorical identity column

很多數(shù)據(jù)都不是數(shù)字格式的摊唇,比如動(dòng)物的類別“貓狗牛羊”咐蝇、商品的類別“食品服裝數(shù)碼”、人的姓氏“張王李趙”...這些都是文字格式的巷查。

但是有序,Tensorflow只能處理數(shù)字。

我們必須把字符名稱變?yōu)閿?shù)字模式岛请,或者說(shuō)我們必須用數(shù)字來(lái)表示文字旭寿。
參照上面的分箱的方法,我們可以創(chuàng)建很多箱子表示各種動(dòng)物崇败,把每個(gè)種類動(dòng)物名稱寫在卡片上盅称,放到對(duì)應(yīng)的箱子里。

假設(shè)我們有4種寵物分類:貓后室,狗缩膝,兔子,豬岸霹,對(duì)應(yīng)列表[a1,a2,a3,a4]那么就有:


寵物類別的獨(dú)熱編碼

語(yǔ)法格式

categorical_column_with_identity(
    key,
    num_buckets,
    default_value=None
)

測(cè)試代碼

import tensorflow as tf

pets = {'pets': [2,3,0,1]}  #貓0疾层,狗1,兔子2贡避,豬3

column = tf.feature_column.categorical_column_with_identity(
    key='pets',
    num_buckets=4)

indicator = tf.feature_column.indicator_column(column)
tensor = tf.feature_column.input_layer(pets, [indicator])

with tf.Session() as session:
        print(session.run([tensor]))

運(yùn)行輸出結(jié)果

[array([[0., 0., 1., 0.], #兔子
       [0., 0., 0., 1.], #豬
       [1., 0., 0., 0.], #貓
       [0., 1., 0., 0.]], dtype=float32)] #狗

分類詞匯列Categorical vocabulary column

在上面的示例圖中我們看到痛黎,必須手工在excel里面把cat予弧、dog、rabbit湖饱、pig轉(zhuǎn)為0123才行桌肴,能不能更快一些?
tf.feature_column.categorical_column_with_vocabulary_list這個(gè)方法就是將一個(gè)單詞列表生成為分類詞匯特征列的琉历。

語(yǔ)法格式

categorical_column_with_vocabulary_list(
    key,
    vocabulary_list,
    dtype=None,
    default_value=-1,
    num_oov_buckets=0
)

num_ovv_buckets,Out-Of-Vocabulary水醋,如果數(shù)據(jù)里面的某個(gè)單詞沒(méi)有對(duì)應(yīng)的箱子旗笔,比如出現(xiàn)了老鼠mouse,那么就會(huì)在【箱子總數(shù)4~num_ovv_buckets+ 箱子總數(shù)=7】拄踪,如果num_ovv=3,那么老鼠mouse會(huì)被標(biāo)記為4~7中的某個(gè)數(shù)字蝇恶,可能是5,也可能是4或6惶桐。num_ovv不可以是負(fù)數(shù)撮弧。

測(cè)試代碼

import tensorflow as tf

pets = {'pets': ['rabbit','pig','dog','mouse','cat']}  

column = tf.feature_column.categorical_column_with_vocabulary_list(
    key='pets',
    vocabulary_list=['cat','dog','rabbit','pig'], 
    dtype=tf.string, 
    default_value=-1,
    num_oov_buckets=3)

indicator = tf.feature_column.indicator_column(column)
tensor = tf.feature_column.input_layer(pets, [indicator])

with tf.Session() as session:
    session.run(tf.global_variables_initializer())
    session.run(tf.tables_initializer())
    print(session.run([tensor]))

輸出結(jié)果如下,注意到獨(dú)熱list 有7個(gè)元素姚糊,這是由于【貓狗兔子豬4個(gè)+num_oov_buckets】得到的贿衍。

[array([[0., 0., 1., 0., 0., 0., 0.], #'rabbit'
       [0., 0., 0., 1., 0., 0., 0.], #'pig'
       [0., 1., 0., 0., 0., 0., 0.], #'dog'
       [0., 0., 0., 0., 0., 1., 0.], #mouse
       [1., 0., 0., 0., 0., 0., 0.]], dtype=float32)] #'cat'

單詞有些時(shí)候會(huì)比較多,這時(shí)候我們可以直接從文件中讀取文字列表:

import os
import tensorflow as tf

pets = {'pets': ['rabbit','pig','dog','mouse','cat']}  

dir_path = os.path.dirname(os.path.realpath(__file__))
fc_path=os.path.join(dir_path,'pets_fc.txt')

column=tf.feature_column.categorical_column_with_vocabulary_file(
        key="pets",
        vocabulary_file=fc_path,
        num_oov_buckets=0)

indicator = tf.feature_column.indicator_column(column)
tensor = tf.feature_column.input_layer(pets, [indicator])

with tf.Session() as session:
    session.run(tf.global_variables_initializer())
    session.run(tf.tables_initializer())
    print(session.run([tensor]))

其中pets_fc.txt每行一個(gè)單詞如:

cat
dog
rabbit
pig

管理員權(quán)限運(yùn)行救恨,得到以下結(jié)果贸辈,這次我們oov使用了0,并沒(méi)有增加元素?cái)?shù)量肠槽,但是也導(dǎo)致了mouse變成了全部是0的列表

[array([[0., 0., 1., 0.], #rabbit
       [0., 0., 0., 1.], #pig
       [0., 1., 0., 0.], #dog
       [0., 0., 0., 0.],#mosue
       [1., 0., 0., 0.]], dtype=float32)] #cat

哈希欄Hashed Column

仍然是分箱擎淤,但是這一次我們更加關(guān)心“我希望有多少分類?”秸仙,也許我們有150個(gè)單詞嘴拢,但我們只希望分成100個(gè)分類,多下來(lái)50個(gè)的怎么處理寂纪?

取余數(shù)席吴!101除以100余1,我們就把第101種單詞也標(biāo)記為1弊攘,和我們的第1種單詞變成了同一類抢腐,如此類推,第102種和2種同屬第2類,第103種和3種同屬第3類...

我們把計(jì)算余數(shù)的操作寫為%襟交;那么第N個(gè)單詞屬于N%100類迈倍。

feature_id = hash(raw_feature) % hash_buckets_size

哈希列HashedColumn對(duì)于大數(shù)量的類別很有效(vocabulary的file模式也不錯(cuò)),尤其是語(yǔ)言文章處理捣域,將文章分句切詞之后啼染,往往得到大數(shù)量的單詞宴合,每個(gè)單詞作為一個(gè)類別,對(duì)于機(jī)器學(xué)習(xí)來(lái)說(shuō)迹鹅,更容易找到潛在的單詞之間的語(yǔ)法關(guān)系卦洽。

但哈希也會(huì)帶來(lái)一些問(wèn)題。如下圖所示斜棚,我們把廚房用具kitchenware和運(yùn)動(dòng)商品sports都標(biāo)記成了分類12阀蒂。這看起來(lái)是錯(cuò)誤的,不過(guò)很多時(shí)候tensorflow還是能夠利用其他的特征列把它們區(qū)分開(kāi)弟蚀。所以蚤霞,為了有效減少內(nèi)存和計(jì)算時(shí)間,可以這么做义钉。


語(yǔ)法格式

categorical_column_with_hash_bucket(
    key,
    hash_bucket_size,
    dtype=tf.string
)

測(cè)試代碼

import tensorflow as tf

colors = {'colors': ['green','red','blue','yellow','pink','blue','red','indigo']}  

column = tf.feature_column.categorical_column_with_hash_bucket(
        key='colors',
        hash_bucket_size=5,
    )

indicator = tf.feature_column.indicator_column(column)
tensor = tf.feature_column.input_layer(colors, [indicator])

with tf.Session() as session:
    session.run(tf.global_variables_initializer())
    session.run(tf.tables_initializer())
    print(session.run([tensor]))

運(yùn)行得到如下的輸出,我們注意到red和blue轉(zhuǎn)化后都是一樣的昧绣,yellow,indigo捶闸,pink也都一樣夜畴,這很糟糕。

[array([[0., 0., 0., 0., 1.],#green
       [1., 0., 0., 0., 0.],#red
       [1., 0., 0., 0., 0.],#blue
       [0., 1., 0., 0., 0.],#yellow
       [0., 1., 0., 0., 0.],#pink
       [1., 0., 0., 0., 0.],#blue
       [1., 0., 0., 0., 0.],#red
       [0., 1., 0., 0., 0.]], dtype=float32)]#indigo

將hash_bucket_size箱子數(shù)量設(shè)置為10删壮,這個(gè)問(wèn)題可以得到解決贪绘。箱子數(shù)量的旋轉(zhuǎn)很重要,越大獲得的分類結(jié)果越精確醉锅。


交叉列Crossed column

交叉列可以把多個(gè)特征合并成為一個(gè)特征兔簇,比如把經(jīng)度longitude、維度latitude兩個(gè)特征合并為地理位置特征location硬耍。
如下圖垄琐,我們把Atlanda城市范圍的地圖橫向分成100區(qū)間,豎向分成100區(qū)間经柴,總共分割成為10000塊小區(qū)域狸窘。(也許接下來(lái)我們需要從數(shù)據(jù)分析出哪里是富人區(qū)哪里是窮人區(qū))

測(cè)試代碼如下:

import tensorflow as tf

featrues = {
        'longtitude': [19,61,30,9,45],
        'latitude': [45,40,72,81,24]
    }

longtitude = tf.feature_column.numeric_column('longtitude')
latitude = tf.feature_column.numeric_column('latitude')

longtitude_b_c = tf.feature_column.bucketized_column(longtitude, [33,66])
latitude_b_c  = tf.feature_column.bucketized_column(latitude,[33,66])

column = tf.feature_column.crossed_column([longtitude_b_c, latitude_b_c], 12)

indicator = tf.feature_column.indicator_column(column)
tensor = tf.feature_column.input_layer(featrues, [indicator])

with tf.Session() as session:
    session.run(tf.global_variables_initializer())
    session.run(tf.tables_initializer())
    print(session.run([tensor]))

上面的代碼中進(jìn)行了分箱操作,分成~33,33~66,66~三箱敬辣,運(yùn)行得到下面輸出

[array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
       [0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0.]], dtype=float32)]

指示列Indicator Columns和嵌入列Embeding Columns

我們?cè)谏厦娴拇a中使用了很多次指示列命令

indicator = tf.feature_column.indicator_column(column)
tensor = tf.feature_column.input_layer(featrues, [indicator])

指示列并不直接操作數(shù)據(jù),但它可以把各種分類特征列轉(zhuǎn)化成為input_layer()方法接受的特征列陋气。

當(dāng)我們遇到成千上萬(wàn)個(gè)類別的時(shí)候,獨(dú)熱列表就會(huì)變的特別長(zhǎng)[0,1,0,0,0,....0,0,0]引润。嵌入列可以解決這個(gè)問(wèn)題巩趁,它不再限定每個(gè)元素必須是0或1,而可以是任何數(shù)字淳附,從而使用更少的元素?cái)?shù)表現(xiàn)數(shù)據(jù)议慰。

如下圖蠢古,我們最初的數(shù)據(jù)可能是4個(gè)單詞比如dog、spoon别凹、scissors草讶、guitar,然后這些單詞被分類特征列Categorical處理成為數(shù)字0炉菲、32堕战、79、80拍霜,接下來(lái)我們可以使用指示列來(lái)處理成為獨(dú)熱的01列表(圖中假設(shè)我們有81種單詞分類)践啄,也可以按照嵌入Embeding列來(lái)處理成小數(shù)元素組成的3元素?cái)?shù)列。

分類列Categorical沉御、指示列Indicator和嵌入列Embeding

嵌入列中的小數(shù)只在train訓(xùn)練的時(shí)候自動(dòng)計(jì)算生成,能夠有效增加訓(xùn)練模型的效率和性能昭灵,同時(shí)又能便于機(jī)器學(xué)習(xí)從數(shù)據(jù)中發(fā)現(xiàn)潛在的新規(guī)律吠裆。

為什么嵌入Embeding的都是[0.421,0.399,0.512]這樣的3元素列表,而不是4元5元烂完?實(shí)際上有下面的參考算法:


嵌入列表的維數(shù)等于類別總數(shù)開(kāi)4次方试疙,也就是3的4次方等于81種類。


嵌入列語(yǔ)法

embedding_column(
    categorical_column,
    dimension,
    combiner='mean',
    initializer=None,
    ckpt_to_load_from=None,
    tensor_name_in_ckpt=None,
    max_norm=None,
    trainable=True
)

dimention維度抠蚣,即每個(gè)列表元素?cái)?shù)
combiner組合器祝旷,默認(rèn)meam,在語(yǔ)言文字處理中選sqrtn可能更好
initializer初始器
tensor_name_in_ckpt可以從check point中恢復(fù)
ckpt_to_load_from恢復(fù)文件

示例代碼

import tensorflow as tf

features = {'pets': ['dog','cat','rabbit','pig','mouse']}  

pets_f_c = tf.feature_column.categorical_column_with_vocabulary_list(
    'pets',
    ['cat','dog','rabbit','pig'], 
    dtype=tf.string, 
    default_value=-1)

column = tf.feature_column.embedding_column(pets_f_c, 3)
tensor = tf.feature_column.input_layer(features, [column])

with tf.Session() as session:
    session.run(tf.global_variables_initializer())
    session.run(tf.tables_initializer())

    print(session.run([tensor]))

運(yùn)行得到輸出,我們看到由于老鼠mouse沒(méi)有對(duì)應(yīng)的箱子嘶窄,所以元素都為0

[array([[ 0.15651548, -0.620424  ,  0.41636208],
       [-1.0857592 ,  0.03593585,  0.20340031],
       [-0.6021426 , -0.48347804, -0.7165713 ],
       [-0.36875582,  0.4034163 , -1.0998975 ],
       [ 0.        ,  0.        ,  0.        ]], dtype=float32)]

特征列和估算器Estimator

在鳶尾花的案例中怀跛,我們拼接多個(gè)數(shù)值特征列numeric column成為feature_columns列表

feature_columns = []
for key in train_x.keys():
    feature_columns.append(tf.feature_column.numeric_column(key=key))

然后利用特征列創(chuàng)建了深度神經(jīng)網(wǎng)絡(luò)分類器tf.estimator.DNNClassifier:

classifier = tf.estimator.DNNClassifier(
    feature_columns=feature_columns,
    hidden_units=[10, 10],
    n_classes=3,
    model_dir=models_path,
    config=ckpt_config) #

有了這個(gè)DNNClassifier我們就能對(duì)原始數(shù)據(jù)進(jìn)行train、evaluate柄冲、pedict吻谋。
Tensorflow提供了多個(gè)評(píng)估器,但不是每種評(píng)估器都能夠接收所有類型的特征列feature column现横。

  • 線性分類器 linearClassifier和線性回歸器linearRegressor漓拾,接收所有類型特征列;
  • 深度神經(jīng)網(wǎng)絡(luò)分類器DNNClassifier和深度神經(jīng)網(wǎng)絡(luò)回歸器DNNRegressor戒祠,僅接收密集特征列dense column,其他類型特征列必須用指示列indicatorColumn或嵌入列embedingColumn進(jìn)行包裹
  • 線性神經(jīng)網(wǎng)絡(luò)合成分類器linearDNNCombinedClassifier和線性神經(jīng)網(wǎng)絡(luò)合成回歸器linearDNNCombinedRegressor:
    • linear_feature_columns參數(shù)接收所有類型特征列
    • dnn_feature_columns只接收密度特征列dense column

分類列CategoricalColumn和密集列DenseColumn

上面介紹了Tensorflow用于生成特征列的9個(gè)方法(tf.feature_column...)骇两,每個(gè)方法最終都會(huì)得到分類列或者密集列:



權(quán)重分類列WeightedCategoricalColumn

默認(rèn)的CategoricalColumn所有分類的權(quán)重都是一樣的,沒(méi)有輕重主次姜盈。而權(quán)重分類特征列則可以為每個(gè)分類設(shè)置權(quán)重低千。
語(yǔ)法格式

weighted_categorical_column(
    categorical_column,
    weight_feature_key,
    dtype=tf.float32
)

測(cè)試代碼

import tensorflow as tf
from tensorflow.python.feature_column.feature_column import _LazyBuilder

features = {'color': [['R'], ['A'], ['G'], ['B'],['R']],
                  'weight': [[1.0], [5.0], [4.0], [8.0],[3.0]]}

color_f_c = tf.feature_column.categorical_column_with_vocabulary_list(
    'color', ['R', 'G', 'B','A'], dtype=tf.string, default_value=-1
)

column = tf.feature_column.weighted_categorical_column(color_f_c, 'weight')

indicator = tf.feature_column.indicator_column(column)
tensor = tf.feature_column.input_layer(features, [indicator])

with tf.Session() as session:
    session.run(tf.global_variables_initializer())
    session.run(tf.tables_initializer())
    print(session.run([tensor]))

運(yùn)行之后得到下面輸出,權(quán)重改變了獨(dú)熱模式贩据,不僅包含0或1栋操,還帶有權(quán)重值

[array([[1., 0., 0., 0.],
       [0., 0., 0., 5.],
       [0., 4., 0., 0.],
       [0., 0., 8., 0.],
       [3., 0., 0., 0.]], dtype=float32)]

線性模型LinearModel

對(duì)所有特征進(jìn)行線性加權(quán)操作(數(shù)值和權(quán)重值相乘)闸餐。
語(yǔ)法格式

linear_model(
    features,
    feature_columns,
    units=1,
    sparse_combiner='sum',
    weight_collections=None,
    trainable=True
)

測(cè)試代碼

import tensorflow as tf
from tensorflow.python.feature_column.feature_column import _LazyBuilder


def get_linear_model_bias():
    with tf.variable_scope('linear_model', reuse=True):
        return tf.get_variable('bias_weights')


def get_linear_model_column_var(column):
    return tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES,
                             'linear_model/' + column.name)[0]

featrues = {
        'price': [[1.0], [5.0], [10.0]],
        'color': [['R'], ['G'], ['B']]
    }

price_column = tf.feature_column.numeric_column('price')
color_column = tf.feature_column.categorical_column_with_vocabulary_list('color',
                                                                      ['R', 'G', 'B'])
prediction = tf.feature_column.linear_model(featrues, [price_column, color_column])

bias = get_linear_model_bias()
price_var = get_linear_model_column_var(price_column)
color_var = get_linear_model_column_var(color_column)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    sess.run(tf.local_variables_initializer())
    sess.run(tf.tables_initializer())

    sess.run(bias.assign([7.0]))
    sess.run(price_var.assign([[10.0]]))
    sess.run(color_var.assign([[2.0], [2.0], [2.0]]))

    predication_result = sess.run([prediction])

    print(prediction)
    print(predication_result)

運(yùn)行結(jié)果得到

[array([[ 19.],
       [ 59.],
       [109.]], dtype=float32)]

以上全部演示代碼都可以從百度網(wǎng)盤下載(提取密碼:qdvx)


探索人工智能的新邊界

如果您發(fā)現(xiàn)文章錯(cuò)誤,請(qǐng)不吝留言指正矾芙;
如果您覺(jué)得有用舍沙,請(qǐng)點(diǎn)喜歡;
如果您覺(jué)得很有用剔宪,感謝轉(zhuǎn)發(fā)~


END

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拂铡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子葱绒,更是在濱河造成了極大的恐慌感帅,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件地淀,死亡現(xiàn)場(chǎng)離奇詭異失球,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)帮毁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門实苞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人烈疚,你說(shuō)我怎么就攤上這事黔牵。” “怎么了爷肝?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵猾浦,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我灯抛,道長(zhǎng)金赦,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任对嚼,我火速辦了婚禮素邪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘猪半。我一直安慰自己兔朦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布磨确。 她就那樣靜靜地躺著沽甥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪乏奥。 梳的紋絲不亂的頭發(fā)上摆舟,一...
    開(kāi)封第一講書(shū)人閱讀 49,842評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼恨诱。 笑死媳瞪,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的照宝。 我是一名探鬼主播蛇受,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼厕鹃!你這毒婦竟也來(lái)了兢仰?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤剂碴,失蹤者是張志新(化名)和其女友劉穎把将,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體忆矛,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡察蹲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了催训。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片递览。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖瞳腌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情镜雨,我是刑警寧澤嫂侍,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站荚坞,受9級(jí)特大地震影響挑宠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜颓影,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一各淀、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧诡挂,春花似錦碎浇、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至城豁,卻和暖如春苟穆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工雳旅, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留跟磨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓攒盈,卻偏偏與公主長(zhǎng)得像抵拘,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子沦童,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容