1.4.2 监督学习算法

监督学习算法

监督学习算法是给定一组输入x和输出y的训练集,学习如何关联输入和输出。

概率监督学习(逻辑回归)

线性回归中,能够通过求正规方差来找到最佳权重,相比而言,逻辑回归更困难,其最佳权重没有闭解。反之,我们必须最大化对数似然来搜索最优解,通过梯度下降法最小化负对数似然来搜索。

# _*_ coding: utf-8 _*_
"""
根据两门考试成绩,判断是否通过
steps:
1\ deal with the data
2\ get the hypothesis function
3\ get the cost function
4\ get the gradient of the cost function
5\ calculate the theta with decrece gradient
6\ predict with the theta, caculate the accuracy
7\ plot the boundary line if possiable
"""

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

def dealData():
    data = pd.read_csv('ex2data1.txt', names=['exam1', 'exam2', 'admit'])
    print(data.head())
    if 'Ones' not in data.columns:
        data.insert(0, 'Ones', 1)

    X = data.iloc[:, :-1].as_matrix()
    y = data.iloc[:, -1].as_matrix()

    theta = np.zeros(X.shape[1])
    return X, y, theta, data

def sigmod(z):
    """
    logistic regression hypothesis
    :param z:
    :return:
    """
    return 1 / (1 + np.exp(-z))


def cost(theta, X, y):
    first = (-y * np.log(sigmod(X @ theta)))
    second = (1 - y) * np.log(1 - sigmod(X @ theta))
    return np.mean(first - second)

def gradient(theta, X, y):
    """
    calculate the gradient
    :param theta:
    :param X:
    :param y:
    :return:
    """
    return (X.T @ (sigmod(X @ theta) - y)) / len(X)


# Learning the theta
import scipy.optimize as opt
X, y, theta, data = dealData()
result = opt.fmin_tnc(func=cost, x0=theta, fprime=gradient, args=(X, y))
print(result)

# evaluating logistic regression
def predict(theta, X):
    probability = sigmod(X @ theta)
    return [1 if x >= 0.5 else 0 for x in probability ]

final_theta = result[0]
predictions = predict(final_theta, X)
correct = [1 if a==b else 0 for (a, b) in zip(predictions, y)]
accuracy = sum(correct) / len(correct)
print(accuracy)

from sklearn.metrics import classification_report

print(classification_report(predictions, y))

# Decision boundary, plot the line
# theta0 + x1 * thate1 + x2 * theta2 = 0
x1 = np.arange(130, step=0.1)
x2 = -(final_theta[0] + x1*final_theta[1]) / final_theta[2]

# visaulize the original data
positive = data[data.admit.isin(['1'])]
negetive = data[data.admit.isin(['0'])]
plt.scatter(positive['exam1'], positive['exam2'], c='b', label='admitted')
plt.scatter(negetive['exam1'], negetive['exam2'], c='r', label='Not admitted')
plt.plot(x1, x2)
plt.legend()
plt.xlabel('exam1')
plt.ylabel('exam2')
plt.show()
       exam1      exam2  admit
0  34.623660  78.024693      0
1  30.286711  43.894998      0
2  35.847409  72.902198      0
3  60.182599  86.308552      1
4  79.032736  75.344376      1
(array([-25.16131867,   0.20623159,   0.20147149]), 36, 0)
0.89
             precision    recall  f1-score   support

          0       0.85      0.87      0.86        39
          1       0.92      0.90      0.91        61

avg / total       0.89      0.89      0.89       100

在这里插入图片描述

支持向量机

从逻辑回归到SVM:

h θ ( x ) = 1 1 + e − θ T x h_{\theta}(x) = \frac{1}{1 + e^{-\theta^Tx}} hθ(x)=1+eθTx1

在这里插入图片描述
可以看到,如果想要 y = 1 , h θ ( x ) = 1 , θ T x > > 0 y = 1, h_\theta (x) = 1, \theta^Tx >> 0 y=1,hθ(x)=1θTx>>0

对于单个样本逻辑回归的cost function是 :

c o s t = − ( y log ⁡ h θ ( x ) ) − ( 1 − y ) log ⁡ ( 1 − h θ ( x ) ) = − y log ⁡ 1 1 + e − θ T x − ( 1 − y ) log ⁡ ( 1 − 1 1 + e − θ T x ) cost = -(y\log h_\theta(x))-(1-y)\log(1-h_\theta(x)) = -y\log \frac{1}{1+e^{-\theta^Tx}} - (1-y)\log (1- \frac {1}{1+ e^-\theta^Tx}) cost=(yloghθ(x))(1y)log(1hθ(x))=ylog1+eθTx1(1y)log(11+eθTx1)

这个式子代表这单个样本对整体cost的贡献

考虑两种情况:

在这里插入图片描述
两种情况下分别为 c o s t 1 ( z ) cost_1(z) cost1(z) c o s t 0 ( z ) cost_0(z) cost0(z)

优化目标:

logistic : m i n 1 m ∑ [ ( y ( i ) ( − log ⁡ h θ ( x ( i ) ) ) ) − ( 1 − y ( i ) ) log ⁡ ( 1 − h θ ( x ( i ) ) ) ] + λ 2 m ∑ θ j 2 min \frac{1}{m} \sum[(y^{(i)}(-\log h_\theta(x^{(i)})))-(1-y^{(i)})\log(1-h_\theta(x^{(i)}))] + \frac{\lambda}{2m}\sum\theta_j^2 minm1[(y(i)(loghθ(x(i))))(1y(i))log(1hθ(x(i)))]+2mλθj2

简化为 A + λ B A+\lambda B A+λB

替换后:

SVM : m i n 1 m ∑ [ ( y ( i ) c o s t 1 ( θ T x ( i ) ) − ( 1 − y ( i ) ) c o s t 0 ( θ T x ( i ) ) ] + λ 2 m ∑ θ j 2 min \frac{1}{m} \sum [(y^{(i)}cost_1(\theta^Tx^{(i)}) -(1-y^{(i)})cost_0(\theta^Tx^{(i)})] + \frac{\lambda}{2m}\sum\theta_j^2 minm1[(y(i)cost1(θTx(i))(1y(i))cost0(θTx(i))]+2mλθj2

去掉m

SVM : m i n ∑ [ ( y ( i ) c o s t 1 ( θ T x ( i ) ) − ( 1 − y ( i ) ) c o s t 0 ( θ T x ( i ) ) ] + λ 2 ∑ θ j 2 min \sum[(y^{(i)}cost_1(\theta^Tx^{(i)}) -(1-y^{(i)})cost_0(\theta^Tx^{(i)})] + \frac{\lambda}{2}\sum\theta_j^2 min[(y(i)cost1(θTx(i))(1y(i))cost0(θTx(i))]+2λθj2

简化为CA+B的形式

最终 : m i n C ∑ [ ( y ( i ) c o s t 1 ( θ T x ( i ) ) − ( 1 − y ( i ) ) c o s t 0 ( θ T x ( i ) ) ] + 1 2 ∑ θ j 2 min C \sum [(y^{(i)}cost_1(\theta^Tx^{(i)}) -(1-y^{(i)})cost_0(\theta^Tx^{(i)})] + \frac{1}{2}\sum\theta_j^2 minC[(y(i)cost1(θTx(i))(1y(i))cost0(θTx(i))]+21θj2

核函数

1、高斯hernel(最常用)

在这里插入图片描述

2、多项式kernel

kernel=‘poly’

3、线性kernel

kernel=‘linear’

通过SVM训练的步骤

利用核函数转换特征

我们有数据 ( x ( 1 ) , y ( 1 ) ) , ( x ( 2 ) , y ( 2 ) ) , . . . , ( x ( m ) , y ( m ) ) (x^{(1)}, y^{(1)}), (x^{(2)}, y^{(2)}), ..., (x^{(m)}, y^{(m)}) (x(1),y(1)),(x(2),y(2)),...,(x(m),y(m))

l ( 1 ) = x ( 1 ) , l ( 2 ) = x ( 2 ) , . . . , l ( m ) = x ( m ) l^{(1)}=x^{(1)}, l^{(2)}=x^{(2)}, ...,l^{(m)}=x^{(m)} l(1)=x(1)l(2)=x(2),...,l(m)=x(m)

对于一个样本 ( x ( i ) , y ( i ) ) (x^{(i)}, y^{(i)}) (x(i),y(i))使用高斯核,则

特征 x ( i ) x^{(i)} x(i)变成:

f 1 ( i ) = k e r n e l ( x ( i ) , l ( 1 ) ) f^{(i)}_1 = kernel(x^{(i)}, l^{(1)}) f1(i)=kernel(x(i),l(1))

f 2 ( i ) = k e r n e l ( x ( i ) , l ( 2 ) ) f^{(i)}_2 = kernel(x^{(i)}, l^{(2)}) f2(i)=kernel(x(i),l(2))



f m ( i ) = k e r n e l ( x ( i ) , l ( m ) ) f^{(i)}_m = kernel(x^{(i)}, l^{(m)}) fm(i)=kernel(x(i),l(m))

f ( i ) = [ f 1 ( i ) , f 2 ( i ) , . . . , f m ( i ) ] T f^{(i)} = [f^{(i)}_1, f^{(i)}_2, ..., f^{(i)}_m]^T f(i)=[f1(i),f2(i),...,fm(i)]T

那么训练数据变成 ( f ( i ) , y ( i ) ) (f^{(i)}, y^{(i)}) (f(i),y(i))

训练

m i n C ∑ [ ( y ( i ) c o s t 1 ( θ T f ( i ) ) − ( 1 − y ( i ) ) c o s t 0 ( θ T f ( i ) ) ] + 1 2 ∑ θ j 2 min C \sum [(y^{(i)}cost_1(\theta^Tf^{(i)}) -(1-y^{(i)})cost_0(\theta^Tf^{(i)})] + \frac{1}{2}\sum\theta_j^2 minC[(y(i)cost1(θTf(i))(1y(i))cost0(θTf(i))]+21θj2

找到最小值,就找到了支持向量机的参数

# _*_ coding: utf-8 _*_
print(__doc__)
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm, datasets

def make_meshgrid(x, y, h=.02):
    x_min, x_max = x.min() - 1, x.max() + 1
    y_min, y_max = y.min() - 1, y.max() + 1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                         np.arange(y_min, y_max, h))
    return xx, yy


def plot_contours(ax, clf, xx, yy, **params):
    Z = clf.predict(np.c_[xx.ravel(),  yy.ravel()])
    Z = Z.reshape(xx.shape)
    out = ax.contourf(xx, yy, Z, **params)
    return out

iris = datasets.load_iris()
X = iris.data[:, :2]
y = iris.target

C = 1.0 # SVC regularization parameter
models = (svm.SVC(kernel='linear', C=C),
          svm.LinearSVC(C=C),
          svm.SVC(kernel='rbf', gamma=0.7, C=C),  ## 径向基函数 (Radial Basis Function 简称 RBF), 就是某种沿径向对称的标量函数
          svm.SVC(kernel='poly', degree=3, C=C))
models = (clf.fit(X, y) for clf in models)

# title for the plots
titles = ('SVC with linear kernel',
          'LinearSVC (linear kernel)',
          'SVC with RBF kernel',
          'SVC with polynomial (degree 3) kernel')

fig, sub = plt.subplots(2, 2)
X0, X1 = X[:, 0], X[:, 1]
xx, yy = make_meshgrid(X0, X1)

for clf, title, ax in zip(models, titles, sub.flatten()):
    plot_contours(ax, clf, xx, yy, cmap=plt.cm.coolwarm, alpha=0.8)
    ax.scatter(X0, X1, c=y, cmap=plt.cm.coolwarm, s=20, edgecolors='k')
    ax.set_xlim(xx.min(), xx.max())
    ax.set_ylim(yy.min(), yy.max())
    ax.set_xticks(())
    ax.set_yticks(())
    ax.set_title(title)
plt.show()
Automatically created module for IPython interactive environment

在这里插入图片描述

最近邻回归(KNN)

K最近邻是一类可以用于分类或者回归的技术,作为一个非参数学习算法,K-最近邻并不局限于固定的数目参数。我们通常认为K-最近邻算法没有任何参数,而是直接使用训练数据的简单函数。

K最近邻甚至没有训练学习的过程,在测试阶段,我们希望在新的测试数据输入x上产生y,我们需要在训练数据X上找到x的K最近邻,然后返回训练集上对应的y的平均值。

所以我们可以想到K最近邻的一个缺点是它不能学习出哪一个特征比其它更具有识别力。

KNN是通过测量不同特征值之间的距离进行分类。它的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别,其中K通常是不大于20的整数。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。

1)计算测试数据与各个训练数据之间的距离;

2)按照距离的递增关系进行排序;

3)选取距离最小的K个点;

4)确定K个点中各个类别出现的频率;

5)返回前K个点中出现频率最高的类别作为测试数据的预测分类。

# 代码来源机器学习实战
#coding:utf-8

from numpy import *
import operator

##给出训练数据以及对应的类别
def createDataSet():
    group = array([[1.0,2.0],[1.2,0.1],[0.1,1.4],[0.3,3.5]])
    labels = ['A','A','B','B']
    return group,labels

def classify(input,dataSet,label,k):
    dataSize = dataSet.shape[0]
    #计算欧式距离
    diff = tile(input,(dataSize,1)) - dataSet
    sqdiff = diff ** 2
    squareDist = sum(sqdiff,axis = 1)#行向量分别相加,从而得到新的一个行向量
    dist = squareDist ** 0.5
    print(dist)
    
    ##对距离进行排序
    sortedDistIndex = argsort(dist)##argsort()根据元素的值从大到小对元素进行排序,返回下标
    print(sortedDistIndex)

    classCount={}
    for i in range(k):
        voteLabel = label[sortedDistIndex[i]]
        print(voteLabel)
        ###对选取的K个样本所属的类别个数进行统计
        classCount[voteLabel] = classCount.get(voteLabel,0) + 1
    ###选取出现的类别次数最多的类别
    maxCount = 0
    for key,value in classCount.items():
        if value > maxCount:
            maxCount = value
            classes = key

    return classes

from numpy import *
dataSet,labels = createDataSet()
input = array([1.1,0.3])
K = 3
output = classify(input,dataSet,labels,K)
print("测试数据为:",input,"分类结果为:",output)
[1.70293864 0.2236068  1.48660687 3.2984845 ]
[1 2 0 3]
A
B
A
测试数据为: [1.1 0.3] 分类结果为: A

决策树

在学习决策树之前,需要先了解一下信息论,可以参考https://blog.csdn.net/egbert123/article/details/86367259

决策树通过简单的条件学判断,生成一个类似于树状结构,分为叶子节点,中间节点和根节点

_叶子节点_存放实际结果,_中间节点_和_根节点_存放判断准则

使用决策树需要以下步骤:

  1. 收集数据:可以使用任何方法。比如想构建一个相亲系统,我们可以从媒婆那里,或者通过参访相亲对象获取数据。根据他们考虑的因素和最终的选择结果,就可以得到一些供我们利用的数据了。
  2. 准备数据:收集完的数据,我们要进行整理,将这些所有收集的信息按照一定规则整理出来,并排版,方便我们进行后续处理。
  3. 分析数据:可以使用任何方法,决策树构造完成之后,我们可以检查决策树图形是否符合预期。
  4. 训练算法:这个过程也就是构造决策树,同样也可以说是决策树学习,就是构造一个决策树的数据结构。
  5. 测试算法:使用经验树计算错误率。当错误率达到了可接收范围,这个决策树就可以投放使用了。
  6. 使用算法

决策树的生成是一个回归过程,以下情况会导致回归结束

  1. 当前节点包含的所有样本都属于同一个类别,无需划分
  2. 当前属性值为空,或者所有样本所在所有属性上取值相同,无法划分
  3. 当前集合包含样本集合为空
    在这里插入图片描述
使用决策树一共有三种决策方法:ID3, C4.5和CART
ID3

ID3算法是根据信息增益来决定当前节点应该用什么特征构建决策树,用计算出来的信息增益最高的特征建立当前节点。

在这里插入图片描述
例如,规定分类income >= 100, 身高 >=180

在这里插入图片描述
信息熵: i n f o ( D ) = − 1 7 l o g 1 7 − 6 7 l o g 6 7 = 0.5917 info(D) = -\frac{1}{7}log\frac{1}{7} - \frac{6}{7}log\frac{6}{7} = 0.5917 info(D)=71log7176log76=0.5917 (七个里面1个愿意的)

根据income划分: i n f o i n c o m e ( D ) = 3 7 ( − 1 3 l o g 1 3 − 1 3 l o g 1 3 ) + 4 7 ( − 0 4 l o g 0 4 − 4 4 l o g 4 4 ) = 0.3935 info_{income}(D) = \frac{3}{7}(-\frac{1}{3}log\frac{1}{3} - \frac{1}{3}log\frac{1}{3}) + \frac{4}{7}(-\frac{0}{4}log\frac{0}{4} - \frac{4}{4}log\frac{4}{4}) = 0.3935 infoincome(D)=73(31log3131log31)+74(40log4044log44)=0.3935

信息增益为: G a i n i n c o m e = 0.5917 − 0.3935 = 0.1982 Gain_{income} = 0.5917 - 0.3935 = 0.1982 Gainincome=0.59170.3935=0.1982

同理可以得到 G a i n h e i g h t = 0.076 Gain_{height} = 0.076 Gainheight=0.076, G a i n l o o k s = 0.076 Gain_{looks} = 0.076 Gainlooks=0.076

所以income在属性中具有最高的信息增益,所以被选为分裂属性。

C4.5

选择具有最大增益率的属性作为分裂属性

依然采用上面的例子:

S p l i t I n f o i n c o m e ( D ) = − 3 7 l o g 3 7 − 4 7 l o g 4 7 = 0.9852 SplitInfo_{income}(D) = -\frac{3}{7}log\frac{3}{7}-\frac{4}{7}log\frac{4}{7} = 0.9852 SplitInfoincome(D)=73log7374log74=0.9852

G a i n R a t i o ( i n c o m e ) = G a i n i n c o m e S p l i t I n f o i n c o m e ( D ) = 0.1982 GainRatio(income) = \frac{Gain_{income}}{SplitInfo_{income}(D)} = 0.1982 GainRatio(income)=SplitInfoincome(D)Gainincome=0.1982

CART(sklearn采用的算法)

CART分类树算法使用基尼系数来代替信息增益比,基尼系数代表了模型的不纯度,基尼系数越小,则不纯度越低,特征越好。这和信息增益(比)是相反的。

G i n i ( D ) = 1 − ∑ p i 2 Gini(D) = 1 - \sum p_i^2 Gini(D)=1pi2

当为2分类时, G i n i ( p ) = 2 p ( 1 − p ) Gini(p) = 2p(1-p) Gini(p)=2p(1p)

G i n i A ( D ) = ∣ D 1 ∣ ∣ D ∣ G i n i ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ G i n i ( D 2 ) Gini_A(D) = \frac{|D_1|}{|D|}Gini(D_1) + \frac{|D_2|}{|D|}Gini(D_2) GiniA(D)=DD1Gini(D1)+DD2Gini(D2)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值