根据现有数据对分类边界线建立回归公式,依此进行分类
根据现有数据对分类边界线建立回归公式,以此进行分类。这里的“回归” 一词源于最佳拟合,表示要找到最佳拟合参数集
(1)找一个合适的预测函数,一般表示为h函数,该函数就是我们需要找的分类函数,它用来预测输入数据的判断结果。这个过程是非常关键的,需要对数据有一定的了解或分析,知道或者猜测预测函数的“大概”形式,比如是线性函数还是非线性函数
(2)构造一个Cost函数(损失函数),该函数表示预测的输出(h)与训练数据类别(y)之间的偏差,可以是二者之间的差(h-y)或者是其他的形式。综合考虑所有训练数据的“损失”,将Cost求和或者求平均,记为J(θ)函数,表示所有训练数据预测值与实际类别的偏差
(3)显然,J(θ)函数的值越小表示预测函数越准确(即h函数越准确),所以这一步需要做的是找到J(θ)函数的最小值。找函数的最小值有不同的方法,Logistic Regression实现时有梯度下降法(Gradient Descent)
假如有一个罐子,里面有黑白两种颜色的球,数目多少不知,两种颜色的比例也不知。我 们想知道罐中白球和黑球的比例,但我们不能把罐中的球全部拿出来数。现在我们可以每次任意从已经摇匀的罐中拿一个球出来,记录球的颜色,然后把拿出来的球 再放回罐中。这个过程可以重复,我们可以用记录的球的颜色来估计罐中黑白球的比例。假如在前面的一百次重复记录中,有七十次是白球,请问罐中白球所占的比例最有可能是多少?很多人马上就有答案了: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)的值最大。这和我们常识中按抽样中的比例来计算的结果是一样的。
(1)实现简单,易于理解和实现;计算代价不高,速度很快,存储资源低
(2)容易欠拟合,分类精度可能不高
逻辑斯蒂比较稳定, 使用比较多
导包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 逻辑回归
from sklearn.linear_model import LogisticRegression
使用KNN与Logistic回归两种方法
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
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
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
我们希望预测速度越快越好
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