逻辑斯蒂回归

【关键词】Logistics函数,最大似然估计,梯度下降法

1、Logistics回归的原理

利用Logistics回归进行分类的主要思想是:根据现有数据对分类边界线建立回归公式,以此进行分类。这里的“回归” 一词源于最佳拟合,表示要找到最佳拟合参数集。

训练分类器时的做法就是寻找最佳拟合参数,使用的是最优化算法。接下来介绍这个二值型输出分类器的数学原理

Logistic Regression和Linear Regression的原理是相似的,可以简单的描述为这样的过程:

(1)找一个合适的预测函数,一般表示为h函数,该函数就是我们需要找的分类函数,它用来预测输入数据的判断结果。这个过程是非常关键的,需要对数据有一定的了解或分析,知道或者猜测预测函数的“大概”形式,比如是线性函数还是非线性函数。

(2)构造一个Cost函数(损失函数),该函数表示预测的输出(h)与训练数据类别(y)之间的偏差,可以是二者之间的差(h-y)或者是其他的形式。综合考虑所有训练数据的“损失”,将Cost求和或者求平均,记为J(θ)函数,表示所有训练数据预测值与实际类别的偏差。

(3)显然,J(θ)函数的值越小表示预测函数越准确(即h函数越准确),所以这一步需要做的是找到J(θ)函数的最小值。找函数的最小值有不同的方法,Logistic Regression实现时有梯度下降法(Gradient Descent)。

1) 构造预测函数

Logistic Regression虽然名字里带“回归”,但是它实际上是一种分类方法,用于两分类问题(即输出只有两种)。首先需要先找到一个预测函数(h),显然,该函数的输出必须是两类值(分别代表两个类别),所以利用了Logistic函数(或称为Sigmoid函数),函数形式为:

image.png

该函数形状为:

image.png

预测函数可以写为:

image.png

2)构造损失函数

Cost函数和J(θ)函数是基于最大似然估计推导得到的。

每个样本属于其真实标记的概率,即似然函数,可以写成:

image.png

所有样本都属于其真实标记的概率为

image.png

对数似然函数为

image.png

最大似然估计就是要求得使l(θ)取最大值时的θ,其实这里可以使用梯度上升法求解,求得的θ就是要求的最佳参数

3) 梯度下降法求J(θ)的最小值

求J(θ)的最小值可以使用梯度下降法,根据梯度下降法可得θ的更新过程:

image.png

式中为α学习步长,下面来求偏导:

image.png

上式求解过程中用到如下的公式:

image.png

因此,θ的更新过程可以写成:

image.png

因为式中α本来为一常量,所以1/m一般将省略,所以最终的θ更新过程为:

image.png

2、实战

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参数的选择:

  • “liblinear”:小数量级的数据集
  • “lbfgs”, “sag” or “newton-cg”:大数量级的数据集以及多分类问题
  • “sag”:极大的数据集

逻辑斯提 Logistic

是一个线性回归模型,处理二分类问题

概率论

对分类边界建立回归公式

不能处理回归问题

1) 手写数字数据集的分类

使用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)

导入数据load_digits()

from sklearn.linear_model import LogisticRegression

创建模型,训练和预测

logistic = LogisticRegression(C=0.1)

C惩罚系数 允许误差的阈值

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产生数据集进行分类

导包使用datasets.make_blobs创建一系列点

from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier

import numpy as np
import pandas as pd

设置三个中心点,随机创建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)

创建机器学习模型,训练数据

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

等差数列

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

预测坐标点数据,并进行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、作业

【第1题】预测年收入是否大于50K美元

读取adult.txt文件,并使用逻辑斯底回归算法训练模型,根据种族、职业、工作时长来预测一个人的性别

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))

由于评分较低,把所有的数据特征都保留

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))

你可能感兴趣的:(逻辑斯蒂回归)