【關鍵詞】Logistics函數(shù)齿桃,最大似然估計,梯度下降法
1煮盼、Logistics回歸的原理
利用Logistics回歸進行分類的主要思想是:根據現(xiàn)有數(shù)據對分類邊界線建立回歸公式短纵,以此進行分類。這里的“回歸” 一詞源于最佳擬合僵控,表示要找到最佳擬合參數(shù)集香到。
訓練分類器時的做法就是尋找最佳擬合參數(shù),使用的是最優(yōu)化算法。接下來介紹這個二值型輸出分類器的數(shù)學原理
Logistic Regression和Linear Regression的原理是相似的养渴,可以簡單的描述為這樣的過程:
(1)找一個合適的預測函數(shù)雷绢,一般表示為h函數(shù),該函數(shù)就是我們需要找的分類函數(shù)理卑,它用來預測輸入數(shù)據的判斷結果翘紊。這個過程是非常關鍵的,需要對數(shù)據有一定的了解或分析藐唠,知道或者猜測預測函數(shù)的“大概”形式帆疟,比如是線性函數(shù)還是非線性函數(shù)。
(2)構造一個Cost函數(shù)(損失函數(shù))宇立,該函數(shù)表示預測的輸出(h)與訓練數(shù)據類別(y)之間的偏差踪宠,可以是二者之間的差(h-y)或者是其他的形式。綜合考慮所有訓練數(shù)據的“損失”妈嘹,將Cost求和或者求平均柳琢,記為J(θ)函數(shù),表示所有訓練數(shù)據預測值與實際類別的偏差润脸。
(3)顯然柬脸,J(θ)函數(shù)的值越小表示預測函數(shù)越準確(即h函數(shù)越準確),所以這一步需要做的是找到J(θ)函數(shù)的最小值毙驯。找函數(shù)的最小值有不同的方法倒堕,Logistic Regression實現(xiàn)時有梯度下降法(Gradient Descent)。
1) 構造預測函數(shù)
Logistic Regression雖然名字里帶“回歸”爆价,但是它實際上是一種分類方法垦巴,用于兩分類問題(即輸出只有兩種)。首先需要先找到一個預測函數(shù)(h)铭段,顯然骤宣,該函數(shù)的輸出必須是兩類值(分別代表兩個類別),所以利用了Logistic函數(shù)(或稱為Sigmoid函數(shù))稠项,函數(shù)形式為:
該函數(shù)形狀為:
預測函數(shù)可以寫為:
2)構造損失函數(shù)
Cost函數(shù)和J(θ)函數(shù)是基于最大似然估計推導得到的涯雅。
每個樣本屬于其真實標記的概率,即似然函數(shù)展运,可以寫成:
所有樣本都屬于其真實標記的概率為
對數(shù)似然函數(shù)為
最大似然估計就是要求得使l(θ)取最大值時的θ活逆,其實這里可以使用梯度上升法求解,求得的θ就是要求的最佳參數(shù)
3) 梯度下降法求J(θ)的最小值
求J(θ)的最小值可以使用梯度下降法拗胜,根據梯度下降法可得θ的更新過程:
式中為α學習步長蔗候,下面來求偏導:
上式求解過程中用到如下的公式:
因此,θ的更新過程可以寫成:
因為式中α本來為一常量埂软,所以1/m一般將省略锈遥,所以最終的θ更新過程為:
2纫事、實戰(zhàn)
sklearn.linear_model.LogisticRegression(penalty='l2', dual=False, tol=0.0001, C=1.0, fit_intercept=True, intercept_scaling=1, class_weight=None, random_state=None, solver='liblinear', max_iter=100, multi_class='ovr', verbose=0, warm_start=False, n_jobs=1)
solver參數(shù)的選擇:
- “l(fā)iblinear”:小數(shù)量級的數(shù)據集
- “l(fā)bfgs”, “sag” or “newton-cg”:大數(shù)量級的數(shù)據集以及多分類問題
- “sag”:極大的數(shù)據集
邏輯斯提 Logistic
是一個線性回歸模型,處理二分類問題
概率論
對分類邊界建立回歸公式
不能處理回歸問題
1) 手寫數(shù)字數(shù)據集的分類
使用KNN與Logistic回歸兩種方法
from sklearn.datasets import load_digits
digits = load_digits()
digits
train = digits.data
target = digits.target
images = digits.images
import matplotlib.pyplot as plt
%matplotlib inline
plt.imshow(images[0])
plt.imshow(train[0].reshape(8,8))
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(train,target)
導入數(shù)據load_digits()
from sklearn.linear_model import LogisticRegression
創(chuàng)建模型所灸,訓練和預測
logistic = LogisticRegression(C=0.1)
C懲罰系數(shù) 允許誤差的閾值
C越大丽惶,允許的誤差越大
logistic.fit(X_train,y_train)
y_ = logistic.predict(X_test)
logistic.score(X_test,y_test)
展示結果
plt.figure(figsize=(10,16))
for i in range(100):
axes = plt.subplot(10,10,i+1)
data = X_test[i].reshape(8,8)
plt.imshow(data,cmap='gray')
t = y_test[i]
p = y_[i]
title = 'T:'+str(t) + '\nP:'+str(p)
axes.set_title(title)
axes.axis('off')
2) 使用make_blobs產生數(shù)據集進行分類
導包使用datasets.make_blobs創(chuàng)建一系列點
from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier
import numpy as np
import pandas as pd
設置三個中心點,隨機創(chuàng)建100個點
train,target = make_blobs(n_samples=150,n_features=2,centers=[[1,4],[3,2],[5,6]])
plt.scatter(train[:,0],train[:,1],c=target)
創(chuàng)建機器學習模型爬立,訓練數(shù)據
logistic = LogisticRegression()
knnclf = KNeighborsClassifier()
logistic.fit(train,target)
knnclf.fit(train,target)
提取坐標點钾唬,對坐標點進行處理
獲取邊界
xmin,xmax = train[:,0].min()-0.5, train[:,1].max()+0.5
ymin,ymax = train[:,1].min()-0.5, train[:,1].max()+0.5
等差數(shù)列
x = np.linspace(xmin,xmax,200)
y = np.linspace(ymin,ymax,200)
x和y交叉
xx,yy = np.meshgrid(x,y)
X_test = np.c_[xx.ravel(),yy.ravel()]
X_test.shape
預測坐標點數(shù)據,并進行reshape()
%time y1_ = logistic.predict(X_test)
%time y2_ = knnclf.predict(X_test)
繪制圖形
from matplotlib.colors import ListedColormap
colormap = ListedColormap(['#aa00ff','#00aaff','#aaffff'])
def draw_classifier_bounds(X_train,y_train,X_test,y_test):
plt.figure(figsize=(10,8))
axes = plt.subplot(111)
axes.scatter(X_test[:,0],X_test[:,1],c=y_test,cmap=colormap)
axes.scatter(X_train[:,0],X_train[:,1],c=y_train)
draw_classifier_bounds(train,target,X_test,y1_)
draw_classifier_bounds(train,target,X_test,y2_)
3侠驯、作業(yè)
【第1題】預測年收入是否大于50K美元
讀取adult.txt文件抡秆,并使用邏輯斯底回歸算法訓練模型,根據種族吟策、職業(yè)儒士、工作時長來預測一個人的性別
samples = pd.read_csv('../data/adults.txt')
samples.head(2)
train = samples[['race','occupation','hours_per_week']].copy()
target = samples['sex']
train['race'].unique()
race_dic = {
'White':0,
'Black':1,
'Asian-Pac-Islander':2,
'Amer-Indian-Eskimo':3,
'Other':4
}
train['race'] = train['race'].map(race_dic)
unique_arr = train['occupation'].unique()
def transform_occ(x):
return np.argwhere(x == unique_arr)[0,0]
train['occupation'] = train['occupation'].map(transform_occ)
train
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(train,target,test_size=0.2,random_state=1)
logistic = LogisticRegression(C=100)
knnclf = KNeighborsClassifier(n_neighbors=9)
logistic.fit(X_train,y_train)
knnclf.fit(X_train,y_train)
y1_ = logistic.predict(X_test)
y2_ = knnclf.predict(X_test)
print('logistic score is %f'%logistic.score(X_test,y_test))
print('knnclf score is %f'%knnclf.score(X_test,y_test))
由于評分較低,把所有的數(shù)據特征都保留
train = samples.drop('sex',axis=1).copy()
target = samples.sex
train.head(2)
columns = train.columns[train.dtypes == object]
for column in columns:
unique_arr = train[column].unique()
def transform_obj(x):
return np.argwhere(x == unique_arr)[0,0]
train[column] = train[column].map(transform_obj)
train.dtypes
X_train,X_test,y_train,y_test = train_test_split(train,target,test_size=0.2,random_state=1)
logistic = LogisticRegression(C=0.01)
knnclf = KNeighborsClassifier(n_neighbors=5)
logistic.fit(X_train,y_train)
knnclf.fit(X_train,y_train)
y1_ = logistic.predict(X_test)
y2_ = knnclf.predict(X_test)
print('logistic score is %f'%logistic.score(X_test,y_test))
print('knnclf score is %f'%knnclf.score(X_test,y_test))