基礎(chǔ)|認(rèn)識(shí)機(jī)器學(xué)習(xí)中的邏輯回歸、決策樹、神經(jīng)網(wǎng)絡(luò)算法
1、 邏輯回歸
邏輯回歸。它始于輸出結(jié)果為有實(shí)際意義的連續(xù)值的線性回歸,但是線性回歸對(duì)于分類的問題沒有辦法準(zhǔn)確而又具備魯棒性地分割,因此我們?cè)O(shè)計(jì)出了邏輯回歸這樣一個(gè)算法,它的輸出結(jié)果表征了某個(gè)樣本屬于某類別的概率。邏輯回歸的成功之處在于,將原本輸出結(jié)果范圍可以非常大的θTX 通過sigmoid函數(shù)映射到(0,1),從而完成概率的估測(cè)。sigmoid函數(shù)圖像如下圖所示:
直觀地在二維空間理解邏輯回歸,是sigmoid函數(shù)的特性,使得判定的閾值能夠映射為平面的一條判定邊界,當(dāng)然隨著特征的復(fù)雜化,判定邊界可能是多種多樣的樣貌,但是它能夠較好地把兩類樣本點(diǎn)分隔開,解決分類問題。求解邏輯回歸參數(shù)的傳統(tǒng)方法是梯度下降,構(gòu)造為凸函數(shù)的代價(jià)函數(shù)后,每次沿著偏導(dǎo)方向(下降速度最快方向)邁進(jìn)一小部分,直至N次迭代后到達(dá)最低點(diǎn)。利用Scikit-Learn對(duì)數(shù)據(jù)進(jìn)行邏輯回歸分析。 首先進(jìn)行特征篩選, 特征篩選的方法有很多,主要包含在Scikit_Learn的feature_selection庫(kù)中, 比較簡(jiǎn)單的有通過F檢驗(yàn)(f_regression) 來(lái)給出各個(gè)特征的F值和p值, 從而可以篩選變量(選擇F值大的或者p值小的特征)其次有遞歸特征消除(Recursive Feature Elimination, RFE) 和穩(wěn)定性選擇(Stability Selection) 等比較新的方法。之后就可以利用篩選后的特征建立邏輯回歸模型。
遞歸特征消除的主要思想是反復(fù)的構(gòu)建模型(如SVM或者回歸模型) 然后選出最好的(或者最差的) 的特征(可以根據(jù)系數(shù)來(lái)選) , 把選出來(lái)的特征放到一邊, 然后在剩余的特征上重復(fù)這個(gè)過程, 直到遍歷所有特征。 這個(gè)過程中特征被消除的次序就是特征的排序。 因此, 這是一種尋找最優(yōu)特征子集的貪心算法。 Scikit-Learn提供了RFE包, 可以用于特征消除, 還提供了RFECV, 可以通過交叉驗(yàn)證來(lái)對(duì)特征進(jìn)行排序。
代碼體驗(yàn)
- import pandas as pd
- input_file='./bankloan.xls'
- data=pd.read_excel(input_file)
- data.head()
- X=data.iloc[:,:8].as_matrix()#將矩陣轉(zhuǎn)換為Numpy數(shù)組
- Y=data.iloc[:,8].as_matrix()
- from sklearn.linear_model import LogisticRegression as LR
- from sklearn.linear_model import RandomizedLogisticRegression as RLR
- rlr=RLR()#建立隨機(jī)邏輯回歸模型,篩選變量
- rlr.fit(X,Y) #訓(xùn)練模型
- rlr.get_support()#獲取特征篩選結(jié)果,也可以通過.scores_方法獲取各個(gè)特征的分?jǐn)?shù)
- x=data.iloc[:,0:8]
- X = x[x.columns[rlr.get_support()]].as_matrix() #篩選好特征
- lr=LR()#建立邏輯回歸模型
- lr.fit(X,Y)
- print("正確率:%s" % lr.score(X,Y))
- x.columns[rlr.get_support()]
2、決策樹
決策樹(decision tree):是一個(gè)樹結(jié)構(gòu)(可以是二叉樹或非二叉樹)。其每個(gè)非葉節(jié)點(diǎn)表示一個(gè)特征屬性上的測(cè)試,每個(gè)分支代表這個(gè)特征屬性在某個(gè)值域上的輸出,而每個(gè)葉節(jié)點(diǎn)存放一個(gè)類別。使用決策樹進(jìn)行決策的過程就是從根節(jié)點(diǎn)開始,測(cè)試待分類項(xiàng)中相應(yīng)的特征屬性,并按照其值選擇輸出分支,直到到達(dá)葉子節(jié)點(diǎn),將葉子節(jié)點(diǎn)存放的類別作為決策結(jié)果。
決策樹構(gòu)造:使用屬性選擇度量來(lái)選擇將元組最好地劃分成不同的類的屬性。所謂決策樹的構(gòu)造就是進(jìn)行屬性選擇度量確定各個(gè)特征屬性之間的拓?fù)浣Y(jié)構(gòu)。構(gòu)造決策樹的關(guān)鍵步驟是分裂屬性。所謂分裂屬性就是在某個(gè)節(jié)點(diǎn)處按照某一特征屬性的不同劃分構(gòu)造不同的分支,其目標(biāo)是讓各個(gè)分裂子集盡可能地“純”。盡可能“純”就是盡量讓一個(gè)分裂子集中待分類項(xiàng)屬于同一類別。分裂屬性分為三種不同的情況:
- 屬性是離散值且不要求生成二叉決策樹。此時(shí)用屬性的每一個(gè)劃分作為一個(gè)分支。
- 屬性是離散值且要求生成二叉決策樹。此時(shí)使用屬性劃分的一個(gè)子集進(jìn)行測(cè)試,按照“屬于此子集”和“不屬于此子集”分成兩個(gè)分支。
- 屬性是連續(xù)值。此時(shí)確定一個(gè)值作為分裂點(diǎn)split_point,按照>split_point和<=split_point生成兩個(gè)分支。
構(gòu)造決策樹的關(guān)鍵性內(nèi)容是進(jìn)行屬性選擇度量,屬性選擇度量是一種選擇分裂準(zhǔn)則,是將給定的類標(biāo)記的訓(xùn)練集合的數(shù)據(jù)劃分D“最好”地分成個(gè)體類的啟發(fā)式方法,它決定了拓?fù)浣Y(jié)構(gòu)及分裂點(diǎn)split_point的選擇。
屬性選擇度量算法有很多,一般使用自頂向下遞歸分治法,并采用不回溯的貪心策略。
代碼體驗(yàn)
- import pandas as pd
- input_file='./sales_data.xls'
- data=pd.read_excel(input_file,index_col='序號(hào)')
- data[data=="好"]=1
- data[data=="是"]=1
- data[data=="高"]=1
- data[data!=1]=-1
- #注意類型,上面輸出可以看出是object類型,要轉(zhuǎn)換成int類型
- X=x.as_matrix().astype(int)
- Y=y.as_matrix().astype(int)
- from sklearn.tree import DecisionTreeClassifier as DTC#導(dǎo)入分類樹
- dtc=DTC()
- dtc.fit(X,Y)
- from sklearn.tree import export_graphviz
- from sklearn.externals.six import StringIO
- with open("tree.dot", 'w') as f:
- f = export_graphviz(dtc, feature_names = x.columns, out_file = f)
3、神經(jīng)網(wǎng)絡(luò)
人工神經(jīng)網(wǎng)絡(luò)(ANN)
人工神經(jīng)網(wǎng)絡(luò)(Artificial Neural Network,即ANN ),是20世紀(jì)80 年代以來(lái)人 工智能領(lǐng)域興起的研究熱點(diǎn)。它從信息處理角度對(duì)人腦神經(jīng)元網(wǎng)絡(luò)進(jìn)行抽象, 建立某種 簡(jiǎn)單模型,按不同的連接方式組成不同的網(wǎng)絡(luò)。在工程與學(xué)術(shù)界也常直接簡(jiǎn)稱為神 經(jīng)網(wǎng)絡(luò)或類神經(jīng)網(wǎng)絡(luò)。神經(jīng)網(wǎng)絡(luò)是一種運(yùn)算模型,由大量的節(jié)點(diǎn)(或稱神經(jīng)元)之間相 互聯(lián)接構(gòu)成。每個(gè)節(jié)點(diǎn)代表一種特定的輸出函數(shù),稱為激勵(lì)函數(shù)(activation function)。每?jī)蓚€(gè)節(jié)點(diǎn)間的連接都代表一個(gè)對(duì)于通過該連接信號(hào)的加 權(quán)值,稱之為權(quán)重,這相當(dāng)于人工神經(jīng)網(wǎng)絡(luò)的記憶。網(wǎng)絡(luò)的輸出則依網(wǎng)絡(luò)的連接方式, 權(quán)重值和激勵(lì)函數(shù)的不同而不同。而網(wǎng)絡(luò)自身通常都是對(duì)自然界某種算法或者函數(shù) 的逼近,也可能是對(duì)一種邏輯策略的表達(dá)。
Keras簡(jiǎn)介
Keras:基于Python的深度學(xué)習(xí)庫(kù)
Keras是一個(gè)高層神經(jīng)網(wǎng)絡(luò)API,Keras由純Python編寫而成并基Tensorflow、Theano以及CNTK后端。Keras 為支持快速實(shí)驗(yàn)而生,能夠把你的idea迅速轉(zhuǎn)換為結(jié)果 。
常用模塊簡(jiǎn)介:
1.optimizers
包:keras.optimizers :
這個(gè)是用來(lái)選用優(yōu)化方法的,里面有SGD,Adagrad,Adadelta,RMSprop,Adam可選 。
2.objectives
包:keras.objectives
該模塊主要負(fù)責(zé)為神經(jīng)網(wǎng)絡(luò)附加損失函數(shù),即目標(biāo)函
這個(gè)定義了用什么形式的誤差來(lái)優(yōu)化,有
mean_squared_error / mse:平均方差
mean_absolute_error / mae:絕對(duì)誤差
mean_absolute_percentage_error / mape:平均絕對(duì)百分差
mean_squared_logarithmic_error / msle:對(duì)數(shù)誤差
squared_hinge
hinge
binary_crossentropy: Also known as logloss.
categorical_crossentropy:使用這個(gè)目標(biāo)函數(shù)需要設(shè)置label為二進(jìn)制數(shù)組的形式。
3.model
包:keras.models 這是Keras中最主要的一個(gè)模塊,用于對(duì)各個(gè)組件進(jìn)行組裝
from keras.model import Sequential
model = keras.models.Sequential() 初始化一個(gè)神經(jīng)網(wǎng)絡(luò)
model.add(......)#add方法進(jìn)行組裝
4.layers
包:keras.layers
該模塊主要用于生成神經(jīng)網(wǎng)絡(luò)層,包含多種類型,如Core layers、Convolutional layers等
from keras.layers import Dense
model.add(Dense(input_dim=3,output_dim=5)#加入隱藏層
5.Initializations
包:keras.initializations
該模塊主要負(fù)責(zé)對(duì)模型參數(shù)(權(quán)重)進(jìn)行初始化,初始化方法包括:uniform、lecun_uniform、normal、orthogonal、zero、glorot_normal、he_normal等
model.add(Dense(input_dim=3,output_dim=5,init='uniform')) #加入帶初始化(uniform)的隱含層
6.Activations
包:keras.activations、keras.layers.advanced_activations(新激活函數(shù))
該模塊主要負(fù)責(zé)為神經(jīng)層附加激活函數(shù),如linear、sigmoid、hard_sigmoid、tanh、softplus、relu、 softplus以及LeakyReLU等比較新的激活函數(shù)
Keras的Sequential模型
Keras的核心數(shù)據(jù)結(jié)構(gòu)是“模型”,模型是一種組織網(wǎng)絡(luò)層的方式。Keras中主要的模型是Sequential模型,Sequential是一系列網(wǎng)絡(luò)層按順序構(gòu)成的棧。你也可以查看函數(shù)式模型來(lái)學(xué)習(xí)建立更復(fù)雜的模型。
Sequential模型如下:
- from keras.models import Sequential
- model = Sequential()
將一些網(wǎng)絡(luò)層通過.add()堆疊起來(lái),就構(gòu)成了一個(gè)模型:
- from keras.layers import Dense, Activation
- model.add(Dense(units=64, input_dim=100))
- model.add(Activation("relu"))
- model.add(Dense(units=10))
- model.add(Activation("softmax"))
完成模型的搭建后,我們需要使用.compile()方法來(lái)編譯模型:
- model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
編譯模型時(shí)必須指明損失函數(shù)和優(yōu)化器,如果你需要的話,也可以自己定制損失函數(shù)。Keras的一個(gè)核心理念就是簡(jiǎn)明易用同時(shí),保證用戶對(duì)Keras的絕對(duì)控制力度,用戶可以根據(jù)自己的需要定制自己的模型、網(wǎng)絡(luò)層,甚至修改源代碼。
- from keras.optimizers import SGD
- model.compile(loss='categorical_crossentropy', optimizer=SGD(lr=0.01, momentum=0.9, nesterov=True))
完成模型編譯后,我們?cè)谟?xùn)練數(shù)據(jù)上按batch進(jìn)行一定次數(shù)的迭代來(lái)訓(xùn)練網(wǎng)絡(luò)
- model.fit(x_train, y_train, epochs=5, batch_size=32)
當(dāng)然,我們也可以手動(dòng)將一個(gè)個(gè)batch的數(shù)據(jù)送入網(wǎng)絡(luò)中訓(xùn)練,這時(shí)候需要使用:model.train_on_batch(x_batch, y_batch)
隨后,我們可以使用一行代碼對(duì)我們的模型進(jìn)行評(píng)估,看看模型的指標(biāo)是否滿足我們的要求:
- loss_and_metrics = model.evaluate(x_test, y_test, batch_size=128)
或者,我們可以使用我們的模型,對(duì)新的數(shù)據(jù)進(jìn)行預(yù)測(cè):
- classes = model.predict(x_test, batch_size=128)
搭建一個(gè)問答系統(tǒng)、圖像分類模型,或神經(jīng)圖靈機(jī)、word2vec詞嵌入器就是這么快。支撐深度學(xué)習(xí)的基本想法本就是簡(jiǎn)單的,現(xiàn)在讓我們把它的實(shí)現(xiàn)也變的簡(jiǎn)單起來(lái)!
代碼體驗(yàn)
- import pandas as pd
- #讀取數(shù)據(jù)
- input_file='./sales_data.xls'
- data=pd.read_excel(input_file,index_col='序號(hào)')
- #將數(shù)據(jù)的類別標(biāo)簽轉(zhuǎn)換為數(shù)據(jù)
- data[data=='好']=1
- data[data=='是']=1
- data[data=='高']=1
- data[data!=1]=0
- x=data.iloc[:,:3].as_matrix().astype(int)#選取訓(xùn)練集,轉(zhuǎn)換為矩陣形式,并且注意類型
- y=data.iloc[:,3].as_matrix().astype(int)
- from keras.models import Sequential
- from keras.layers.core import Dense,Activation
- model=Sequential()#建立模型
- model.add(Dense(input_dim=3,output_dim=10))
- model.add(Activation('relu'))#用relu作為激活函數(shù)
- model.add(Dense(input_dim=10,output_dim=1))
- model.add(Activation('sigmoid'))#輸出分類0或1
- model.compile(loss = 'binary_crossentropy', optimizer = 'adam')
- model.fit(x,y,nb_epoch = 1000, batch_size = 10) #訓(xùn)練模型,學(xué)習(xí)一千次yp=model.predict_classes(x).reshape(len(y)) #分類預(yù)測(cè)
- yp = model.predict_classes(x).reshape(len(y)) #分類預(yù)測(cè)
- import matplotlib.pyplot as plt #導(dǎo)入作圖庫(kù)
- from sklearn.metrics import confusion_matrix #導(dǎo)入混淆矩陣函數(shù)
- def cm_plot(y, yp):
- cm = confusion_matrix(y, yp) #混淆矩陣
- plt.matshow(cm, cmap=plt.cm.Greens) #畫混淆矩陣圖,配色風(fēng)格使用cm.Greens,更多風(fēng)格請(qǐng)參考官網(wǎng)。
- plt.colorbar() #顏色標(biāo)簽
- for x in range(len(cm)): #數(shù)據(jù)標(biāo)簽
- for y in range(len(cm)):
- plt.annotate(cm[x,y], xy=(x, y), horizontalalignment='center', verticalalignment='center')
- plt.ylabel('True label') #坐標(biāo)軸標(biāo)簽
- plt.xlabel('Predicted label') #坐標(biāo)軸標(biāo)簽
- return plt
- cm_plot(y,yp).show() #顯示混淆矩陣可視化結(jié)果
從圖可以看出, 檢測(cè)樣本為34個(gè), 預(yù)測(cè)正確的個(gè)數(shù)為26個(gè), 預(yù)測(cè)準(zhǔn)確率為76.4%, 預(yù)測(cè)準(zhǔn)確率較低, 是由于神經(jīng)網(wǎng)絡(luò)訓(xùn)練時(shí)需要較多樣本, 而這里是由于訓(xùn)練數(shù)據(jù)較少造成的。
需要指出的是, 這里的案例比較簡(jiǎn)單,我們并沒有考慮過擬合的問題。事實(shí)上,神經(jīng)網(wǎng)絡(luò)的擬合能力是很強(qiáng)的,容易出現(xiàn)過擬合現(xiàn)象。跟傳統(tǒng)的添加“懲罰項(xiàng)”的做法不同, 目前神經(jīng)網(wǎng)絡(luò)(尤其是深度神經(jīng)網(wǎng)絡(luò))中流行的防止過擬合的方法是隨機(jī)地讓部分神經(jīng)網(wǎng)絡(luò)節(jié)點(diǎn)休眠,也就是dropout,dropout可參考文章http://mp.weixin.qq.com/s/OB3xBKWHH1lAo-yBdlJVFg。
參考文獻(xiàn):
1、http://blog.csdn.net/han_xiaoyang/article/details/49123419
2、https://www.cnblogs.com/leoo2sk/archive/2010/09/19/decision-tree.html
3、Python數(shù)據(jù)分析與挖掘?qū)崙?zhàn)
4、http://www.coin163.com/it/x7874130266141340969
5、http://keras-cn.readthedocs.io/en/latest/