机器学习 —— 逻辑回归 简单介绍与使用

一、什么是逻辑斯蒂函数

 

 根据现有数据对分类边界线建立回归公式,依此进行分类

二、逻辑斯蒂回归---->分类

1.利用Logistics回归进行分类的主要思想

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

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

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

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

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

3.站在巨人的肩膀上

 

 举个例子:

假如有一个罐子,里面有黑白两种颜色的球,数目多少不知,两种颜色的比例也不知。我 们想知道罐中白球和黑球的比例,但我们不能把罐中的球全部拿出来数。现在我们可以每次任意从已经摇匀的罐中拿一个球出来,记录球的颜色,然后把拿出来的球 再放回罐中。这个过程可以重复,我们可以用记录的球的颜色来估计罐中黑白球的比例。假如在前面的一百次重复记录中,有七十次是白球,请问罐中白球所占的比例最有可能是多少?很多人马上就有答案了:70%。而其后的理论支撑是什么呢?

我们假设罐中白球的比例是p,那么黑球的比例就是1-p。因为每抽一个球出来,在记录颜色之后,我们把抽出的球放回了罐中并摇匀,所以每次抽出来的球的颜 色服从同一独立分布。这里我们把一次抽出来球的颜色称为一次抽样。题目中在一百次抽样中,七十次是白球的概率是P(Data | M),这里Data是所有的数据,M是所给出的模型,表示每次抽出来的球是白色的概率为p。如果第一抽样的结果记为x1,第二抽样的结果记为x2... 那么Data = (x1,x2,…,x100)。这样,

    P(Data | M)

     = P(x1,x2,…,x100|M)

     = P(x1|M)P(x2|M)…P(x100|M)

     = p^70(1-p)^30.

那么p在取什么值的时候,P(Data |M)的值最大呢?将p^70(1-p)^30对p求导,并其等于零。

    70p^69(1-p)^30-p^70*30(1-p)^29=0。

    解方程可以得到p=0.7。

在边界点p=0,1,P(Data|M)=0。所以当p=0.7时,P(Data|M)的值最大。这和我们常识中按抽样中的比例来计算的结果是一样的。

 

 4.优缺点

(1)实现简单,易于理解和实现;计算代价不高,速度很快,存储资源低

(2)容易欠拟合,分类精度可能不高

三、实战

逻辑斯蒂比较稳定, 使用比较多

导包

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt


# 逻辑回归
from sklearn.linear_model import LogisticRegression

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

使用KNN与Logistic回归两种方法

  • from sklearn.datasets import load_digits
from sklearn.datasets import load_digits


digits = load_digits()

data = digits['data']
target = digits['target']
feature_names = digits['feature_names']
target_names = digits['target_names']
images = digits['images']


data.shape    # (1797, 64)

images.shape   # (1797, 8, 8)

pd.Series(target).unique()  # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

target_names  # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

feature_names
'''
['pixel_0_0',
 'pixel_0_1',
 'pixel_0_2',
 'pixel_0_3',
 'pixel_0_4',
 'pixel_0_5',
 'pixel_0_6',
 'pixel_0_7',
 'pixel_1_0',
 'pixel_1_1',
 'pixel_1_2',
 'pixel_1_3',
 'pixel_1_4',
 'pixel_1_5',
 'pixel_1_6',
 'pixel_1_7',
 'pixel_2_0',
 'pixel_2_1',
 'pixel_2_2',
 'pixel_2_3',
 'pixel_2_4',
 'pixel_2_5',
 'pixel_2_6',
 'pixel_2_7',
 'pixel_3_0',
 'pixel_3_1',
 'pixel_3_2',
 'pixel_3_3',
 'pixel_3_4',
 'pixel_3_5',
 'pixel_3_6',
 'pixel_3_7',
 'pixel_4_0',
 'pixel_4_1',
 'pixel_4_2',
 'pixel_4_3',
 'pixel_4_4',
 'pixel_4_5',
 'pixel_4_6',
 'pixel_4_7',
 'pixel_5_0',
 'pixel_5_1',
 'pixel_5_2',
 'pixel_5_3',
 'pixel_5_4',
 'pixel_5_5',
 'pixel_5_6',
 'pixel_5_7',
 'pixel_6_0',
 'pixel_6_1',
 'pixel_6_2',
 'pixel_6_3',
 'pixel_6_4',
 'pixel_6_5',
 'pixel_6_6',
 'pixel_6_7',
 'pixel_7_0',
 'pixel_7_1',
 'pixel_7_2',
 'pixel_7_3',
 'pixel_7_4',
 'pixel_7_5',
 'pixel_7_6',
 'pixel_7_7']
'''


plt.figure(figsize=(0.3,0.3))
plt.imshow(images[10],cmap='gray')

plt.figure(figsize=(0.3,0.3))
plt.imshow(data[0].reshape(8,8),cmap='gray')

  • 划分数据集
    • from sklearn.model_selection import train_test_split
from sklearn.model_selection import train_test_split


x_train,x_test,y_train,y_test = train_test_split(data,target,test_size=0.2)
x_train.shape,x_test.shape
# ((1437, 64), (360, 64))
  • 使用逻辑回归

创建模型,训练和预测

# 范数
# L1 正则
# L2 正则

# C=1.0 :惩罚系数
#  越大越严格:对训练数据拟合越好,可能造成过拟合(过度拟合训练数据,会造成预测效果不好)
#  越小越不严格:对训练数据拟合没那么好,可能造成欠拟合(对训练数据拟合不好,预测效果也不会好)

# solver : {'newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'},             default='lbfgs'
#   对逻辑回归中损失函数调优的一种算法
# 默认 lbfgs
# liblinear:一般适用于小数据集
# sag、saga:一般适用于大数据集,速度更快
# newton-cg、lbfgs:中等数据集

# max_iter = 100:最大迭代次数

# n_jobs:表示使用处理器的数量,内部进行异步处理,等于 -1 表示全部使用,一般可以给CPU数量或者2倍

lr = LogisticRegression(C=1.0,solver='lbfgs',n_jobs=-1)
lr



# 训练
%timeit lr.fit(x_train,y_train)
# 499 ms ± 8.38 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)


# 预测
%timeit y_pred = lr.predict(x_test)
# 95.9 µs ± 484 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)


# 测试集得分
lr.score(x_test,y_test)
# 0.975


# 训练集模型得分
lr.score(x_train,y_train)
# 1.0

  • 使用KNN

    • 创建模型,训练和预测
    • from sklearn.neighbors import KNeighborsClassifier
from sklearn.neighbors import KNeighborsClassifier


knn = KNeighborsClassifier()


# 训练
%timeit knn.fit(x_train,y_train)
# 266 µs ± 3.05 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)


# 预测
%timeit y_pred = knn.predict(x_test)
# 22.6 ms ± 1.22 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)


# 预测集得分
knn.score(x_test,y_test)
# 0.9888888888888889


# 训练集得分
knn.score(x_train,y_train)
# 0.9902574808629089

  • KNN 训练速度更快
  • LR(逻辑回归)预测速度更快

我们希望预测速度越快越好

2. 使用make_blobs产生数据集进行分类

  • 导包使用datasets.make_blobs创建一系列点
  • from sklearn.datasets import make_blobs
from sklearn.datasets import make_blobs


# make_blobs(
#     n_samples=100,     : 样本数量
#     n_features=2,      :特征数(列数)
#     *,
#     centers=None,      :中心点个数(几堆点)
#     cluster_std=1.0,   :离散程度
#     center_box=(-10.0, 10.0),    :中心点范围
#     shuffle=True,
#     random_state=None,
#     return_centers=False,
# )
data,target = make_blobs(
    n_samples=300,
    centers=6,
    cluster_std=1.0
)

# 画图
plt.scatter(data[:,0],data[:,1],c=target)

设置三个中心点,随机创建100个点

创建机器学习模型(逻辑斯蒂回归),训练数据

lr = LogisticRegression(max_iter=1000)
lr.fit(data,target)

分类后,并绘制边界图(难)

# np.meshgrid()
x = np.array([1,2,3,4])
y = np.array([5,6,7,8,9])
display(x,y)
# array([1, 2, 3, 4])
# array([5, 6, 7, 8, 9])


X,Y = np.meshgrid(x,y)
display(X,Y)
'''
array([[1, 2, 3, 4],
       [1, 2, 3, 4],
       [1, 2, 3, 4],
       [1, 2, 3, 4],
       [1, 2, 3, 4]])
       
array([[5, 5, 5, 5],
       [6, 6, 6, 6],
       [7, 7, 7, 7],
       [8, 8, 8, 8],
       [9, 9, 9, 9]])
'''


# 让 X,Y 相交
display(X.reshape(-1))
display(Y.reshape(-1))
'''
array([1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4])
array([5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9])
'''

# 
np.c_[[1,2,3],[4,5,6]]
'''
array([[1, 4],
       [2, 5],
       [3, 6]])
'''

np.c_[X.reshape(-1),Y.reshape(-1)]
'''
array([[1, 5],
       [2, 5],
       [3, 5],
       [4, 5],
       [1, 6],
       [2, 6],
       [3, 6],
       [4, 6],
       [1, 7],
       [2, 7],
       [3, 7],
       [4, 7],
       [1, 8],
       [2, 8],
       [3, 8],
       [4, 8],
       [1, 9],
       [2, 9],
       [3, 9],
       [4, 9]])
'''




# 将上面图的x轴的坐标等分为多分,y轴也等分为多分
x = np.linspace(data[:,0].min(),data[:,0].max(),1000)
y = np.linspace(data[:,1].min(),data[:,1].max(),1000)

X,Y = np.meshgrid(x,y)

# XY = np.c_[X.reshape(-1),Y.reshape(-1)]
XY = np.c_[X.ravel(),Y.ravel()]   # ravel 扁平化

XY.shape   # (1000000, 2)


XY
'''
array([[ -3.4974961 , -11.94747921],
       [ -3.48150479, -11.94747921],
       [ -3.46551349, -11.94747921],
       ...,
       [ 12.4458366 ,  11.56873078],
       [ 12.4618279 ,  11.56873078],
       [ 12.47781921,  11.56873078]])
'''



# 我们把XY这1000000个点,当作测试数据
# 预测
y_pred = lr.predict(XY)
y_pred.shape    # (1000000,)


y_pred
# array([4, 4, 4, ..., 3, 3, 3])


# plt.scatter(XY[:,0],XY[:,1],c=y_pred)    # 速度慢

# pcolormesh: 画边界图
plt.pcolormesh(X,Y,y_pred.reshape(1000,1000))

plt.scatter(data[:,0],data[:,1],c=target,cmap='rainbow')

lr.score(data,target)
# 0.9866666666666667
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值