[機器學習演算法]邏輯回歸
邏輯回歸其實是一種分類演算法,很多人因為名字的原因將其誤以為是回歸演算法,但其本質還是建立在線性回歸的基礎上。
本文主要分為四部分:邏輯回歸的理論推導、自編函數實現邏輯回歸、如何調包實現、邏輯回歸面試常見問題
一、理論推導
該部分主要是學習吳恩達的《機器學習》視頻後所做筆記,以及自己的一些理解
二、自編函數實現
1.將數據集分割為特徵屬性與類別
from numpy import *import matplotlib.pyplot as plt#輸出特徵值矩陣、目標變數def loadDataSet(): dataMat = [] labelMat = [] fr = open(testSet.txt) for line in fr.readlines(): lineArr = line.strip().split() #移除空格並分割 dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #X0設置為1,X1和X2從文件中獲得 labelMat.append(int(lineArr[2])) return dataMat, labelMat #dataMat 100行3列,labelMat 1行列表
2.sigmoid函數(支持向量的運算)
def sigmoid(inX): return 1.0/(1+exp(-inX))
3.梯度上升演算法得到最優的權係數
def gradAscent(dataMatIn, classLabels): dataMatrix = mat(dataMatIn) #轉化為NumPy矩陣類型,100行3列 labelMat = mat(classLabels).transpose() #轉化為NumPy矩陣類型並轉置,100行1列 m, n = shape(dataMatrix) #獲得行數、列數 alpha = 0.001 #設置步長 maxCycles = 500 #迭代步數 weights = ones((n, 1)) #權係數初始化,3行1列 for k in range(maxCycles): h = sigmoid(dataMatrix*weights) #矩陣乘法 error = (labelMat - h) #向量的減法 weights = weights + alpha*dataMatrix.transpose()*error return weights
4.畫分割線與散點圖
def plotBestFit(wei): weights = wei.getA() #將NumPy矩陣轉化為NumPy數組,不然下面根據索引提取會越界 # weights = array(wei) #該方式也可以轉換 dataMat, labelMat = loadDataSet() dataArr = array(dataMat) n = shape(dataArr)[0] xcord1 = [] ycord1 = [] xcord2 = [] ycord2 = [] for i in range(n): #提取屬於1類的數據 if int(labelMat[i]) == 1: xcord1.append(dataArr[i, 1]) ycord1.append(dataArr[i, 2]) #提取屬於0類的數據 else: xcord2.append(dataArr[i, 1]) ycord2.append(dataArr[i, 2]) fig = plt.figure() ax = fig.add_subplot(111) ax.scatter(xcord1, ycord1, s=30, c=red, marker=s) ax.scatter(xcord2, ycord2, s=30, c=green) x = arange(-3.0, 3.0, 0.1) #設置分類線的範圍 y = (-weights[0]-weights[1]*x)/weights[2] #此處x是X1,y是X2, 0=W0*X0+W1*X1+W2*X2 X0=1 ax.plot(x, y) plt.xlabel(X1) plt.ylabel(X2) plt.show()#dataMat, labelMat = loadDataSet()#weights = gradAscent(dataMat, labelMat)#print(weights)#plotBestFit(weights)
以上就已經完成了一般邏輯回歸的流程,但是3中利用梯度上升演算法得到最優的權係數時,涉及到大量矩陣與向量的運算,計算量非常大,所以有了以下的隨機梯度上升演算法。
# #隨機梯度上升演算法(優點:全數值計算,沒有矩陣的轉化過程,全程數組類型)# def stocGradAscent0(dataMatrix, classLabels):# m, n = shape(dataMatrix)# alpha = 0.01# weights = ones(n)# for i in range(m):# h = sigmoid(sum(dataMatrix[i]*weights))# error = classLabels[i] - h# weights = weights + alpha*error*dataMatrix[i]# return weights
三、如何調包實現
1.數據預處理
import pandas as pdimport numpy as np#創建特徵列表(帶目標變數)column_names = [Sample code number, Clump Thickness, Uniformity of Cell Size, Uniformity of Cell Shape, Marginal Adhesion, Single Epithelial Cell Size, Bare Nuclei, Bland Chromatin, Normal Nucleoli, Mitoses, Class]#使用pandas從互聯網讀取數據data = pd.read_csv(https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data, names=column_names)#原數據中缺失部分用?代替,要轉化為標準的缺失值data = data.replace(to_replace=?, value=np.nan)#丟棄有缺失值的行data = data.dropna(how=any)#輸出數據量和維度print(data.shape)
2.將數據隨機分為訓練集和測試集
from sklearn.cross_validation import train_test_split #用於分割數據#25%作為測試集X_train, X_test, y_train, y_test = train_test_split(data[column_names[1:10]], data[column_names[10]], test_size=0.25, random_state=0)#查看訓練樣本的數量和類別分布print(y_train.value_counts())#查看測試樣本的數量和類別分布print(y_test.value_counts())
這裡使用了sklearn.model_selection里的train_test_split函數,用來從樣本中隨機的按比例選取訓練集和測試集,是交叉驗證中常用的函數。
用法為:
X_train,X_test, y_train, y_test = train_test_split(train_data, train_target, test_size=0.4, random_state=0)
其中:
train_data為所要劃分的樣本特徵集,train_target為所要劃分的樣本結果,test_size是樣本佔比,如果是整數的話就是樣本的數量,random_state是隨機數的種子。
所謂隨機數種子,其實就是該組隨機數的編號,在需要重複試驗的時候,保證得到一組一樣的隨機數。
沒有設置隨機數種子:
設置相同的隨機數種子:
設置不同的隨機數種子:
隨機數的產生取決於種子,隨機數和種子之間的關係遵從以下兩個規則:
種子不同,產生不同的隨機數;種子相同,即使實例不同也產生相同的隨機數。
3.使用邏輯回歸模型進行訓練、預測
from sklearn.preprocessing import StandardScaler #用於數據標準化from sklearn.linear_model import LogisticRegression#標準化,使每個維度數據方差為1,均值為0,不會因為特徵值過大過小影響結果ss = StandardScaler()X_train = ss.fit_transform(X_train)X_test = ss.transform(X_test)lr = LogisticRegression()#利用fit函數訓練模型參數lr.fit(X_train, y_train)#利用訓練好的模型對測試集進行預測y_predict = lr.predict(X_test)#分類目標下屬於每個標籤的概率y_predict_pro = lr.predict_proba(X_test)print(y_predict)print(y_predict_pro)
這部分里有一個細節需要注意一下,訓練樣本用fit_transform,而測試樣本用transform,這就需要好好區分fit,transform,fit_transform三個函數:fit用於從一個訓練集中學習模型參數,其中就包括了歸一化時用到的均值,標準偏差;transform就是將fit出的模型參數用於所給數據,實現轉化;而fit_transform就很高效的將模型訓練和轉化合併到一起。
在此處訓練樣本先做fit,得到均值和方差,然後將這些參數用於transform(歸一化訓練數據),使得到的訓練數據是歸一化的,而測試數據只需要在原先得到的均值和方差上做歸一化就行了,所以用transform就行。
4.分析模型的性能
from sklearn.metrics import classification_report#自帶評分函數獲得模型的準確性print(準確率為:, lr.score(X_test, y_test))#獲得精確率、召回率、f1值print(classification_report(y_test, y_predict, target_names=[Benign, Malignant]))
四、面試常見問題
邏輯回歸的常見面試點總結
未經許可,禁止轉載!!!
推薦閱讀:
※《信用風險評分卡研究》中最大似然估計分析表的解讀
※[貝葉斯九]之EM演算法
※為什麼我們需要傳統方法?
※機器學習-決策樹 Decision Tree
※強化學習——環境庫OpenAI Gym