机器学习方法总结(二)

线性回归模型

1.线性回归

  • 优点:建模速度快、计算量小、系数容易理解和解释。
  • 缺点:模型容易欠拟合、对异常值敏感。
  1. 原理:对给定数据集D={(x_{1},y_{1}),(x_{2},y_{2})......(x_{m},y_{m}))))},其中x_{i}\in (x_{i1}......x_{id}),y_{i}\in R,d为特征维度,m为样本数量,即找到一个线性模型拟合x_{i},y_{i}之间的关系,以最简单的例子:用f(x_{i})=wx_{i}+b拟合yi,找到一个合适的w和b。
  2. 求解策略:最小二乘法即基于均方误差最小化的思想进行求解,使得找到一条直线,样本中所有的点到直线的欧氏距离之和最小。
  3. 求解方法:梯度下降和牛顿法等最优化算法。

2.延伸:对数几率回归

  1. 变回归任务为分类任务,需要找到一个单调可微的函数将分类任务的真实标记y和线性回归的预测值联系起来。如:在每个特征乘上一个回归系数再求和得到w^{T}x+b,然后将回归方程带入sigmoid函数中得到:y=1/(1+e^{-(w^{T}+b)})就可以得到一个二分类的分类模型。
  2. 求解策略:极大似然估计方法得到模型中的参数,公式推导略。
  3. 求解方法同线性回归。
  4. 推广到多分类问题,就是拆解成若干个二分类任务求解。

3.最优化算法

  1. 梯度下降法:梯度下降法的优化思想是用当前位置负梯度方向作为搜索方向,因为该方向为当前位置的最快下降方向,所以也被称为是”最速下降法“,梯度下降法在接近最优解的区域收敛速度明显变慢,所以利用梯度下降法求解需要很多次的迭代。梯度下降算法在每次更新回归系数时都会遍历整个数据集,当数据集小时效果很好,但是数据集太多时时间复杂度就太高了,所以它的优化办法时采用随机梯度下降,每次随机选取一个样本进行随机梯度下降。随机梯度下降也会有缺点:SGD的一个问题是噪音较BGD要多,使得SGD并不是每次迭代都向着整体最优化方向。
  2. 牛顿法:使用函数f(x)的泰勒级数的前面几项来寻找方程(x) = 0的根,牛顿法最大的特点就在于它的收敛速度很快,因为从本质上讲牛顿法是一种利用高阶导数进行收敛的方法,可以看出下一步参数变化的趋势,但是伴随着的计算量也会增加。拟牛顿法我暂时未用到过,所以不谈了。
  3. 启发式优化算法:包括像PSO、EA算法以及一些多目标优化框架,这个不是几句话能说清的,但我刚好有学过这方面知识,所以会在之后单列一章介绍。

4.代码实现

第一部分代码是基于sklearn学习框架实现的,较为简单,也比较实用,将逻辑回归用于实现深度学习中的入门例子:手写数字的识别。

import numpy as np
import tensorflow as tf
#是minist数据集,可以去网上下一下
import input_data
from sklearn.datasets import load_digits
#以one-hot编码读入训练数据
minist=input_data.read_data_sets('//minist//data', one_hot=True)
mnist = fetch_mldata('MNIST original')
#利用read_data_sets下载minist数据集并且分好类
trainimg=minist.train.images
trainlabel=minist.train.labels
testimg=minist.test.images
testlabel=minist.test.lables
print('Minist Loaded')
#tf.palceholder:用于得到传递进来的真实训练样本,占位符
#images_placeholder = tf.placeholder(tf.float32, shape=[batch_size, IMAGE_PIXELS])
#labels_placeholder = tf.placeholder(tf.int32, shape=[batch_size])
x=tf.placeholder("float",[None,784])
y=tf.placeholder("float",[None,10])
#tf.Variable:主要在于一些可训练变量(trainable variables),比如模型的权重(weights,W)或者偏差值(bias)
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
#softmax模型可以用来给不同的对象分配概率,用于多分类
actv=tf.nn.softmax(tf.matmul(x, W) + b)
#cost function,这是对数似然损失函数的均值
cost=tf.reduce_mean(-tf.reduce_sum(y*tf.log(actv),reduction_indices=1))
learning_rate=0.01
#定义一个GradientDescentOptimizer的求解策略和求解目标minimize(cost)为一个tf运算
optm=tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
#预测结果
pred=tf.equl(tf.argmx(actv,1),tf.argmax(y,1))
#精度
accr=tf.reduce_mean(tf.cast(pred,"float"))
init=tf.globle_variables_initializer()
#初始一个session
sess=tf.Session
sess.run(init)
training_epochs=50
batch_size=100
display_step=5
for epoch in range(training_epochs):
    avg_cost=0
    num_bacth=int(minist.train.num_examples/batch_size)
    for i in range(num_batch):
        #划分每次训练的训练batch和测试batch
        batch_xs,batch_ys=minist.train.next_batch(batch_size)
        #运算session,给tf占位变量喂值
        sess.run(optm,feed_dict={x: batch_xs, y: batch_ys})
        feeds={x: batch_xs, y: batch_ys}
        avg_cost +=sess.run(cost,feed_dict=feeds)
        if epoch % display_step == 0:
        feeds_train = {x: batch_xs, y: batch_ys}
        feeds_test = {x: mnist.test.images, y: mnist.test.labels}
        train_acc = sess.run(accr, feed_dict=feeds_train)
        test_acc = sess.run(accr, feed_dict=feeds_test)
        print ("Epoch: %03d/%03d cost: %.9f train_acc: %.3f test_acc: %.3f" 
               % (epoch, training_epochs, avg_cost, train_acc, test_acc))
print ("DONE")

第二部分是脱离库实现的,是机器学习实战中的一个预测病马死亡率的例子。

import numpy as np
import random
def sigmoid(inX):
    return 1.0/(1+exp(-inX))
#定义随机梯度上升法
def stocGradAscent1(dataMatrix, classLabels, numIter=150):
    m,n=shape(dataMatrix)
    weights = oens(n)
    for j in range(numIter):
        dataIndex = range(m)
        for i in range(m):
            alpha = 4/(1.0+i+j)+0.01
            #随机生成下一个实数,它在 [x, y) 范围内。
            randIndex = int(random.uniform(0,len(dataIndex)))
            #改进之一:随机产生一个样本
            h = sigmoid(sum(dataMatrix[randIndex]*weights))
            error = classLabels[randIndex]-h
            #改进之二:权重更新
            weights = weights+alpha*error*dataMatrix[randIndex]
            del(dataIndex[randIndex])
    return weights
def classifyVector(inX,weights):
    prob=sigmoid(sum(inX*weights))
    if prob > 0.5: return 1.0
    else: return 0.0
def colicTest():
    frTrain = open('horseColicTraining.txt')
    frTest = open('hourseColicTest.txt')
    #这里是把训练集分成特征和标签,同时把特征从字符串提取出来转换成列表
    trainingSet=[]
    trainingLabels=[]
    for line in frTrain.readlines():
        #分标签和去两边的空格
        currLine = line.strip().split('\t')
        lineArr=[]
        for i in range (21):
            lineArr.append(float(currLine[i]))
        trainingSet.append(lineArr)
        trainingLabels,append(float(currLine[21]))
        #随机梯度上升法得到最佳权重
        trainWeights = stocGradAscent1(array(trainingSet),trainingLabels,500)
        errorCount=0;numTestVec=0.0
    for line in frTest.readlines():
        numTestVect += 1.0
        currLine = line.strip().split('\t')
        lineArr = []
        for i in range(21):
            lineArr.append(float(currLine[i]))
        #得到测试标签结果
        if int(classifyVector(array(lineArr),trainWeights)) != int(currLine(21)):
            errorCount += 1
    errorRate = (float(errorCount)/numTestVec)
    print('the error rate of this test is: %f' %errorRate)
    return errorRate
#求十次精确度的平均值
def multiTest():
    numTest = 10
    errorSum = 0.0
    for k in range(numTests):
        errorSum += colicTest()
    print('after %d iterations the average error rate is : %f' %(numTest, errorSum/float(numTest)))

猜你喜欢

转载自blog.csdn.net/qq_38593211/article/details/81101883