【头歌】期末复习机器学习(一)

【头歌】期末复习机器学习(一)

绪论

实验1 基本概念

第一关 什么是机器学习

下面哪种方法属于机器学习?

A、在猫狗分类问题中,先将猫与狗的特点总结出来,再告诉机器,如果符合猫的特点,则判定为猫,如果符合狗的特点,则判定为狗。
B、将大量名画的真品与赝品输入计算机,让计算机自己从数据中学习出一个模型用来判断是真品还是赝品。
C、让计算机通过对以往的房价数据进行分析,预测未来房价走势。
D、通过人为编写好代码,符合条件则判定为人脸,否则不是人脸,从而制作出人脸识别系统。

答案:BC

第二关 机器学习的常见术语

1、以下是我们的一份数据集,则 x 32 x_{32} x32表示的是?


A、青绿
B、硬挺
C、清脆
D、浊响

答案:B

第三关 机器学习的主要任务

1、我们现在手头上有大量的猫与狗的图片,我现在想训练出一个模型,能够区别出这张图片是猫还是狗,这是一个什么问题?

A、回归
B、分类
C、聚类

答案:B

2、我们现在手头上有大量的动物的图片,为了方便处理,我们想让同一种动物的图片放到同一个文件夹,这是一个什么问题?

A、聚类
B、回归
C、分类
D、无监督学习

答案:AD

3、在无人驾驶时,希望程序能够根据路况决策汽车的方向盘的旋转角度,那么该任务是?

A、分类
B、回归
C、聚类
D、降维

答案:B

模型评估与选择

实验1 模型评估、选择与验证

第1关:为什么要有训练集与测试集

1、下面正确的是?

A、将手头上所有的数据拿来训练模型,预测结果正确率最高的模型就是我们所要选的模型。
B、将所有数据中的前百分之70拿来训练模型,剩下的百分之30作为测试集,预测结果正确率最高的模型就是我们所要选的模型。
C、将所有数据先随机打乱顺序,一半用来训练模型,一半作为测试集,预测结果正确率最高的模型就是我们所要选的模型。
D、将所有数据先随机打乱顺序,百分之80用来训练模型,剩下的百分之20作为测试集,预测结果正确率最高的模型就是我们所要选的模型。

答案:D
2、训练集与测试集的划分对最终模型的确定有无影响?

A、有
B、无

答案:A

第2关:欠拟合与过拟合

1、请问,图中A与B分别处于什么状态?

A、欠拟合,欠拟合
B、欠拟合,过拟合
C、过拟合,欠拟合
D、过拟合,过拟合
在这里插入图片描述
答案:B
2、如果一个模型在训练集上正确率为99%,测试集上正确率为60%。我们应该怎么做?

A、加入正则化项
B、增加训练样本数量
C、增加模型复杂度
D、减少模型复杂度

答案:ABD

第3关 偏差与方差

1、如果一个模型,它在训练集上正确率为85%,测试集上正确率为80%,则模型是过拟合还是欠拟合?其中,来自于偏差的误差为?来自方差的误差为?

A、欠拟合,5%,5%
B、欠拟合,15%,5%
C、过拟合,15%,15%
D、过拟合,5%,5%

答案:B

第4关 验证集与交叉验证

1、假设,我们现在利用5折交叉验证的方法来确定模型的超参数,一共有4组超参数,我们可以知道,5折交叉验证,每一组超参数将会得到5个子模型的性能评分,假设评分如下,我们应该选择哪组超参数?

A、子模型1:0.8 子模型2:0.7 子模型3:0.8 子模型4:0.6 子模型5:0.5
B、子模型1:0.9 子模型2:0.7 子模型3:0.8 子模型4:0.6 子模型5:0.5
C、子模型1:0.5 子模型2:0.6 子模型3:0.7 子模型4:0.6 子模型5:0.5
D、子模型1:0.8 子模型2:0.8 子模型3:0.8 子模型4:0.8 子模型5:0.6

答案:B
2、下列说法正确的是?

A、相比自助法,在初始数据量较小时交叉验证更常用。
B、自助法对集成学习方法有很大的好处
C、使用交叉验证能够增加模型泛化能力
D、在数据难以划分训练集测试集时,可以使用自助法

答案:BCD

第5关 衡量回归性能的指标

1、下列说法正确的是?

A、相比MSE指标,MAE对噪声数据不敏感
B、RMSE指标值越小越好
C、R-Squared指标值越小越好
D、当我们的模型不犯任何错时,R-Squared值为0
答案:AB

第6关:准确度的陷阱与混淆矩阵
import numpy as np

def confusion_matrix(y_true, y_predict):
    def TN(y_true, y_predict):
        return np.sum((y_true == 0) & (y_predict == 0))
    def FP(y_true, y_predict):
        return np.sum((y_true == 0) & (y_predict == 1))
    def FN(y_true, y_predict):
        return np.sum((y_true == 1) & (y_predict == 0))
    def TP(y_true, y_predict):
        return np.sum((y_true == 1) & (y_predict == 1))
    return np.array([
        [TN(y_true, y_predict), FP(y_true, y_predict)],
        [FN(y_true, y_predict), TP(y_true, y_predict)]
    ])
第7关:精准率与召回率
import numpy as np

def precision_score(y_true, y_predict):
    '''
    计算精准率并返回
    :param y_true: 真实类别,类型为ndarray
    :param y_predict: 预测类别,类型为ndarray
    :return: 精准率,类型为float
    '''
    #********* Begin *********#
    TP = np.sum((y_true == 1) & (y_predict == 1))
    FP = np.sum((y_true == 0) & (y_predict == 1))
    Precision = TP/(TP+FP)
    return Precision
    #********* End *********#

def recall_score(y_true, y_predict):
    '''
    计算召回率并召回
    :param y_true: 真实类别,类型为ndarray
    :param y_predict: 预测类别,类型为ndarray
    :return: 召回率,类型为float
    '''
    #********* Begin *********#
    TP = np.sum((y_true == 1) & (y_predict == 1))
    FN = np.sum((y_true == 1) & (y_predict == 0))
    Recall = TP/(TP+FN)
    return Recall
    #********* End *********#

第8关:F1 Score
import numpy as np

def f1_score(precision, recall):
    '''
    计算f1 score并返回
    :param precision: 模型的精准率,类型为float
    :param recall: 模型的召回率,类型为float
    :return: 模型的f1 score,类型为float
    '''
    #********* Begin *********#
    f1 = (2*precision*recall)/(precision+recall)
    return f1
    #********* End ***********#

第9关:ROC曲线与AUC
import numpy as np

def calAUC(prob, labels):
    '''
    计算AUC并返回
    :param prob: 模型预测样本为Positive的概率列表,类型为ndarray
    :param labels: 样本的真实类别列表,其中1表示Positive,0表示Negtive,类型为ndarray
    :return: AUC,类型为float
    '''
    #********* Begin *********#
    f = list(zip(prob, labels))
    rank = [values2 for values1, values2 in sorted(f, key=lambda x:x[0])]
    rankList = [i+1 for i in range(len(rank)) if rank[i] == 1]
    
    posNum = 0
    negNum = 0
    for i in range(len(labels)):
        if(labels[i] == 1):
            posNum += 1
        else:
            negNum += 1
    auc = (sum(rankList) - (posNum*(posNum+1))/2)/(posNum*negNum)
    return auc
    #********* End *********#


第10关:sklearn中的分类性能指标
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score

def classification_performance(y_true, y_pred, y_prob):
    '''
    返回准确度、精准率、召回率、f1 Score和AUC
    :param y_true:样本的真实类别,类型为`ndarray`
    :param y_pred:模型预测出的类别,类型为`ndarray`
    :param y_prob:模型预测样本为`Positive`的概率,类型为`ndarray`
    :return:
    '''
    #********* Begin *********#
    return accuracy_score(y_true, y_pred), precision_score(y_true, y_pred), recall_score(y_true, y_pred), f1_score(y_true, y_pred,y_prob), roc_auc_score(y_true, y_prob)
    #********* End *********#

实验2 理解机器学习基本概念:从电影评分预测讲起

第1关:统计数据集的基本属性
# -*- coding:utf-8 -*-

def stat_data(train_data):
    """求出用户数和电影数,评分数目, 平均评分, 最大评分, 最小评分
    参数:
        train_data - Pandas的DataFrame对象,有四列'user','movie','rating','timestamp',是训练数据集
    返回值:
        num_user - 整数,用户数
        num_movie - 整数,电影数
        num_rating - 整数,评分数目
        avg_rating - 浮点数,平均评分
        max_rating - 浮点数,最大评分
        min_rating - 浮点数,最小评分
    """
    num_user = 0
    num_movie = 0
    num_rating = 0
    avg_rating = 0
    max_rating = 0
    min_rating = 0
    # 请在此添加实现代码
    #********** Begin *********#        
    num_user = train_data['user'].nunique()
    num_movie = train_data['movie'].nunique()
    num_rating = train_data['rating'].size
    avg_rating = train_data['rating'].mean()
    max_rating = train_data['rating'].max()
    min_rating = train_data['rating'].min()
    #**********  End  *********#
    return num_user, num_movie, num_rating, avg_rating, max_rating, min_rating 
第2关:进一步探索数据集
# -*- coding:utf-8 -*-

def avg_rating_of_users_movies(data):
    """求出每个用户的平均评分
    参数:
        data - Pandas的DataFrame对象,有四列'user','movie','rating','timestamp',是训练数据集
    返回值:
        user2avg_r - Pandas的DataFrame对象,有一列'rating'
        movie2avg_r - Pandas的DataFrame对象,有一列'rating'
    """
    user2avg_r = ''
    movie2avg_r = ''
    # 请在此添加实现代码
    #********** Begin *********#        
    user2avg_r = data.groupby('user')['rating'].mean().reset_index(name='rating')
    movie2avg_r = data.groupby('movie')['rating'].mean().reset_index(name='rating')
    #**********  End  *********#    
    return user2avg_r, movie2avg_r
    
def top_10_user_movie_on_avg_rating(user2avg_r, movie2avg_r):    
    """求出平均评分最高的10个用户和10个电影
    参数:
        user2avg_r - Pandas的DataFrame对象,有一列'rating'
        movie2avg_r - Pandas的DataFrame对象,有一列'rating'
    返回值:
        top10_users - 整数列表,用户ID数组,比如[3,4,5,6]代表前4个用户账户是3,4,5,6
        top10_movies - 整数列表,电影ID数组,比如[30,40,50,60]代表前4个电影编号是3,4,5,6
    """
    top10_users = []
    top10_movies = []
    # 请在此添加实现代码
    #********** Begin *********#        
    top10_users = user2avg_r.sort_values(by='rating',ascending=False).head(10)['user'].tolist()
    top10_movies = movie2avg_r.sort_values(by='rating',ascending=False).head(10)['movie'].tolist()
    #**********  End  *********#
    return top10_users, top10_movies
第3关:实现基础预测评分算法
def learn(train_data, N, M):
    """从训练数据中学习得到模型
    参数:
        train_data - Pandas的DataFrame对象,有四列'user','movie','rating','timestamp',是训练数据集
        N - 整数,用户数目
        M - 整数,电影数目        
    返回值:
        g - 数据集中的平均每用户每电影评分值参数
        alpha - 浮点数组,用户评分偏差参数数组,举例alpha[9]表示用户9的评分偏差
        beta - 浮点数组,电影评分偏差参数数组,举例beta[90]表示电影90的评分偏差
    """        
    # 导入Step2的模块
    from stat_rating import avg_rating_of_users_movies
    import numpy as np    
    
    # 模型参数
    g = 0  # 模型参数:所有用户所有电影的平均评分
    alpha = np.zeros(N)  # 模型参数:每个用户的评分偏好
    beta = np.zeros(M)  # 模型参数:每个电影的评分偏好
    
    # 计算平均每用户每电影评分值参数g
    g = np.mean(train_data['rating'])
    
    # 计算用户评分偏差参数alpha
    for i in range(N):
        user_ratings = train_data[train_data['user'] == i]['rating']

        # 检查该用户是否有评分数据
        if len(user_ratings) == 0:
            alpha[i] = 0 - g;
        else:
            alpha[i] = np.mean(user_ratings) - g
    
    # 计算电影评分偏差参数beta
    for j in range(M):
        movie_ratings = train_data[train_data['movie'] == j]['rating']

        # 检查该电影是否有评分数据
        if len(movie_ratings) == 0:
            beta[j] = 0 - g;
        else:
            beta[j] = np.mean(movie_ratings) - g
    
    return g, alpha, beta

第4关:应用模型做预测
def predict(g, alpha, beta, test_data):
    """预测用户对电影的评分
    参数:
        g - 浮点数,模型参数平均电影评分参数
        alpha - 浮点数组,用户评分偏差参数数组
        beta - 浮点数组,电影评分偏差参数数组
        test_data - Pandas的DataFrame对象,有两列'user','movie',是测试数据集
    返回值:
        ret - 浮点数数组,预测的评分数组,每个值对应test_data中的每一行的评分值
    """
    ret = []
    N = len(alpha)
    M = len(beta)

    # 预测每条测试数据的评分
    for index, row in test_data.iterrows():
        user = row['user']
        movie = row['movie']

        # 防止索引超出范围
        if user >= N or movie >= M:
            ret.append(g)
        else:
            # 预测评分公式:预测评分 = 模型参数g + 用户评分偏差alpha + 电影评分偏差beta
            prediction = g + alpha[user] + beta[movie]
            ret.append(prediction)

    return ret

第5关:评估机器学习模型
import numpy as np

def RMSE(predicted_rating, true_rating):
    """计算RMSE值
    参数:
        predicted_rating - list,预测的评分
        true_rating - list,真实的评分
    返回值:
        rmse - 浮点数,RMSE值
    """
    rmse = 0
    
    # 将列表转换为numpy数组
    predicted_rating = np.array(predicted_rating)
    true_rating = np.array(true_rating)
    
    # 计算平方差和
    squared_error = np.square(predicted_rating - true_rating).sum()
    
    # 计算均方根误差
    mean_squared_error = squared_error / len(predicted_rating)
    rmse = np.sqrt(mean_squared_error)
    
    return rmse

第6关:基于梯度下降法的模型参数估计
# -*- coding:utf-8 -*-

def gradient(u, m, r, g, alpha, beta):
    """求出用户权重的梯度
    参数:
        u - 整数,用户ID
        m - 整数,电影ID
        r - 整数,实际评分
        g - 浮点数,平均评分参数
        alpha - 浮点数组,用户评分偏差参数数组
        beta - 浮点数组,电影评分偏差参数数组
    返回值:
        grad_alpha - 浮点数,用户梯度值,举例grad_alpha[9]表示用户9的评分偏差梯度
        grad_beta - 浮点数,电影梯度值,举例grad_beta[90]表示电影90的评分偏差梯度
    """
    grad_alpha = 0
    grad_beta = 0
    # 请在此添加实现代码
    #********** Begin *********#        
     # 获取用户u对电影m的预测评分
    predict_rating = g + alpha[u] + beta[m]
    
    # 计算梯度
    grad_alpha = -2 * (r - predict_rating)
    grad_beta = -2 * (r - predict_rating)
    #**********  End  *********#
    
    return grad_alpha, grad_beta
    
def learn(train_data, N, M, steps, tao, g):
    """学习模型
    参数:
        train_data - Pandas的DataFrame对象,有四列'user','movie','rating','timestamp',是训练数据集        
        N - 整数,用户数目
        M - 整数,电影数目
        steps - 整数,迭代次数
        tao - 浮点数,学习速率
        g - 浮点数,平均电影评分
    返回值:
        alpha - 浮点数组,用户评分偏差参数数组,举例alpha[9]表示用户9的评分偏差
        beta - 浮点数组,电影评分偏差参数数组,举例beta[90]表示电影90的评分偏差
    """
    import numpy as np

    #以正态分布初始化模型参数bu和bi
    alpha = np.zeros(N)+0.01
    beta = np.zeros(M)+0.01
    
    #迭代循环
    for step in range(steps):
        for row in train_data.itertuples():
            u = row.user
            m = row.movie
            r = row.rating
            # 请在此添加实现代码
            #********** Begin *********#        
            # 计算梯度
            grad_alpha, grad_beta = gradient(u, m, r, g, alpha, beta)
            
            # 更新参数
            alpha[u] -= tao * grad_alpha
            beta[m] -= tao * grad_beta
            #**********  End  *********#
            
    return alpha, beta

线性模型

实验1 回归的概念与类型

1、以下哪种方法为无监督类型机器学习方法?

A、回归
B、分类
C、聚类

答案: C
2、以下哪些为连续型变量?

A、温度
B、身高
C、房价
D、国籍

答案: ABC
3、以下哪些模型适用于回归的任务?

A、简单回归模型
B、多项式回归模型
C、多元线性回归模型
D、逻辑回归模型

答案: ABC
4、以下哪个统计指标能反映机器学习结果的自身不稳定性?

A、偏差
B、方差
C、平方差

答案: B
5、在多项式回归中,随着多项式的最大指数p增加,训练得到的回归模型表现会是下面怎样的情形?

A、在训练集合上偏差大
B、在训练集合上偏差小
C、在测试集合上方差大
D、在测试集合上方差小

答案: BC
6、以下哪种回归模型可以有效利用特征之间的交互?

A、线性回归模型
B、多项式回归模型
C、神经网络回归模型

答案: C

实验2 线性回归

第1关:简单线性回归与多元线性回归

下面属于多元线性回归的是?

A、求得正方形面积与对角线之间的关系。
B、建立股票价格与成交量、换手率等因素之间的线性关系。
C、建立西瓜价格与西瓜大小、西瓜产地、甜度等因素之间的线性关系。
D、建立西瓜书销量与时间之间的线性关系。

答案: BC
2、若线性回归方程得到多个解,下面哪些方法能够解决此问题?

A、获取更多的训练样本
B、选取样本有效的特征,使样本数量大于特征数
C、加入正则化项
D、不考虑偏置项b

答案: ABC
3、下列关于线性回归分析中的残差(预测值减去真实值)说法正确的是?

A、残差均值总是为零
B、残差均值总是小于零
C、残差均值总是大于零
D、以上说法都不对

答案: A

第2关:线性回归的正规方程解
#encoding=utf8 
import numpy as np
def mse_score(y_predict,y_test):
    '''
    input:y_predict(ndarray):预测值
          y_test(ndarray):真实值
    ouput:mse(float):mse损失函数值
    '''
    #********* Begin *********#
    mse = np.mean((y_predict-y_test)**2)
    #********* End *********#
    return mse
class LinearRegression :
    def __init__(self):
        '''初始化线性回归模型'''
        self.theta = None
    def fit_normal(self,train_data,train_label):
        '''
        input:train_data(ndarray):训练样本
              train_label(ndarray):训练标签
        '''
        #********* Begin *********#
        x=np.hstack([np.ones((len(train_data),1)),train_data])
        self.theta=np.linalg.inv(x.T.dot(x)).dot(x.T).dot(train_label)
        #********* End *********#
        return self.theta
    def predict(self,test_data):
        '''
        input:test_data(ndarray):测试样本
        '''
        #********* Begin *********#
        x=np.hstack([np.ones((len(test_data),1)),test_data])
        return x.dot(self.theta)
        #********* End *********#
第3关:衡量线性回归的性能指标
#encoding=utf8 
import numpy as np
#mse
def mse_score(y_predict,y_test):
    mse = np.mean((y_predict-y_test)**2)
    return mse
#r2
def r2_score(y_predict,y_test):
    '''
    input:y_predict(ndarray):预测值
          y_test(ndarray):真实值
    output:r2(float):r2值
    '''
    #********* Begin *********#
    from sklearn.metrics import r2_score
    r2 = r2_score(y_test,y_predict)
    #y_mean=np.mean(y_test)
    #r2 = 1-(sum(y_predict-y_test)**2)/(sum(y_mean-y_test)**2)
    #********* End *********#
    return r2
class LinearRegression :
    def __init__(self):
        '''初始化线性回归模型'''
        self.theta = None
    def fit_normal(self,train_data,train_label):
        '''
        input:train_data(ndarray):训练样本
              train_label(ndarray):训练标签
        '''
        #********* Begin *********#
        x=np.hstack([np.ones((len(train_data),1)),train_data])
        self.theta=np.linalg.inv(x.T.dot(x)).dot(x.T).dot(train_label)
        #********* End *********#
        return self.theta
    def predict(self,test_data):
        '''
        input:test_data(ndarray):测试样本
        '''
        #********* Begin *********#
        x=np.hstack([np.ones((len(test_data),1)),test_data])
        return x.dot(self.theta)
        #********* End *********#

第4关:scikit-learn线性回归实践 - 波斯顿房价预测
#encoding=utf8
#********* Begin *********#
import pandas as pd
from sklearn.linear_model import LinearRegression
#获取训练数据
train_data = pd.read_csv('./step3/train_data.csv')
#获取训练标签
train_label = pd.read_csv('./step3/train_label.csv')
train_label = train_label['target']
#获取测试数据
test_data = pd.read_csv('./step3/test_data.csv')

# 实例化API
estimator = LinearRegression()
# 使用fit方法进行训练
estimator.fit(train_data,train_label)
predict = estimator.predict(test_data)
predict = pd.DataFrame({'result':predict})
predict.to_csv('./step3/result.csv')
#********* End *********#

实验3 分类的概念

第1关:分类之“三顾茅庐”

1、分类问题属于下列哪一类?

A、有监督学习
B、无监督学习
C、弱监督学习
D、远程监督学习

答案:A
2、下列哪些不属于分类问题的典型应用?

A、识别邮箱收件是否为垃圾文件
B、智能音箱控制家电
C、根据症状与检查结果自动诊断疾病
D、购物网站为顾客推荐“猜你喜欢”

答案:BD
3、分类问题需要预测的变量为离散整数值或者连续实数均可。

A、正确
B、错误

答案:B

第2关:分类之“华山论剑”

1、根据输出结果形式,分类器可分为概率和非概率分类器。

A、正确
B、错误

答案:A
2、下列哪些属于非概率分类器?

A、贝叶斯分类
B、逻辑回归分类
C、k近邻
D、支持向量机

答案:CD
3、手写数字识别应该采用何种方法?

A、概率分类器
B、非概率分类器
C、这不是分类问题,无需分类器

答案:B

实验4 逻辑回归

第1关:逻辑回归核心思想
#encoding=utf8
import numpy as np

def sigmoid(t):
    '''
    完成sigmoid函数计算
    :param t: 负无穷到正无穷的实数
    :return: 转换后的概率值
    :可以考虑使用np.exp()函数
    '''
    #********** Begin **********#
    y=1/(1+np.exp(-t))
    return y
    #********** End **********#
第2关:逻辑回归的损失函数

1、逻辑回归的损失函数可以写成如下形式
在这里插入图片描述
A、对
B、错

答案:A
2、下列说法正确的是

A、损失值能够衡量模型在训练数据集上的拟合程度
B、sigmoid函数不可导
C、sigmoid函数的输入越大,输出就越大
D、训练的过程,就是寻找合适的参数使得损失函数值最小的过程

答案:ACD
3、sigmoid函数(对数几率函数)相对于单位阶跃函数有哪些好处?

A、sigmoid函数可微分
B、sigmoid函数处处连续
C、sigmoid函数不是单调的
D、sigmoid函数最多计算二阶导

答案:AB
4、逻辑回归的优点有哪些?
A、需要事先对数据的分布做假设
B、可以得到“类别”的真正的概率预测
C、可以用闭式解求解
D、可以用现有的数值优化算法求解

答案:D

第3关:梯度下降
# -*- coding: utf-8 -*-

import numpy as np
import warnings
warnings.filterwarnings("ignore")

def gradient_descent(initial_theta,eta=0.05,n_iters=1000,epslion=1e-8):
    '''
    梯度下降
    :param initial_theta: 参数初始值,类型为float
    :param eta: 学习率,类型为float
    :param n_iters: 训练轮数,类型为int
    :param epslion: 容忍误差范围,类型为float
    :return: 训练后得到的参数
    '''
    #   请在此添加实现代码   #
    #********** Begin *********#
    theta=initial_theta
    i=0
    while i<n_iters:
        gra = 2*(theta-3)
        last_theat = theta
        theta = theta-eta*gra
        if(abs(theta-last_theat)<epslion):
            break
        i=i+1
    return theta
    #********** End **********#

第4关:动手实现逻辑回归 - 癌细胞精准识别
# -*- coding: utf-8 -*-

import numpy as np
import warnings
warnings.filterwarnings("ignore")

def sigmoid(x):
    '''
    sigmoid函数
    :param x: 转换前的输入
    :return: 转换后的概率
    '''
    return 1/(1+np.exp(-x))


def fit(x,y,eta=1e-3,n_iters=10000):
    '''
    训练逻辑回归模型
    :param x: 训练集特征数据,类型为ndarray
    :param y: 训练集标签,类型为ndarray
    :param eta: 学习率,类型为float
    :param n_iters: 训练轮数,类型为int
    :return: 模型参数,类型为ndarray
    '''
    #   请在此添加实现代码   #
    #********** Begin *********#
    theta = np.zeros(x.shape[1])
    i_iter = 0
    while i_iter < n_iters:
        gradient = (sigmoid(x.dot(theta))-y).dot(x)
        theta = theta -eta*gradient
        i_iter += 1
    return theta
    #********** End **********#

第5关:手写数字识别
from sklearn.linear_model import LogisticRegression
from sklearn import datasets
import matplotlib.pyplot as plt
def digit_predict(train_image, train_label, test_image):
    '''
    实现功能:训练模型并输出预测结果
    :param train_sample: 包含多条训练样本的样本集,类型为ndarray,shape为[-1, 8, 8]
    :param train_label: 包含多条训练样本标签的标签集,类型为ndarray
    :param test_sample: 包含多条测试样本的测试集,类型为ndarry
    :return: test_sample对应的预测标签
    '''

    #************* Begin ************#
    flat_train_image = train_image.reshape((-1, 64))
    # 训练集标准化
    train_min = flat_train_image.min()
    train_max = flat_train_image.max()
    flat_train_image = (flat_train_image-train_min)/(train_max-train_min)
    # 测试集变形
    flat_test_image = test_image.reshape((-1, 64))
    # 测试集标准化
    test_min = flat_test_image.min()
    test_max = flat_test_image.max()
    flat_test_image = (flat_test_image - test_min) / (test_max - test_min)

    # 训练--预测
    rf = LogisticRegression(C=4.0)
    rf.fit(flat_train_image, train_label)
    return rf.predict(flat_test_image)
    #************* End **************#

实验5 多分类学习

第1关:OvO多分类策略
import numpy as np

# 逻辑回归
class tiny_logistic_regression(object):
    def __init__(self):
        #W
        self.coef_ = None
        #b
        self.intercept_ = None
        #所有的W和b
        self._theta = None
        #01到标签的映射
        self.label_map = {}


    def _sigmoid(self, x):
        return 1. / (1. + np.exp(-x))


    #训练,train_labels中的值可以为任意数值
    def fit(self, train_datas, train_labels, learning_rate=1e-4, n_iters=1e3):
        #loss
        def J(theta, X_b, y):
            y_hat = self._sigmoid(X_b.dot(theta))
            try:
                return -np.sum(y*np.log(y_hat)+(1-y)*np.log(1-y_hat)) / len(y)
            except:
                return float('inf')

        # 算theta对loss的偏导
        def dJ(theta, X_b, y):
            return X_b.T.dot(self._sigmoid(X_b.dot(theta)) - y) / len(y)

        # 批量梯度下降
        def gradient_descent(X_b, y, initial_theta, leraning_rate, n_iters=1e2, epsilon=1e-6):
            theta = initial_theta
            cur_iter = 0
            while cur_iter < n_iters:
                gradient = dJ(theta, X_b, y)
                last_theta = theta
                theta = theta - leraning_rate * gradient
                if (abs(J(theta, X_b, y) - J(last_theta, X_b, y)) < epsilon):
                    break
                cur_iter += 1
            return theta

        unique_labels = list(set(train_labels))
        labels = np.array(train_labels)

        # 将标签映射成0,1
        self.label_map[0] = unique_labels[0]
        self.label_map[1] = unique_labels[1]

        for i in range(len(train_labels)):
            if train_labels[i] == self.label_map[0]:
                labels[i] = 0
            else:
                labels[i] = 1

        X_b = np.hstack([np.ones((len(train_datas), 1)), train_datas])
        initial_theta = np.zeros(X_b.shape[1])
        self._theta = gradient_descent(X_b, labels, initial_theta, learning_rate, n_iters)

        self.intercept_ = self._theta[0]
        self.coef_ = self._theta[1:]

        return self


    #预测X中每个样本label为1的概率
    def predict_proba(self, X):
        X_b = np.hstack([np.ones((len(X), 1)), X])
        return self._sigmoid(X_b.dot(self._theta))

    #预测
    def predict(self, X):
        proba = self.predict_proba(X)
        result = np.array(proba >= 0.5, dtype='int')
        # 将0,1映射成标签
        for i in range(len(result)):
            if result[i] == 0:
                result[i] = self.label_map[0]
            else:
                result[i] = self.label_map[1]
        return result



class OvO(object):
    def __init__(self):
        # 用于保存训练时各种模型的list
        self.models = []


    def fit(self, train_datas, train_labels):
        '''
        OvO的训练阶段,将模型保存到self.models中
        :param train_datas: 训练集数据,类型为ndarray
        :param train_labels: 训练集标签,标签值为0,1,2之类的整数,类型为ndarray,shape为(-1,)
        :return:None
        '''

        #********* Begin *********#
        unique_labels = list(set(train_labels))
        for i in range(len(unique_labels)):
            for j in range(i+1,len(unique_labels)):
                datas=train_datas[(train_labels == unique_labels[i]) | (train_labels == unique_labels[j])]
                labels = train_labels[(train_labels == unique_labels[i]) |(train_labels == unique_labels[j])]
                lr = tiny_logistic_regression()
                lr.fit(datas,labels)
                self.models.append(lr)
        #********* End *********#


    def predict(self, test_datas):
        '''
        OvO的预测阶段
        :param test_datas:测试集数据,类型为ndarray
        :return:预测结果,类型为ndarray
        '''

        #********* Begin *********#
        def _predict(models, test_data):
            # 变形
            test_data = np.reshape(test_data, (1, -1))
            vote = {}
            # 计票
            for model in models:
                pred = model.predict(test_data)[0]
                if pred not in vote:
                    vote[pred] = 1
                else:
                    vote[pred] += 1
            vote = sorted(vote.items(), key=lambda x: x[1], reverse=True)
            return vote[0][0]
 
        predict = []
        for data in test_datas:
            predict.append(_predict(self.models, data))
        return np.array(predict)
        #********* End *********#





第2关:OvR多分类策略
import numpy as np
# 逻辑回归
class tiny_logistic_regression(object):
    def __init__(self):
        #W
        self.coef_ = None
        #b
        self.intercept_ = None
        #所有的W和b
        self._theta = None
        #01到标签的映射
        self.label_map = {}
    def _sigmoid(self, x):
        return 1. / (1. + np.exp(-x))
    #训练
    def fit(self, train_datas, train_labels, learning_rate=1e-4, n_iters=1e3):
        #loss
        def J(theta, X_b, y):
            y_hat = self._sigmoid(X_b.dot(theta))
            try:
                return -np.sum(y*np.log(y_hat)+(1-y)*np.log(1-y_hat)) / len(y)
            except:
                return float('inf')
        # 算theta对loss的偏导
        def dJ(theta, X_b, y):
            return X_b.T.dot(self._sigmoid(X_b.dot(theta)) - y) / len(y)
        # 批量梯度下降
        def gradient_descent(X_b, y, initial_theta, leraning_rate, n_iters=1e2, epsilon=1e-6):
            theta = initial_theta
            cur_iter = 0
            while cur_iter < n_iters:
                gradient = dJ(theta, X_b, y)
                last_theta = theta
                theta = theta - leraning_rate * gradient
                if (abs(J(theta, X_b, y) - J(last_theta, X_b, y)) < epsilon):
                    break
                cur_iter += 1
            return theta
        X_b = np.hstack([np.ones((len(train_datas), 1)), train_datas])
        initial_theta = np.zeros(X_b.shape[1])
        self._theta = gradient_descent(X_b, train_labels, initial_theta, learning_rate, n_iters)
        self.intercept_ = self._theta[0]
        self.coef_ = self._theta[1:]
        return self
    #预测X中每个样本label为1的概率
    def predict_proba(self, X):
        X_b = np.hstack([np.ones((len(X), 1)), X])
        return self._sigmoid(X_b.dot(self._theta))
    #预测
    def predict(self, X):
        proba = self.predict_proba(X)
        result = np.array(proba >= 0.5, dtype='int')
        return result
class OvR(object):
    def __init__(self):
        # 用于保存训练时各种模型的list
        self.models = []
        # 用于保存models中对应的正例的真实标签
        # 例如第1个模型的正例是2,则real_label[0]=2
        self.real_label = []
    def fit(self, train_datas, train_labels):
        '''
        OvO的训练阶段,将模型保存到self.models中
        :param train_datas: 训练集数据,类型为ndarray
        :param train_labels: 训练集标签,类型为ndarray,shape为(-1,)
        :return: None
        '''
        # 获取所有不同的类别标签
        unique_labels = np.unique(train_labels)

        for label in unique_labels:
            # 创建一个新的二元分类器
            binary_classifier = tiny_logistic_regression()
            
            # 将当前类别作为正例,其余类别作为负例
            binary_train_labels = (train_labels == label).astype(int)
            
            # 训练二元分类器
            binary_classifier.fit(train_datas, binary_train_labels)
            
            # 保存训练好的模型和对应的真实标签
            self.models.append(binary_classifier)
            self.real_label.append(label)

    def predict(self, test_datas):
        '''
        OvR的预测阶段
        :param test_datas:测试集数据,类型为ndarray
        :return:预测结果,类型为ndarray
        '''
        # 存储每个类别的预测概率
        class_probabilities = []

        for model in self.models:
            # 对每个二元分类器进行预测
            class_probabilities.append(model.predict_proba(test_datas))

        # 将概率最高的类别作为预测结果
        predicted_labels = np.array(self.real_label)[np.argmax(class_probabilities, axis=0)]

        return predicted_labels
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值