20200105

一.昨日回顾

	静态成员,必须在类外以 类名::成员名 定义
	静态成员函数(无this)
	const成员函数:this为const指针,仅能调用const成员函数

在这里插入图片描述

二.04作业

1.单例模式

class sp{
    static sp* _sp;
    sp(){};
public:
    int data=0;
    static sp* get_one_sp(){
        if(!_sp)_sp=new sp();
        return _sp;
    } 
};
sp* sp::_sp=nullptr;


int main()
{
    std::cout << "Hello world" << std::endl;
    sp* sp1=sp::get_one_sp();
    sp* sp2=sp::get_one_sp();
    cout<<sp1<<" kaichong "<<sp2<<"   data="<<sp1->data<<endl;
    return 0;
}

2.重温栈/队列/带头节点循环链表

带头结点循环链表比较繁琐:
#include <iostream>
using namespace std;

struct Node
{
    int data=0;
    Node * pre=nullptr;
    Node * next=nullptr;
};

class List
{
    Node * _head;
    Node * _tail;
    int    _size;
    Node * find(Node * p)	//如果存在,就返回该节点;不存在,就返回空指针
    {
        if(!_size){
            cout<<"empty list"<<endl;
            return nullptr;
        }else{
            auto first=_head->next,cur=_head->next;
            while(cur!=p){
                cur=cur->next;
                if(cur==first){
                    cout<<"no matching Node"<<endl;
                    return nullptr; 
                }
            }
            cout<<"data first address="<<cur<<endl;
            return cur;
        }
    }
    Node * insert(Node *p)
        //确定节点存在时,在该节点前一位置直接插入元素
    {
        auto tmp=new Node;
        if(p==_head->next){
            tmp->next=_head->next;
            _head->next=tmp;
            _tail->next=tmp;
            tmp->pre=_tail; 
        }else{
            tmp->pre=p->pre;
            tmp->next=p;
            p->pre->next=tmp;
            p->pre=tmp;
        }
        _size++;
        return tmp;
    }
    void erase(Node *p)			//删除一个指定的节点
    {
        if(_size==1){
            _head->next=nullptr;
            _tail=nullptr;
        }else if(p==_head->next){
            _tail->next=p->next;
            p->next->pre=_tail;
            _head->next=p->next;
        }else if(p==_tail){
            _tail=p->pre;
            _tail->next=p->next;
            p->next->pre=_tail;
        }else{
            p->next->pre=p->pre;
            p->pre->next=p->next;
        }
        delete p;
        _size--;
    }
public:
    List():_head(new Node()),_tail(nullptr),_size(0){}
    ~List(){
        if(_size){
            Node* first=_head->next,*tmp=nullptr;
            while(first!=_tail){
                tmp=first->next;
                delete first;
                first=tmp;
            }
            delete _tail;
        }
    }

    void push_back(int value)//在尾部添加数据
    {
        if(!_tail){
            _head->next=new Node;
            _tail=_head->next;
            _tail->data=value;
            _tail->pre=_tail;
            _tail->next=_tail;
            _size++;
        }else{
            auto tmp=new Node;
            tmp->pre=_tail;
            tmp->next=_head->next;
            tmp->data=value;
            _tail->next=tmp;
            _head->next->pre=tmp;
            _tail=tmp;
            _size++;
        }
    }

    void push_front(int value)//在头部添加数据
    {
        if(!_tail){
            _head->next=new Node;
            _tail=_head->next;
            _tail->data=value;
            _tail->pre=_tail;
            _tail->next=_tail;
            _size++;
        }else{
            auto tmp=new Node;
            tmp->pre=_tail;
            tmp->next=_head->next;
            tmp->data=value;
            _tail->next=tmp;
            _head->next->pre=tmp;
            _head->next=tmp;
            _size++;
        }
    }
    void pop_back()//在尾部删除一个数据
    {
        if(!_size){
            cout<<"empty list"<<endl;
        }else if(_size==1){
            delete _tail;
            _tail=nullptr;
            _head->next=nullptr;
            _size--;
        }else{
            auto tmp=_tail;
            _tail=tmp->pre;
            _head->next->pre=_tail;
            _tail->next=_head->next;
            delete tmp;
            _size--;
        }
    }
    void pop_front()//在头部删除一个数据
    {
        if(!_size){
            cout<<"empty list"<<endl;
        }else if(_size==1){
            delete _tail;
            _tail=nullptr;
            _head->next=nullptr;
            _size--;
        }else{
            auto tmp=_head->next;
            tmp->next->pre=_tail;
            _tail->next=tmp->next;
            _head->next=tmp->next;
            delete tmp;
            _size--;
        }
    }

    void insert(Node *p, int value)//在某个节点之前添加数据, 还需要判断该节点在不在链表之中
    {
        auto tmp=find(p);
        if(!tmp){
            cout<<"insert fail"<<endl;
        }else{
            insert(tmp)->data=value;
        }
    }
    void erase(int data)//需要判断该节点在不在链表之中
    {
        auto tmp=find(data);
        if(!tmp){
            cout<<"insert fail"<<endl;
        }else{
            erase(tmp);
        }
    }
    void display() const//打印链表
    {
        if(!_size){
            cout<<"empty list"<<endl;
            return;
        }else{
            auto first=_head->next,cur=_head->next;
            while(1){
                cout<<cur->data<<endl;
                cur=cur->next;
                if(cur==first){
                    cout<<"end of list"<<endl;
                    break;
                }
            }
            return;
        }
    }
    Node* find(int data){
        if(!_size){
            cout<<"empty list"<<endl;
                    return nullptr;
        }else{
            auto first=_head->next,cur=_head->next;
            while(cur->data!=data){
                cur=cur->next;
                if(cur==first){
                    cout<<"no matching data"<<endl;
                    return nullptr;
                }
            }
            cout<<"data first address="<<cur<<endl;
                    return cur;
        }
    }


};		
int main()
{
    std::cout << "Hello world" << std::endl;
    List l;
    l.push_back(111);
    l.push_back(112);
    l.push_back(113);
    l.push_back(114);
    l.pop_front();
    l.display();
    l.insert(l.find(113),8882);
    l.pop_front();
    l.display();

    return 0;
}

三.机器学习

回顾:正规方程解法与多元梯度下降法均有价值,使用正规方程的变量数量上限经验值为10000个features

在这里插入图片描述

4.7 矩阵不可逆时使用正规方程解法

octave内包含pinv(伪逆函数)与inv,而pinv即使对不可逆矩阵仍能得出正确解
不可逆的原因:
	1.包含多余特征(线性相关)   
	2.包含过多特征(相对于样本数量),如10个样本/100个特征
	需要删除某些特征或正规化

6.1 logistic regression algorithm

一种classification算法,并不是回归问题算法,约等于sigmoid function

在这里插入图片描述

6.3 决策边界

g(z)即为sigmoid function

在这里插入图片描述 决策边界概念:
决策边界概念:
在这里插入图片描述

6.4 选择与拟合cost function中的参数θ

目的:使J(θ)成为一个凹函数(convex),从何可通过梯度下降求极值
通过y不同值时的不同代价函数,使其为凸函数

6.5 简化代价函数与梯度下降

y=0/1两种情况合为一个表达式

在这里插入图片描述

极大似然法得到

在这里插入图片描述

同样的表达式,但属于不同算法,但用于监测梯度下降的方法一样可以应用:迭代次数与J(θ)大小的图像等

在这里插入图片描述

6.6 高级优化

共轭梯度法:不需要指定α,智能内循环:线搜索算法

在这里插入图片描述
在这里插入图片描述

6.7 多元分类/一对多

三元分类问题->三个独立的二元分类问题->每个伪训练集,只有两个类

在这里插入图片描述
选择三个分类器中输出结果概率最高/最可靠的结果作为输出

7.1 正则化:过拟合

虽然高度拟合training set,但有过高方差,泛化差,并非合适的模型

在这里插入图片描述
方法:去除部分变量->减少可能有用的信息
正则化/改变θ量级->保护信息完整性

7.2 正则化:代价函数

使部分θ数量级很小/惩罚部分参数增大带来的效果

在这里插入图片描述

代价函数中添加正则化项使除theta0以外的参数被放缩,正则化参数的选择很重要

在这里插入图片描述

7.4正则化的梯度下降法与正规方程法

对梯度下降法,theta0不变,其余theta参数有所变化

在这里插入图片描述

对正规方程法只要λ>0;则必有矩阵可逆

在这里插入图片描述

7.4 正规方程法及其高级优化方法的正则化

正则化逻辑回归

在这里插入图片描述
在这里插入图片描述

正则化的优化算法/仍需提供代价函数,再次强调octave中theta下标从1开始到n+1

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值