精华内容
下载资源
问答
  • 机器学习算法实践——逻辑回归算法原理模型参数估计算法实践鸢尾花数据集分类实践 算法原理 逻辑斯谛回归模型是由以下条件概率分布表示的分类模型。逻辑斯谛回归模型可以用于二类或多类分类。 P(Y=k∣x)=exp⁡(wk⋅x...

    算法原理

    逻辑斯谛回归模型是由以下条件概率分布表示的分类模型。逻辑斯谛回归模型可以用于二类或多类分类。

    P(Y=kx)=exp(wkx)1+k=1K1exp(wkx),k=1,2,,K1 P(Y=k | x)=\frac{\exp \left(w_{k} \cdot x\right)}{1+\sum_{k=1}^{K-1} \exp \left(w_{k} \cdot x\right)}, \quad k=1,2, \cdots, K-1

    P(Y=Kx)=11+k=1K1exp(wkx) P(Y=K | x)=\frac{1}{1+\sum_{k=1}^{K-1} \exp \left(w_{k} \cdot x\right)}
    这里,xx为输入特征,ww为特征的权值,YY为类别,类别总数为KK

    逻辑斯谛回归模型源自逻辑斯谛分布,其分布函数F(x)F(x)SS形函数。逻辑斯谛回归模型是由输入的线性函数表示的输出的对数几率模型。
    逻辑斯谛函数(也称为Sigmoid函数)形式为
    logi(z)=11+ezlogi (z)=\frac{1}{1+e^{-z}}
    在这里插入图片描述

    模型参数估计

    以二分类模型为例:
    假如逻辑斯蒂模型在学习时,训练数据集为T={(x1,y1),(x2,y2),...,(xN,yN)}T=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\},其中xiRnx_i\in{R^n}, yi{0,1}y_i\in{\{0,1\}}.应用极大似然法估计模型参数,就可以得到逻辑斯蒂回归模型。

    首先在二分类中,P(Y=1x)=exp(wx)1+exp(wx)P(Y=1|x)=\frac{\exp(w\cdot x)}{1+\exp(w\cdot x)} P(Y=0x)=11+exp(wx)P(Y=0|x)=\frac{1}{1+\exp(w\cdot x)}
    P(Y=1x)=π(x)P(Y=1|x)=\pi(x), P(Y=0x)=1π(x)P(Y=0|x)=1-\pi(x)
    似然函数:i=1Nπ(xi)yi[1π(xi)]1yi\prod_{i=1}^{N}\pi(x_i)^{y_i} \cdot [1-\pi(x_i)]^{1-y_i}
    对数似然函数:
    L(w)=log{i=1Nπ(xi)yi[1π(xi)]1yi}=i=1Nyilogπ(xi)+(1yi)log[1π(xi)]=i=1Nyilogπ(xi)1π(xi)+log[1π(xi)]=i=1Nwixilog(1+exp(wxi))L(w) =log\{ \prod_{i=1}^{N}\pi(x_i)^{y_i} \cdot [1-\pi(x_i)]^{1-y_i}\} \\ =\sum_{i=1}^{N}y_i log\pi(x_i)+(1-y_i)log[1-\pi(x_i)] \\ = \sum_{i=1}^{N}y_i log \frac{\pi(x_i)}{1-\pi(x_i)}+log[1-\pi(x_i)] \\ = \sum_{i=1}^{N}w_i \cdot x_i - log(1+ \exp (w \cdot x_i))
    L(w)L(w)求极大值就可以得到模型参数ww的估计值
    逻辑斯蒂回归学习中一般采用梯度下降法以及拟牛顿法。

    算法实践

    我们使用sklearn库中的函数并且将其使用到鸢尾花数据集上来进行分类预测,环境为jupyter notebook
    Step1:库函数导入

    ##  基础函数库
    import numpy as np 
    
    ## 导入画图库
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    ## 导入逻辑回归模型函数
    from sklearn.linear_model import LogisticRegression
    

    Step2:模型训练

    ##Demo演示LogisticRegression分类
    
    ## 构造数据集
    x_fearures = np.array([[-1, -2], [-2, -1], [-3, -2], [1, 3], [2, 1], [3, 2]])
    y_label = np.array([0, 0, 0, 1, 1, 1])
    
    ## 调用逻辑回归模型
    lr_clf = LogisticRegression()
    
    ## 用逻辑回归模型拟合构造的数据集
    lr_clf = lr_clf.fit(x_fearures, y_label) #其拟合方程为 y=w0+w1*x1+w2*x2
    

    Step3:模型参数查看

    ##查看其对应模型的w
    print('the weight of Logistic Regression:',lr_clf.coef_)
    ##查看其对应模型的w0
    print('the intercept(w0) of Logistic Regression:',lr_clf.intercept_)
    
    ## 输出结果
    the weight of Logistic Regression: [[ 0.73462087  0.6947908 ]]
    the intercept(w0) of Logistic Regression: [-0.03643213]
    

    Step4:数据和模型可视化

    ## 可视化构造的数据样本点
    plt.figure()
    plt.scatter(x_fearures[:,0],x_fearures[:,1], c=y_label, s=50, cmap='viridis')
    plt.title('Dataset')
    plt.show()
    

    在这里插入图片描述

    # 可视化决策边界
    plt.figure()
    plt.scatter(x_fearures[:,0],x_fearures[:,1], c=y_label, s=50, cmap='viridis')
    plt.title('Dataset')
    
    nx, ny = 200, 100
    x_min, x_max = plt.xlim()
    y_min, y_max = plt.ylim()
    x_grid, y_grid = np.meshgrid(np.linspace(x_min, x_max, nx),np.linspace(y_min, y_max, ny))
    
    z_proba = lr_clf.predict_proba(np.c_[x_grid.ravel(), y_grid.ravel()])
    z_proba = z_proba[:, 1].reshape(x_grid.shape)
    plt.contour(x_grid, y_grid, z_proba, [0.5], linewidths=2., colors='blue')
    
    plt.show()
    

    在这里插入图片描述

    ### 可视化预测新样本
    
    plt.figure()
    ## new point 1
    x_fearures_new1 = np.array([[0, -1]])
    plt.scatter(x_fearures_new1[:,0],x_fearures_new1[:,1], s=50, cmap='viridis')
    plt.annotate(s='New point 1',xy=(0,-1),xytext=(-2,0),color='blue',arrowprops=dict(arrowstyle='-|>',connectionstyle='arc3',color='red'))
    
    ## new point 2
    x_fearures_new2 = np.array([[1, 2]])
    plt.scatter(x_fearures_new2[:,0],x_fearures_new2[:,1], s=50, cmap='viridis')
    plt.annotate(s='New point 2',xy=(1,2),xytext=(-1.5,2.5),color='red',arrowprops=dict(arrowstyle='-|>',connectionstyle='arc3',color='red'))
    
    ## 训练样本
    plt.scatter(x_fearures[:,0],x_fearures[:,1], c=y_label, s=50, cmap='viridis')
    plt.title('Dataset')
    
    # 可视化决策边界
    plt.contour(x_grid, y_grid, z_proba, [0.5], linewidths=2., colors='blue')
    
    plt.show()
    

    在这里插入图片描述
    Step5:模型预测

    ##在训练集和测试集上分布利用训练好的模型进行预测
    y_label_new1_predict=lr_clf.predict(x_fearures_new1)
    y_label_new2_predict=lr_clf.predict(x_fearures_new2)
    print('The New point 1 predict class:\n',y_label_new1_predict)
    print('The New point 2 predict class:\n',y_label_new2_predict)
    ##由于逻辑回归模型是概率预测模型(前文介绍的p = p(y=1|x,\theta)),所有我们可以利用predict_proba函数预测其概率
    y_label_new1_predict_proba=lr_clf.predict_proba(x_fearures_new1)
    y_label_new2_predict_proba=lr_clf.predict_proba(x_fearures_new2)
    print('The New point 1 predict Probability of each class:\n',y_label_new1_predict_proba)
    print('The New point 2 predict Probability of each class:\n',y_label_new2_predict_proba)
    
    ## 输出
    The New point 1 predict class:
     [0]
    The New point 2 predict class:
     [1]
    The New point 1 predict Probability of each class:
     [[ 0.67507358  0.32492642]]
    The New point 2 predict Probability of each class:
     [[ 0.11029117  0.88970883]]
    

    鸢尾花数据集分类实践

    Step1:函数库导入

    ##  基础函数库
    import numpy as np 
    import pandas as pd
    
    ## 绘图函数库
    import matplotlib.pyplot as plt
    import seaborn as sns
    

    本次我们选择鸢花数据(iris)进行方法的尝试训练,该数据集一共包含5个变量,其中4个特征变量,1个目标分类变量。共有150个样本,目标变量为 花的类别 其都属于鸢尾属下的三个亚属,分别是山鸢尾 (Iris-setosa),变色鸢尾(Iris-versicolor)和维吉尼亚鸢尾(Iris-virginica)。包含的三种鸢尾花的四个特征,分别是花萼长度(cm)、花萼宽度(cm)、花瓣长度(cm)、花瓣宽度(cm),这些形态特征在过去被用来识别物种。

    变量 描述
    sepal length 花萼长度(cm)
    sepal width 花萼宽度(cm)
    petal length 花瓣长度(cm)
    petal width 花瓣宽度(cm)
    target 鸢尾的三个亚属类别,‘setosa’(0), ‘versicolor’(1), ‘virginica’(2)

    Step2:数据读取/载入

    ##我们利用sklearn中自带的iris数据作为数据载入,并利用Pandas转化为DataFrame格式
    from sklearn.datasets import load_iris
    data = load_iris() #得到数据特征
    iris_target = data.target #得到数据对应的标签
    iris_features = pd.DataFrame(data=data.data, columns=data.feature_names) #利用Pandas转化为DataFrame格式
    
    ##利用.info()查看数据的整体信息
    iris_features.info()
    
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 150 entries, 0 to 149
    Data columns (total 4 columns):
    sepal length (cm)    150 non-null float64
    sepal width (cm)     150 non-null float64
    petal length (cm)    150 non-null float64
    petal width (cm)     150 non-null float64
    dtypes: float64(4)
    memory usage: 4.8 KB
    
    ##进行简单的数据查看,我们可以利用.head()头部.tail()尾部
    iris_features.head()
    
    	sepal length (cm)	sepal width (cm)	petal length (cm)	petal width (cm)
    0	5.1	  				3.5					1.4				 	0.2
    1	4.9					3.0					1.4					0.2
    2	4.7					3.2					1.3					0.2
    3	4.6					3.1					1.5					0.2
    4	5.0					3.6					1.4					0.2
    
    ##其对应的类别标签为,其中0,1,2分别代表'setosa','versicolor','virginica'三种不同花的类别
    iris_target
    
    array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
           1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
           2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
           2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
    
    ##利用value_counts函数查看每个类别数量
    
    pd.Series(iris_target).value_counts()
    
    2    50
    1    50
    0    50
    dtype: int64
    
    ##对于特征进行一些统计描述
    
    iris_features.describe()
    
    		sepal length (cm)	sepal width (cm)	petal length (cm)	petal width (cm)
    count	150.000000			150.000000			150.000000			150.000000
    mean	5.843333			3.054000			3.758667			1.198667
    std		0.828066			0.433594			1.764420			0.763161
    min		4.300000			2.000000			1.000000			0.100000
    25%		5.100000			2.800000			1.600000			0.300000
    50%		5.800000			3.000000			4.350000			1.300000
    75%		6.400000			3.300000			5.100000			1.800000
    max		7.900000			4.400000			6.900000			2.500000
    
    ## 合并标签和特征信息
    iris_all = iris_features.copy() ##进行浅拷贝,防止对于原始数据的修改
    iris_all['target'] = iris_target
    
    ## 特征与标签组合的散点可视化
    sns.pairplot(data=iris_all,diag_kind='hist', hue= 'target')
    plt.show()
    

    在这里插入图片描述

    for col in iris_features.columns:
        sns.boxplot(x='target', y=col, saturation=0.5, 
    palette='pastel', data=iris_all)
        plt.title(col)
        plt.show()
    

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

    # 选取其前三个特征绘制三维散点图
    from mpl_toolkits.mplot3d import Axes3D
    
    fig = plt.figure(figsize=(10,8))
    ax = fig.add_subplot(111, projection='3d')
    
    iris_all_class0 = iris_all[iris_all['target']==0].values
    iris_all_class1 = iris_all[iris_all['target']==1].values
    iris_all_class2 = iris_all[iris_all['target']==2].values
    # 'setosa'(0), 'versicolor'(1), 'virginica'(2)
    ax.scatter(iris_all_class0[:,0], iris_all_class0[:,1], iris_all_class0[:,2],label='setosa')
    ax.scatter(iris_all_class1[:,0], iris_all_class1[:,1], iris_all_class1[:,2],label='versicolor')
    ax.scatter(iris_all_class2[:,0], iris_all_class2[:,1], iris_all_class2[:,2],label='virginica')
    plt.legend()
    
    plt.show()
    

    在这里插入图片描述

    ##为了正确评估模型性能,将数据划分为训练集和测试集,并在训练集上训练模型,在测试集上验证模型性能。
    from sklearn.model_selection import train_test_split
    ##选择其类别为0和1的样本(不包括类别为2的样本)
    iris_features_part=iris_features.iloc[:100]
    iris_target_part=iris_target[:100]
    ##测试集大小为20%,80%/20%分
    x_train,x_test,y_train,y_test=train_test_split(iris_features_part,iris_target_part,test_size=0.2,random_state=2020)
    
    ##从sklearn中导入逻辑回归模型
    from sklearn.linear_model import LogisticRegression
    ##定义逻辑回归模型
    clf=LogisticRegression(random_state=0,solver='lbfgs')
    ##在训练集上训练逻辑回归模型
    clf.fit(x_train,y_train)
    
    LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
              intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
              penalty='l2', random_state=0, solver='lbfgs', tol=0.0001,
              verbose=0, warm_start=False)
    
    ##查看其对应的w
    print('the weight of Logistic Regression:',clf.coef_)
    
    ##查看其对应的w0
    print('the intercept(w0) of Logistic Regression:',clf.intercept_)
    
    the weight of Logistic Regression: [[ 0.45244919 -0.81010583  2.14700385  0.90450733]]
    the intercept(w0) of Logistic Regression: [-6.57504448]
    
    ##在训练集和测试集上分布利用训练好的模型进行预测
    train_predict=clf.predict(x_train)
    test_predict=clf.predict(x_test)
    from sklearn import metrics
    ##利用accuracy(准确度)【预测正确的样本数目占总预测样本数目的比例】评估模型效果
    print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_train,train_predict))
    print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_test,test_predict))
    
    ##查看混淆矩阵(预测值和真实值的各类情况统计矩阵)
    confusion_matrix_result=metrics.confusion_matrix(test_predict,y_test)
    print('The confusion matrix result:\n',confusion_matrix_result)
    
    ##利用热力图对于结果进行可视化
    plt.figure(figsize=(8,6))
    sns.heatmap(confusion_matrix_result,annot=True,cmap='Blues')
    plt.xlabel('Predictedlabels')
    plt.ylabel('Truelabels')
    plt.show()
    
    The accuracy of the Logistic Regression is: 1.0
    The accuracy of the Logistic Regression is: 1.0
    The confusion matrix result:
     [[ 9  0]
     [ 0 11]]
    

    在这里插入图片描述

    ##测试集大小为20%,80%/20%分
    x_train,x_test,y_train,y_test=train_test_split(iris_features,iris_target,test_size=0.2,random_state=2020)
    ##定义逻辑回归模型
    clf=LogisticRegression(random_state=0,solver='lbfgs')
    ##在训练集上训练逻辑回归模型
    clf.fit(x_train,y_train)
    ##查看其对应的w
    print('the weight of Logistic Regression:\n',clf.coef_)
    ##查看其对应的w0
    print('the intercept(w0) of Logistic Regression:\n',clf.intercept_)
    ##由于这个是3分类,所有我们这里得到了三个逻辑回归模型的参数,其三个逻辑回归组合起来即可实现三分类
    
    the weight of Logistic Regression:
     [[-0.43538857  0.87888013 -2.19176678 -0.94642091]
     [-0.39434234 -2.6460985   0.76204684 -1.35386989]
     [-0.00806312  0.11304846  2.52974343  2.3509289 ]]
    the intercept(w0) of Logistic Regression:
     [  6.30620875   8.25761672 -16.63629247]
    
    ##在训练集和测试集上分布利用训练好的模型进行预测
    train_predict=clf.predict(x_train)
    test_predict=clf.predict(x_test)
    ##由于逻辑回归模型是概率预测模型(前文介绍的p=p(y=1|x,\theta)),所有我们可以利用predict_proba函数预测其概率
    
    train_predict_proba=clf.predict_proba(x_train)
    test_predict_proba=clf.predict_proba(x_test)
    
    print('The test predict Probability of each class:\n',test_predict_proba)
    ##其中第一列代表预测为0类的概率,第二列代表预测为1类的概率,第三列代表预测为2类的概率。
    
    ##利用accuracy(准确度)【预测正确的样本数目占总预测样本数目的比例】评估模型效果
    print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_train,train_predict))
    print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_test,test_predict))
    
    The test predict Probability of each class:
     [[  1.32525870e-04   2.41745142e-01   7.58122332e-01]
     [  7.02970475e-01   2.97026349e-01   3.17667822e-06]
     [  3.37367886e-02   7.25313901e-01   2.40949311e-01]
     [  5.66207138e-03   6.53245545e-01   3.41092383e-01]
     [  1.06817066e-02   6.72928600e-01   3.16389693e-01]
     [  8.98402870e-04   6.64470713e-01   3.34630884e-01]
     [  4.06382037e-04   3.86192249e-01   6.13401369e-01]
     [  1.26979439e-01   8.69440588e-01   3.57997319e-03]
     [  8.75544317e-01   1.24437252e-01   1.84312617e-05]
     [  9.11209514e-01   8.87814689e-02   9.01671605e-06]
     [  3.86067682e-04   3.06912689e-01   6.92701243e-01]
     [  6.23261939e-03   7.19220636e-01   2.74546745e-01]
     [  8.90760124e-01   1.09235653e-01   4.22292409e-06]
     [  2.32339490e-03   4.47236837e-01   5.50439768e-01]
     [  8.59945211e-04   4.22804376e-01   5.76335679e-01]
     [  9.24814068e-01   7.51814638e-02   4.46852786e-06]
     [  2.01307999e-02   9.35166320e-01   4.47028801e-02]
     [  1.71215635e-02   5.07246971e-01   4.75631465e-01]
     [  1.83964097e-04   3.17849048e-01   6.81966988e-01]
     [  5.69461042e-01   4.30536566e-01   2.39269631e-06]
     [  8.26025475e-01   1.73971556e-01   2.96936737e-06]
     [  3.05327704e-04   5.15880492e-01   4.83814180e-01]
     [  4.69978972e-03   2.90561777e-01   7.04738434e-01]
     [  8.61077168e-01   1.38915993e-01   6.83858427e-06]
     [  6.99887637e-04   2.48614010e-01   7.50686102e-01]
     [  5.33421842e-02   8.31557126e-01   1.15100690e-01]
     [  2.34973018e-02   3.54915328e-01   6.21587370e-01]
     [  1.63311193e-03   3.48301765e-01   6.50065123e-01]
     [  7.72156866e-01   2.27838662e-01   4.47157219e-06]
     [  9.30816593e-01   6.91640361e-02   1.93708074e-05]]
    The accuracy of the Logistic Regression is: 0.958333333333
    The accuracy of the Logistic Regression is: 0.8
    
    
    ##查看混淆矩阵
    confusion_matrix_result=metrics.confusion_matrix(test_predict,y_test)
    print('The confusion matrix result:\n',confusion_matrix_result)
    
    ##利用热力图对于结果进行可视化
    plt.figure(figsize=(8,6))
    sns.heatmap(confusion_matrix_result,annot=True,cmap='Blues')
    plt.xlabel('Predicted labels')
    plt.ylabel('True labels')
    plt.show()
    
    The confusion matrix result:
     [[10  0  0]
     [ 0  7  3]
     [ 0  3  7]]
    ```![在这里插入图片描述](https://img-blog.csdnimg.cn/20200818192036510.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2ODMxODQ1,size_16,color_FFFFFF,t_70#pic_center)
    
    
    展开全文
  • Datawhale八月机器学习-逻辑回归介绍描述原理Demo实践鸢尾花数据集的逻辑回归分类预测数据介绍:代码演示1.导入模块以及数据2.统计数据分析3.数据可视化4.利用逻辑回归模型进行二分类预测5.测试集上查看性能6逻辑...

    介绍

    描述

    1.逻辑回归是分类算法,在线性回归的基础上,施加logistic函数,由理论上取值实数空间,转变成(0,1),针对小于0.5,我们 归为0类,大于0.5归为1类,临界值时可任意归类,变成二分类算法。

    2.逻辑回归基于二分类可以进行多分类预测,对于n个类别的分类任务,我们可以进行两两的二分类任务,就有n(n-1)/2个模型,也有对应的模型参数,最后进行预测时,我们带入n(n-1)/2个模型,产生n(n-1)/2个结果,根据投票决定分类

    logistic函数(sigmord函数,s型曲线):
    在这里插入图片描述

    原理

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

    Demo实践

    1.库函数导入

    ##  基础函数库
    import numpy as np 
    
    ## 导入画图库
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    ## 导入逻辑回归模型函数
    from sklearn.linear_model import LogisticRegression
    

    2.训练模型

    ##Demo演示LogisticRegression分类
    
    ## 构造数据集
    x_fearures = np.array([[-1, -2], [-2, -1], [-3, -2], [1, 3], [2, 1], [3, 2]])
    y_label = np.array([0, 0, 0, 1, 1, 1])
    
    ## 调用逻辑回归模型
    lr_clf = LogisticRegression()
    
    ## 用逻辑回归模型拟合构造的数据集
    lr_clf = lr_clf.fit(x_fearures, y_label) #其拟合方程为 y=w0+w1*x1+w2*x2
    

    3.模型参数查看

    ##查看其对应模型的w
    print('the weight of Logistic Regression:',lr_clf.coef_)
    ##查看其对应模型的w0
    print('the intercept(w0) of Logistic Regression:',lr_clf.intercept_)
    ##the weight of Logistic Regression:[[0.73462087 0.6947908]]
    ##the intercept(w0) of Logistic Regression:[-0.03643213]
    

    4.数据可视化

    ## 可视化构造的数据样本点
    plt.figure()
    plt.scatter(x_fearures[:,0],x_fearures[:,1], c=y_label, s=50, cmap='viridis')
    plt.title('Dataset')
    plt.show()
    

    结果:在这里插入图片描述

    # 可视化决策边界
    plt.figure()
    plt.scatter(x_fearures[:,0],x_fearures[:,1], c=y_label, s=50, cmap='viridis')
    plt.title('Dataset')
    
    nx, ny = 200, 100
    x_min, x_max = plt.xlim()
    y_min, y_max = plt.ylim()
    x_grid, y_grid = np.meshgrid(np.linspace(x_min, x_max, nx),np.linspace(y_min, y_max, ny))
    
    z_proba = lr_clf.predict_proba(np.c_[x_grid.ravel(), y_grid.ravel()])
    z_proba = z_proba[:, 1].reshape(x_grid.shape)
    plt.contour(x_grid, y_grid, z_proba, [0.5], linewidths=2., colors='blue')
    
    plt.show()
    

    结果
    在这里插入图片描述

    ### 可视化预测新样本
    
    plt.figure()
    ## new point 1
    x_fearures_new1 = np.array([[0, -1]])
    plt.scatter(x_fearures_new1[:,0],x_fearures_new1[:,1], s=50, cmap='viridis')
    plt.annotate(s='New point 1',xy=(0,-1),xytext=(-2,0),color='blue',arrowprops=dict(arrowstyle='-|>',connectionstyle='arc3',color='red'))
    
    ## new point 2
    x_fearures_new2 = np.array([[1, 2]])
    plt.scatter(x_fearures_new2[:,0],x_fearures_new2[:,1], s=50, cmap='viridis')
    plt.annotate(s='New point 2',xy=(1,2),xytext=(-1.5,2.5),color='red',arrowprops=dict(arrowstyle='-|>',connectionstyle='arc3',color='red'))
    
    ## 训练样本
    plt.scatter(x_fearures[:,0],x_fearures[:,1], c=y_label, s=50, cmap='viridis')
    plt.title('Dataset')
    
    # 可视化决策边界
    plt.contour(x_grid, y_grid, z_proba, [0.5], linewidths=2., colors='blue')
    
    plt.show()
    

    结果:
    在这里插入图片描述
    5.模型预测

    ##在训练集和测试集上分布利用训练好的模型进行预测
    y_label_new1_predict=lr_clf.predict(x_fearures_new1)
    y_label_new2_predict=lr_clf.predict(x_fearures_new2)
    print('The New point 1 predict class:\n',y_label_new1_predict)
    print('The New point 2 predict class:\n',y_label_new2_predict)
    ##由于逻辑回归模型是概率预测模型(前文介绍的p = p(y=1|x,\theta)),所有我们可以利用predict_proba函数预测其概率
    y_label_new1_predict_proba=lr_clf.predict_proba(x_fearures_new1)
    y_label_new2_predict_proba=lr_clf.predict_proba(x_fearures_new2)
    print('The New point 1 predict Probability of each class:\n',y_label_new1_predict_proba)
    print('The New point 2 predict Probability of each class:\n',y_label_new2_predict_proba)
    ##TheNewpoint1predictclass:
    ##[0]
    ##TheNewpoint2predictclass:
    ##[1]
    ##TheNewpoint1predictProbabilityofeachclass:
    ##[[0.695677240.30432276]]
    ##TheNewpoint2predictProbabilityofeachclass:
    ##[[0.119839360.88016064]]
    

    结果:

    The New point 1 predict class:
    [0]
    The New point 2 predict class:
    [1]
    The New point 1 predict Probability of each class:
    [[0.69567724 0.30432276]]
    The New point 2 predict Probability of each class:
    [[0.11983936 0.88016064]]

    鸢尾花数据集的逻辑回归分类预测

    数据介绍:

    有150个数据集,共分为3类,每类50个样本。每个样本有4个特征。
    每条记录都有 4 项特征:包含4个特征(Sepal.Length(花萼长度)、Sepal.Width(花萼宽度)、Petal.Length(花瓣长度)、>Petal.Width(花瓣宽度)),特征值都为正浮点数,单位为厘米。
    可以通过这4个特征预测鸢尾花卉属于(iris-setosa(山鸢尾), iris-versicolour(杂色鸢尾), iris-virginica(维吉尼亚鸢尾))中>的哪一品种。
    具体参考sklearn中文文档或者自带的小数据集

    代码演示

    1.导入模块以及数据

    #导入库函数
    import numpy as np 
    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    #导入数据集
    from sklearn.datasets import load_iris
    dataset = load_iris()
    print(dataset.data.shape) #(150, 4)
    iris_target = dataset.target #数据标签
    iris_features = pd.DataFrame(data=dataset.data, columns=dataset.feature_names) #利用Pandas转化为DataFrame格式
    
    #查看10条数据
    iris_features.head(10)
    

    结果:
    在这里插入图片描述

    2.统计数据分析

    #数据统计信息
    iris_features.describe()
    

    结果:
    在这里插入图片描述

    3.数据可视化

    ## 合并标签和特征信息
    iris_all = iris_features.copy() ##进行浅拷贝,防止对于原始数据的修改
    iris_all['target'] = iris_target
    ## 特征与标签组合的散点可视化
    sns.pairplot(data=iris_all,diag_kind='hist', hue= 'target')
    plt.show()
    

    结果:
    在这里插入图片描述

    4.利用逻辑回归模型进行二分类预测

    #数据划分
    from sklearn.model_selection import train_test_split
    #二分类任务,选取0和1类的前一百个数据
    iris_features_part=iris_features.iloc[:100]
    iris_target_part=iris_target[:100]
    #测试集大小为20%,80%/20%分
    x_train,x_test,y_train,y_test=train_test_split(iris_features_part,iris_target_part,test_size=0.2,random_state=2020)
    
    #从sklearn中导入逻辑回归模型
    from sklearn.linear_model import LogisticRegression
    #定义逻辑回归模型
    clf=LogisticRegression(random_state=0,solver='lbfgs')
    #在训练集上训练逻辑回归模型
    clf.fit(x_train,y_train)
    #查看其对应的参数w和b(w0)
    print('the weight of Logistic Regression:',clf.coef_)
    print('the intercept(w0) of Logistic Regression:',clf.intercept_)
    

    结果

    the weight of Logistic Regression: [[ 0.45181973 -0.81743611 2.14470304 0.89838607]]
    the intercept(w0) of Logistic Regression: [-6.53367714]

    5.测试集上查看性能

    #在训练集和测试集上分布利用训练好的模型进行预测
    train_predict=clf.predict(x_train)
    test_predict=clf.predict(x_test)
    
    from sklearn import metrics
    #利用accuracy(准确度)【预测正确的样本数目占总预测样本数目的比例】评估模型效果
    print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_train,train_predict))
    print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_test,test_predict))
    
    #查看混淆矩阵(预测值和真实值的各类情况统计矩阵)
    confusion_matrix_result=metrics.confusion_matrix(test_predict,y_test)
    print('The confusion matrix result:\n',confusion_matrix_result)
    
    #利用热力图对于结果进行可视化
    plt.figure(figsize=(8,6))
    sns.heatmap(confusion_matrix_result,annot=True,cmap='Blues')
    plt.xlabel('Predictedlabels')
    plt.ylabel('Truelabels')
    plt.show()
    

    结果
    在这里插入图片描述

    6逻辑回归在整个数据集上进行三分类预测

    #测试集大小为20%,80%/20%分
    x_train,x_test,y_train,y_test=train_test_split(iris_features,iris_target,test_size=0.2,random_state=2020)
    #在训练集上训练逻辑回归模型
    clf.fit(x_train,y_train)
    #查看其对应的w和b
    print('the weight of Logistic Regression:\n',clf.coef_)
    print('the intercept(w0) of Logistic Regression:\n',clf.intercept_)
    #三分类,有三个模型参数,分别是两两进行训练模型是的参数
    

    结果

    the weight of Logistic Regression:
    [[-0.45928925 0.83069892 -2.26606529 -0.99743983]
    [ 0.33117319 -0.72863426 -0.06841147 -0.98711029]
    [ 0.12811606 -0.10206466 2.33447676 1.98455011]]
    the intercept(w0) of Logistic Regression:
    [ 9.43880649 3.93047365 -13.36928015]

    #在训练集和测试集上分布利用训练好的模型进行预测
    train_predict=clf.predict(x_train)
    test_predict=clf.predict(x_test)
    #由于逻辑回归模型是概率预测模型(前文介绍的p=p(y=1|x,\theta)),所有我们可以利用predict_proba函数预测其概率
    
    train_predict_proba=clf.predict_proba(x_train)
    test_predict_proba=clf.predict_proba(x_test)
    
    print('The test predict Probability of each class:\n',test_predict_proba)
    #其中第一列代表预测为0类的概率,第二列代表预测为1类的概率,第三列代表预测为2类的概率。
    
    #利用accuracy(准确度)【预测正确的样本数目占总预测样本数目的比例】评估模型效果
    print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_train,train_predict))
    print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_test,test_predict))
    
    #查看混淆矩阵
    confusion_matrix_result=metrics.confusion_matrix(test_predict,y_test)
    print('The confusion matrix result:\n',confusion_matrix_result)
    
    #利用热力图对于结果进行可视化
    plt.figure(figsize=(8,6))
    sns.heatmap(confusion_matrix_result,annot=True,cmap='Blues')
    plt.xlabel('Predicted labels')
    plt.ylabel('True labels')
    plt.show()
    

    结果
    在这里插入图片描述

    展开全文
  • 机器学习算法与Python实践这个系列主要是参考《机器学习实战》这本书。因为自己想学习Python,然后也想对一些机器学习算法加深下了解,所以就想通过Python来实现几个比较常用的机器学习算法。恰好遇见这本同样定位的...

    转自:http://blog.csdn.net/zouxy09/article/details/20319673



    机器学习算法与Python实践这个系列主要是参考《机器学习实战》这本书。因为自己想学习Python,然后也想对一些机器学习算法加深下了解,所以就想通过Python来实现几个比较常用的机器学习算法。恰好遇见这本同样定位的书籍,所以就参考这本书的过程来学习了。

           这节学习的是逻辑回归(Logistic Regression),也算进入了比较正统的机器学习算法。啥叫正统呢?我概念里面机器学习算法一般是这样一个步骤:

    1)对于一个问题,我们用数学语言来描述它,然后建立一个模型,例如回归模型或者分类模型等来描述这个问题;

    2)通过最大似然、最大后验概率或者最小化分类误差等等建立模型的代价函数,也就是一个最优化问题。找到最优化问题的解,也就是能拟合我们的数据的最好的模型参数;

    3)然后我们需要求解这个代价函数,找到最优解。这求解也就分很多种情况了:

          a)如果这个优化函数存在解析解。例如我们求最值一般是对代价函数求导,找到导数为0的点,也就是最大值或者最小值的地方了。如果代价函数能简单求导,并且求导后为0的式子存在解析解,那么我们就可以直接得到最优的参数了。

          b)如果式子很难求导,例如函数里面存在隐含的变量或者变量相互间存在耦合,也就互相依赖的情况。或者求导后式子得不到解释解,例如未知参数的个数大于已知方程组的个数等。这时候我们就需要借助迭代算法来一步一步找到最有解了。迭代是个很神奇的东西,它将远大的目标(也就是找到最优的解,例如爬上山顶)记在心上,然后给自己定个短期目标(也就是每走一步,就离远大的目标更近一点),脚踏实地,心无旁贷,像个蜗牛一样,一步一步往上爬,支撑它的唯一信念是:只要我每一步都爬高一点,那么积跬步,肯定能达到自己人生的巅峰,尽享山登绝顶我为峰的豪迈与忘我。

           另外需要考虑的情况是,如果代价函数是凸函数,那么就存在全局最优解,方圆五百里就只有一个山峰,那命中注定了,它就是你要找的唯一了。但如果是非凸的,那么就会有很多局部最优的解,有一望无际的山峰,人的视野是伟大的也是渺小的,你不知道哪个山峰才是最高的,可能你会被命运作弄,很无辜的陷入一个局部最优里面,坐井观天,以为自己找到的就是最好的。没想到山外有山,人外有人,光芒总在未知的远处默默绽放。但也许命运眷恋善良的你,带给你的总是最好的归宿。也有很多不信命的人,觉得人定胜天的人,誓要找到最好的,否则不会罢休,永不向命运妥协,除非自己有一天累了,倒下了,也要靠剩下的一口气,迈出一口气能支撑的路程。好悲凉啊……哈哈。

            呃,不知道扯那去了,也不知道自己说的有没有错,有错的话请大家不吝指正。那下面就进入正题吧。正如上面所述,逻辑回归就是这样的一个过程:面对一个回归或者分类问题,建立代价函数,然后通过优化方法迭代求解出最优的模型参数,然后测试验证我们这个求解的模型的好坏,冥冥人海,滚滚红尘,我们是否找到了最适合的那个她。

     

    一、逻辑回归(LogisticRegression)

           Logistic regression (逻辑回归)是当前业界比较常用的机器学习方法,用于估计某种事物的可能性。之前在经典之作《数学之美》中也看到了它用于广告预测,也就是根据某广告被用户点击的可能性,把最可能被用户点击的广告摆在用户能看到的地方,然后叫他“你点我啊!”用户点了,你就有钱收了。这就是为什么我们的电脑现在广告泛滥的原因了。

           还有类似的某用户购买某商品的可能性,某病人患有某种疾病的可能性啊等等。这个世界是随机的(当然了,人为的确定性系统除外,但也有可能有噪声或产生错误的结果,只是这个错误发生的可能性太小了,小到千万年不遇,小到忽略不计而已),所以万物的发生都可以用可能性或者几率(Odds)来表达。“几率”指的是某事物发生的可能性与不发生的可能性的比值。

           Logistic regression可以用来回归,也可以用来分类,主要是二分类。还记得上几节讲的支持向量机SVM吗?它就是个二分类的例如,它可以将两个不同类别的样本给分开,思想是找到最能区分它们的那个分类超平面。但当你给一个新的样本给它,它能够给你的只有一个答案,你这个样本是正类还是负类。例如你问SVM,某个女生是否喜欢你,它只会回答你喜欢或者不喜欢。这对我们来说,显得太粗鲁了,要不希望,要不绝望,这都不利于身心健康。那如果它可以告诉我,她很喜欢、有一点喜欢、不怎么喜欢或者一点都不喜欢,你想都不用想了等等,告诉你她有49%的几率喜欢你,总比直接说她不喜欢你,来得温柔。而且还提供了额外的信息,她来到你的身边你有多少希望,你得再努力多少倍,知己知彼百战百胜,哈哈。Logistic regression就是这么温柔的,它给我们提供的就是你的这个样本属于正类的可能性是多少。

           还得来点数学。(更多的理解,请参阅参考文献)假设我们的样本是{x, y},y是0或者1,表示正类或者负类,x是我们的m维的样本特征向量。那么这个样本x属于正类,也就是y=1的“概率”可以通过下面的逻辑函数来表示:

           这里θ是模型参数,也就是回归系数,σ是sigmoid函数。实际上这个函数是由下面的对数几率(也就是x属于正类的可能性和负类的可能性的比值的对数)变换得到的:

           换句话说,y也就是我们关系的变量,例如她喜不喜欢你,与多个自变量(因素)有关,例如你人品怎样、车子是两个轮的还是四个轮的、长得胜过潘安还是和犀利哥有得一拼、有千尺豪宅还是三寸茅庐等等,我们把这些因素表示为x1, x2,…, xm。那这个女的怎样考量这些因素呢?最快的方式就是把这些因素的得分都加起来,最后得到的和越大,就表示越喜欢。但每个人心里其实都有一杆称,每个人考虑的因素不同,萝卜青菜,各有所爱嘛。例如这个女生更看中你的人品,人品的权值是0.6,不看重你有没有钱,没钱了一起努力奋斗,那么有没有钱的权值是0.001等等。我们将这些对应x1, x2,…, xm的权值叫做回归系数,表达为θ1, θ2,…, θm。他们的加权和就是你的总得分了。请选择你的心仪男生,非诚勿扰!哈哈。

           所以说上面的logistic回归就是一个线性分类模型,它与线性回归的不同点在于:为了将线性回归输出的很大范围的数,例如从负无穷到正无穷,压缩到0和1之间,这样的输出值表达为“可能性”才能说服广大民众。当然了,把大值压缩到这个范围还有个很好的好处,就是可以消除特别冒尖的变量的影响(不知道理解的是否正确)。而实现这个伟大的功能其实就只需要平凡一举,也就是在输出加一个logistic函数。另外,对于二分类来说,可以简单的认为:如果样本x属于正类的概率大于0.5,那么就判定它是正类,否则就是负类。实际上,SVM的类概率就是样本到边界的距离,这个活实际上就让logistic regression给干了。

           所以说,LogisticRegression 就是一个被logistic方程归一化后的线性回归,仅此而已。

    好了,关于LR的八卦就聊到这。归入到正统的机器学习框架下,模型选好了,只是模型的参数θ还是未知的,我们需要用我们收集到的数据来训练求解得到它。那我们下一步要做的事情就是建立代价函数了。

           LogisticRegression最基本的学习算法是最大似然。啥叫最大似然,可以看看我的另一篇博文“从最大似然到EM算法浅解”。

           假设我们有n个独立的训练样本{(x1, y1) ,(x2, y2),…, (xn, yn)},y={0, 1}。那每一个观察到的样本(xi, yi)出现的概率是:


           上面为什么是这样呢?当y=1的时候,后面那一项是不是没有了,那就只剩下x属于1类的概率,当y=0的时候,第一项是不是没有了,那就只剩下后面那个x属于0的概率(1减去x属于1的概率)。所以不管y是0还是1,上面得到的数,都是(x, y)出现的概率。那我们的整个样本集,也就是n个独立的样本出现的似然函数为(因为每个样本都是独立的,所以n个样本出现的概率就是他们各自出现的概率相乘):

           那最大似然法就是求模型中使得似然函数最大的系数取值θ*。这个最大似然就是我们的代价函数(cost function)了。

           OK,那代价函数有了,我们下一步要做的就是优化求解了。我们先尝试对上面的代价函数求导,看导数为0的时候可不可以解出来,也就是有没有解析解,有这个解的时候,就皆大欢喜了,一步到位。如果没有就需要通过迭代了,耗时耗力。

           我们先变换下L(θ):取自然对数,然后化简(不要看到一堆公式就害怕哦,很简单的哦,只需要耐心一点点,自己动手推推就知道了。注:有xi的时候,表示它是第i个样本,下面没有做区分了,相信你的眼睛是雪亮的),得到:

           这时候,用L(θ)对θ求导,得到:


           然后我们令该导数为0,你会很失望的发现,它无法解析求解。不信你就去尝试一下。所以没办法了,只能借助高大上的迭代来搞定了。这里选用了经典的梯度下降算法。

     

    二、优化求解

    2.1、梯度下降(gradient descent)

            Gradient descent 又叫 steepest descent,是利用一阶的梯度信息找到函数局部最优解的一种方法,也是机器学习里面最简单最常用的一种优化方法。它的思想很简单,和我开篇说的那样,要找最小值,我只需要每一步都往下走(也就是每一步都可以让代价函数小一点),然后不断的走,那肯定能走到最小值的地方,例如下图所示:

          但,我同时也需要更快的到达最小值啊,怎么办呢?我们需要每一步都找下坡最快的地方,也就是每一步我走某个方向,都比走其他方法,要离最小值更近。而这个下坡最快的方向,就是梯度的负方向了。

    对logistic Regression来说,梯度下降算法新鲜出炉,如下:


          其中,参数α叫学习率,就是每一步走多远,这个参数蛮关键的。如果设置的太多,那么很容易就在最优值附加徘徊,因为你步伐太大了。例如要从广州到上海,但是你的一步的距离就是广州到北京那么远,没有半步的说法,自己能迈那么大步,是幸运呢?还是不幸呢?事物总有两面性嘛,它带来的好处是能很快的从远离最优值的地方回到最优值附近,只是在最优值附近的时候,它有心无力了。但如果设置的太小,那收敛速度就太慢了,向蜗牛一样,虽然会落在最优的点,但是这速度如果是猴年马月,我们也没这耐心啊。所以有的改进就是在这个学习率这个地方下刀子的。我开始迭代是,学习率大,慢慢的接近最优值的时候,我的学习率变小就可以了。所谓采两者之精华啊!这个优化具体见2.3 。

           梯度下降算法的伪代码如下:

    ################################################

    初始化回归系数为1

    重复下面步骤直到收敛{

            计算整个数据集的梯度

            使用alpha x gradient来更新回归系数

    }

    返回回归系数值

    ################################################

          注:因为本文中是求解的Logit回归的代价函数是似然函数,需要最大化似然函数。所以我们要用的是梯度上升算法。但因为其和梯度下降的原理是一样的,只是一个是找最大值,一个是找最小值。找最大值的方向就是梯度的方向,最小值的方向就是梯度的负方向。不影响我们的说明,所以当时自己就忘了改过来了,谢谢评论下面@wxltt的指出。另外,最大似然可以通过取负对数,转化为求最小值。代码里面的注释也是有误的,写的代码是梯度上升,注销成了梯度下降,对大家造成的不便,希望大家海涵。

     

    2.2、随机梯度下降SGD (stochastic gradient descent)

          梯度下降算法在每次更新回归系数的时候都需要遍历整个数据集(计算整个数据集的回归误差),该方法对小数据集尚可。但当遇到有数十亿样本和成千上万的特征时,就有点力不从心了,它的计算复杂度太高。改进的方法是一次仅用一个样本点(的回归误差)来更新回归系数。这个方法叫随机梯度下降算法。由于可以在新的样本到来的时候对分类器进行增量的更新(假设我们已经在数据库A上训练好一个分类器h了,那新来一个样本x。对非增量学习算法来说,我们需要把x和数据库A混在一起,组成新的数据库B,再重新训练新的分类器。但对增量学习算法,我们只需要用新样本x来更新已有分类器h的参数即可),所以它属于在线学习算法。与在线学习相对应,一次处理整个数据集的叫“批处理”。

            随机梯度下降算法的伪代码如下:

    ################################################

    初始化回归系数为1

    重复下面步骤直到收敛{

            对数据集中每个样本

                   计算该样本的梯度

                    使用alpha xgradient来更新回归系数

     }

    返回回归系数值

    ################################################

     

    2.3、改进的随机梯度下降

          评价一个优化算法的优劣主要是看它是否收敛,也就是说参数是否达到稳定值,是否还会不断的变化?收敛速度是否快?

           上图展示了随机梯度下降算法在200次迭代中(请先看第三和第四节再回来看这里。我们的数据库有100个二维样本,每个样本都对系数调整一次,所以共有200*100=20000次调整)三个回归系数的变化过程。其中系数X2经过50次迭代就达到了稳定值。但系数X1和X0到100次迭代后稳定。而且可恨的是系数X1和X2还在很调皮的周期波动,迭代次数很大了,心还停不下来。产生这个现象的原因是存在一些无法正确分类的样本点,也就是我们的数据集并非线性可分,但我们的logistic regression是线性分类模型,对非线性可分情况无能为力。然而我们的优化程序并没能意识到这些不正常的样本点,还一视同仁的对待,调整系数去减少对这些样本的分类误差,从而导致了在每次迭代时引发系数的剧烈改变。对我们来说,我们期待算法能避免来回波动,从而快速稳定和收敛到某个值。

           对随机梯度下降算法,我们做两处改进来避免上述的波动问题:

    1)在每次迭代时,调整更新步长alpha的值。随着迭代的进行,alpha越来越小,这会缓解系数的高频波动(也就是每次迭代系数改变得太大,跳的跨度太大)。当然了,为了避免alpha随着迭代不断减小到接近于0(这时候,系数几乎没有调整,那么迭代也没有意义了),我们约束alpha一定大于一个稍微大点的常数项,具体见代码。

    2)每次迭代,改变样本的优化顺序。也就是随机选择样本来更新回归系数。这样做可以减少周期性的波动,因为样本顺序的改变,使得每次迭代不再形成周期性。

           改进的随机梯度下降算法的伪代码如下:

    ################################################

    初始化回归系数为1

    重复下面步骤直到收敛{

           对随机遍历的数据集中的每个样本

                  随着迭代的逐渐进行,减小alpha的值

                  计算该样本的梯度

                  使用alpha x gradient来更新回归系数

        }

    返回回归系数值

    ################################################

           比较原始的随机梯度下降和改进后的梯度下降,可以看到两点不同:

    1)系数不再出现周期性波动。2)系数可以很快的稳定下来,也就是快速收敛。这里只迭代了20次就收敛了。而上面的随机梯度下降需要迭代200次才能稳定。

     

    三、Python实现

          我使用的Python是2.7.5版本的。附加的库有Numpy和Matplotlib。具体的安装和配置见前面的博文。在代码中已经有了比较详细的注释了。不知道有没有错误的地方,如果有,还望大家指正(每次的运行结果都有可能不同)。里面我写了个可视化结果的函数,但只能在二维的数据上面使用。直接贴代码:

    logRegression.py

    [python] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. #################################################  
    2. # logRegression: Logistic Regression  
    3. # Author : zouxy  
    4. # Date   : 2014-03-02  
    5. # HomePage : http://blog.csdn.net/zouxy09  
    6. # Email  : zouxy09@qq.com  
    7. #################################################  
    8.   
    9. from numpy import *  
    10. import matplotlib.pyplot as plt  
    11. import time  
    12.   
    13.   
    14. # calculate the sigmoid function  
    15. def sigmoid(inX):  
    16.     return 1.0 / (1 + exp(-inX))  
    17.   
    18.   
    19. # train a logistic regression model using some optional optimize algorithm  
    20. # input: train_x is a mat datatype, each row stands for one sample  
    21. #        train_y is mat datatype too, each row is the corresponding label  
    22. #        opts is optimize option include step and maximum number of iterations  
    23. def trainLogRegres(train_x, train_y, opts):  
    24.     # calculate training time  
    25.     startTime = time.time()  
    26.   
    27.     numSamples, numFeatures = shape(train_x)  
    28.     alpha = opts['alpha']; maxIter = opts['maxIter']  
    29.     weights = ones((numFeatures, 1))  
    30.   
    31.     # optimize through gradient descent algorilthm  
    32.     for k in range(maxIter):  
    33.         if opts['optimizeType'] == 'gradDescent'# gradient descent algorilthm  
    34.             output = sigmoid(train_x * weights)  
    35.             error = train_y - output  
    36.             weights = weights + alpha * train_x.transpose() * error  
    37.         elif opts['optimizeType'] == 'stocGradDescent'# stochastic gradient descent  
    38.             for i in range(numSamples):  
    39.                 output = sigmoid(train_x[i, :] * weights)  
    40.                 error = train_y[i, 0] - output  
    41.                 weights = weights + alpha * train_x[i, :].transpose() * error  
    42.         elif opts['optimizeType'] == 'smoothStocGradDescent'# smooth stochastic gradient descent  
    43.             # randomly select samples to optimize for reducing cycle fluctuations   
    44.             dataIndex = range(numSamples)  
    45.             for i in range(numSamples):  
    46.                 alpha = 4.0 / (1.0 + k + i) + 0.01  
    47.                 randIndex = int(random.uniform(0, len(dataIndex)))  
    48.                 output = sigmoid(train_x[randIndex, :] * weights)  
    49.                 error = train_y[randIndex, 0] - output  
    50.                 weights = weights + alpha * train_x[randIndex, :].transpose() * error  
    51.                 del(dataIndex[randIndex]) # during one interation, delete the optimized sample  
    52.         else:  
    53.             raise NameError('Not support optimize method type!')  
    54.       
    55.   
    56.     print 'Congratulations, training complete! Took %fs!' % (time.time() - startTime)  
    57.     return weights  
    58.   
    59.   
    60. # test your trained Logistic Regression model given test set  
    61. def testLogRegres(weights, test_x, test_y):  
    62.     numSamples, numFeatures = shape(test_x)  
    63.     matchCount = 0  
    64.     for i in xrange(numSamples):  
    65.         predict = sigmoid(test_x[i, :] * weights)[00] > 0.5  
    66.         if predict == bool(test_y[i, 0]):  
    67.             matchCount += 1  
    68.     accuracy = float(matchCount) / numSamples  
    69.     return accuracy  
    70.   
    71.   
    72. # show your trained logistic regression model only available with 2-D data  
    73. def showLogRegres(weights, train_x, train_y):  
    74.     # notice: train_x and train_y is mat datatype  
    75.     numSamples, numFeatures = shape(train_x)  
    76.     if numFeatures != 3:  
    77.         print "Sorry! I can not draw because the dimension of your data is not 2!"  
    78.         return 1  
    79.   
    80.     # draw all samples  
    81.     for i in xrange(numSamples):  
    82.         if int(train_y[i, 0]) == 0:  
    83.             plt.plot(train_x[i, 1], train_x[i, 2], 'or')  
    84.         elif int(train_y[i, 0]) == 1:  
    85.             plt.plot(train_x[i, 1], train_x[i, 2], 'ob')  
    86.   
    87.     # draw the classify line  
    88.     min_x = min(train_x[:, 1])[00]  
    89.     max_x = max(train_x[:, 1])[00]  
    90.     weights = weights.getA()  # convert mat to array  
    91.     y_min_x = float(-weights[0] - weights[1] * min_x) / weights[2]  
    92.     y_max_x = float(-weights[0] - weights[1] * max_x) / weights[2]  
    93.     plt.plot([min_x, max_x], [y_min_x, y_max_x], '-g')  
    94.     plt.xlabel('X1'); plt.ylabel('X2')  
    95.     plt.show()  

    四、测试结果

            测试代码:

    test_logRegression.py

    [python] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. #################################################  
    2. # logRegression: Logistic Regression  
    3. # Author : zouxy  
    4. # Date   : 2014-03-02  
    5. # HomePage : http://blog.csdn.net/zouxy09  
    6. # Email  : zouxy09@qq.com  
    7. #################################################  
    8.   
    9. from numpy import *  
    10. import matplotlib.pyplot as plt  
    11. import time  
    12.   
    13. def loadData():  
    14.     train_x = []  
    15.     train_y = []  
    16.     fileIn = open('E:/Python/Machine Learning in Action/testSet.txt')  
    17.     for line in fileIn.readlines():  
    18.         lineArr = line.strip().split()  
    19.         train_x.append([1.0, float(lineArr[0]), float(lineArr[1])])  
    20.         train_y.append(float(lineArr[2]))  
    21.     return mat(train_x), mat(train_y).transpose()  
    22.   
    23.   
    24. ## step 1: load data  
    25. print "step 1: load data..."  
    26. train_x, train_y = loadData()  
    27. test_x = train_x; test_y = train_y  
    28.   
    29. ## step 2: training...  
    30. print "step 2: training..."  
    31. opts = {'alpha'0.01'maxIter'20'optimizeType''smoothStocGradDescent'}  
    32. optimalWeights = trainLogRegres(train_x, train_y, opts)  
    33.   
    34. ## step 3: testing  
    35. print "step 3: testing..."  
    36. accuracy = testLogRegres(optimalWeights, test_x, test_y)  
    37.   
    38. ## step 4: show the result  
    39. print "step 4: show the result..."    
    40. print 'The classify accuracy is: %.3f%%' % (accuracy * 100)  
    41. showLogRegres(optimalWeights, train_x, train_y)   

            测试数据是二维的,共100个样本。有2个类。如下:

    testSet.txt

    [python] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. -0.017612   14.053064   0  
    2. -1.395634   4.662541    1  
    3. -0.752157   6.538620    0  
    4. -1.322371   7.152853    0  
    5. 0.423363    11.054677   0  
    6. 0.406704    7.067335    1  
    7. 0.667394    12.741452   0  
    8. -2.460150   6.866805    1  
    9. 0.569411    9.548755    0  
    10. -0.026632   10.427743   0  
    11. 0.850433    6.920334    1  
    12. 1.347183    13.175500   0  
    13. 1.176813    3.167020    1  
    14. -1.781871   9.097953    0  
    15. -0.566606   5.749003    1  
    16. 0.931635    1.589505    1  
    17. -0.024205   6.151823    1  
    18. -0.036453   2.690988    1  
    19. -0.196949   0.444165    1  
    20. 1.014459    5.754399    1  
    21. 1.985298    3.230619    1  
    22. -1.693453   -0.557540   1  
    23. -0.576525   11.778922   0  
    24. -0.346811   -1.678730   1  
    25. -2.124484   2.672471    1  
    26. 1.217916    9.597015    0  
    27. -0.733928   9.098687    0  
    28. -3.642001   -1.618087   1  
    29. 0.315985    3.523953    1  
    30. 1.416614    9.619232    0  
    31. -0.386323   3.989286    1  
    32. 0.556921    8.294984    1  
    33. 1.224863    11.587360   0  
    34. -1.347803   -2.406051   1  
    35. 1.196604    4.951851    1  
    36. 0.275221    9.543647    0  
    37. 0.470575    9.332488    0  
    38. -1.889567   9.542662    0  
    39. -1.527893   12.150579   0  
    40. -1.185247   11.309318   0  
    41. -0.445678   3.297303    1  
    42. 1.042222    6.105155    1  
    43. -0.618787   10.320986   0  
    44. 1.152083    0.548467    1  
    45. 0.828534    2.676045    1  
    46. -1.237728   10.549033   0  
    47. -0.683565   -2.166125   1  
    48. 0.229456    5.921938    1  
    49. -0.959885   11.555336   0  
    50. 0.492911    10.993324   0  
    51. 0.184992    8.721488    0  
    52. -0.355715   10.325976   0  
    53. -0.397822   8.058397    0  
    54. 0.824839    13.730343   0  
    55. 1.507278    5.027866    1  
    56. 0.099671    6.835839    1  
    57. -0.344008   10.717485   0  
    58. 1.785928    7.718645    1  
    59. -0.918801   11.560217   0  
    60. -0.364009   4.747300    1  
    61. -0.841722   4.119083    1  
    62. 0.490426    1.960539    1  
    63. -0.007194   9.075792    0  
    64. 0.356107    12.447863   0  
    65. 0.342578    12.281162   0  
    66. -0.810823   -1.466018   1  
    67. 2.530777    6.476801    1  
    68. 1.296683    11.607559   0  
    69. 0.475487    12.040035   0  
    70. -0.783277   11.009725   0  
    71. 0.074798    11.023650   0  
    72. -1.337472   0.468339    1  
    73. -0.102781   13.763651   0  
    74. -0.147324   2.874846    1  
    75. 0.518389    9.887035    0  
    76. 1.015399    7.571882    0  
    77. -1.658086   -0.027255   1  
    78. 1.319944    2.171228    1  
    79. 2.056216    5.019981    1  
    80. -0.851633   4.375691    1  
    81. -1.510047   6.061992    0  
    82. -1.076637   -3.181888   1  
    83. 1.821096    10.283990   0  
    84. 3.010150    8.401766    1  
    85. -1.099458   1.688274    1  
    86. -0.834872   -1.733869   1  
    87. -0.846637   3.849075    1  
    88. 1.400102    12.628781   0  
    89. 1.752842    5.468166    1  
    90. 0.078557    0.059736    1  
    91. 0.089392    -0.715300   1  
    92. 1.825662    12.693808   0  
    93. 0.197445    9.744638    0  
    94. 0.126117    0.922311    1  
    95. -0.679797   1.220530    1  
    96. 0.677983    2.556666    1  
    97. 0.761349    10.693862   0  
    98. -2.168791   0.143632    1  
    99. 1.388610    9.341997    0  
    100. 0.317029    14.739025   0  

             训练结果:

           (a)梯度下降算法迭代500次。(b)随机梯度下降算法迭代200次。(c)改进的随机梯度下降算法迭代20次。(d)改进的随机梯度下降算法迭代200次。

     

    五、参考文献

    [1] Logisticregression (逻辑回归) 概述

    [2] LogisticRegression 之基础知识准备

    [3] LogisticRegression

    展开全文
  • part, test_size = 0.2, random_state = 2020) # random_state为随机数种子 # 从sklearn中导入逻辑回归模型 from sklearn.linear_model import LogisticRegression # 定义 逻辑回归模型 clf = LogisticRegression...

    step 1:导入库函数

    # 基础函数库
    import numpy as np
    import pandas as pd
    
    #绘图函数库
    import matplotlib.pyplot as plt
    import seaborn as sns
    

    本次我们选择鸢花数据(iris)进行方法的尝试训练,该数据集一共包含5个变量,其中4个特征变量,1个目标分类变量。共有150个样本,目标变量为 花的类别 其都属于鸢尾属下的三个亚属,分别是山鸢尾 (Iris-setosa),变色鸢尾(Iris-versicolor)和维吉尼亚鸢尾(Iris-virginica)。包含的三种鸢尾花的四个特征,分别是花萼长度(cm)、花萼宽度(cm)、花瓣长度(cm)、花瓣宽度(cm),这些形态特征在过去被用来识别物种。
    在这里插入图片描述

    step 2: 数据的读取/载入

    # 我们利用 sklearn 中自带的 iris 数据作为数据载入,并利用Pandas转化为DataFrame格式
    from sklearn.datasets import load_iris
    data = load_iris() #得到数据
    iris_target = data.target #得到数据对应的标签,其中0,1,2分别代表'setosa', 'versicolor', 'virginica'三种不同花的类别。
    iris_features = pd.DataFrame(data=data.data, columns=data.feature_names) 
    #data.data得到鸢尾花的数据(也就是花萼和花瓣各自的长宽)
    #data.features_names得到data.data中各个数据的名称
    #利用Pandas转化为DataFrame格式
    

    step 3: 数据信息的简单查看

    # 利用info()查看数据的整体信息
    iris_features.info()
    

    输出如下:
    在这里插入图片描述

    # 进行简单的数据查看,我们可以利用 .head() 头部或者.tail()尾部
    iris_features.head()
    

    输出如下:
    在这里插入图片描述

    # 利用value_counts函数查看每个类别数量
    pd.Series(iris_target).value_counts()
    

    iris_target 的输出如下:
    在这里插入图片描述
    pd.Series(iris_target)的输出如下:
    在这里插入图片描述
    pd.Series(iris_target).value_counts()的输出如下:
    在这里插入图片描述

    # 对于特征进行一些统计描述
    iris_features.describe()
    

    输出如下:
    count
    count代表数量,mean代表均值,std代表标准差

    step 4:可视化描述

    # 合并标签和特征信息
    iris_all = iris_features.copy() # 进行浅拷贝,防止对于原始数据的修改
    iris_all['target'] = iris_target #给拷贝的数据增加‘target’属性
    
    # 特征与标签组合的散点可视化
    sns.pairplot(data=iris_all,diag_kind='hist', hue= 'target')
    # diag_kind='hist'设置主对角线为直方图,'kde'设置主对角线为密度图
    # hue='target' 设置按照target字段进行分类
    plt.show()
    

    输出如下:
    在这里插入图片描述

    for col in iris_features.columns:
        sns.boxplot(x='target', y=col, saturation=0.5,palette='pastel', data=iris_all)
        # x轴为'target',y为该数据特征的列,saturation为颜色的饱和度,palette为调色板,一共6种,本实验选择的是‘pastel’
        plt.title(col) # 图表名称为数据特征的列
        plt.show()
    

    输出为(一共4个):
    在这里插入图片描述

    # 选取其前三个特征绘制三维散点图
    from mpl_toolkits.mplot3d import Axes3D
    
    fig = plt.figure(figsize=(10,8))
    ax = fig.add_subplot(111, projection='3d')
    
    iris_all_class0 = iris_all[iris_all['target']==0].values
    #上述代码得到类别为0的鸢尾花的所有数据,末尾'.values'把数据列表化,前四列为花萼和花瓣各自的长宽,最后一列为鸢尾花的类别
    iris_all_class1 = iris_all[iris_all['target']==1].values
    iris_all_class2 = iris_all[iris_all['target']==2].values
    # 'setosa'(0), 'versicolor'(1), 'virginica'(2)
    ax.scatter(iris_all_class0[:,0], iris_all_class0[:,1], iris_all_class0[:,2],label='setosa')
    #只用到前三列
    ax.scatter(iris_all_class1[:,0], iris_all_class1[:,1], iris_all_class1[:,2],label='versicolor')
    ax.scatter(iris_all_class2[:,0], iris_all_class2[:,1], iris_all_class2[:,2],label='virginica')
    plt.legend() # 显示图中点代表的类别
    
    plt.show()
    

    step 5:利用逻辑回归模型在二分类上进行训练和预测

    # 为了正确评估模型性能,将数据划分为训练集和测试集,并在训练集上训练模型,在测试集上验证模型性能。
    from sklearn.model_selection import train_test_split
    
    # 选择其类别为0和1的样本 (不包括类别为2的样本)
    iris_features_part = iris_features.iloc[:100] # '.iloc' 按照行号取值。类别0和类别1在前100个,所以取前100个
    iris_target_part = iris_target[:100]
    iris_features_part
    
    # 测试集大小为20%, 80%/20%分
    x_train, x_test, y_train, y_test = train_test_split(iris_features_part, iris_target_part, test_size = 0.2, random_state = 2020)
    # random_state为随机数种子
    
    # 从sklearn中导入逻辑回归模型
    from sklearn.linear_model import LogisticRegression
    # 定义 逻辑回归模型 
    clf = LogisticRegression(random_state=0, solver='lbfgs') #权重优化器,小型数据用lbfgs,大的用adam,另外还有sgd
    # 在训练集上训练逻辑回归模型
    clf.fit(x_train, y_train)
    
    # 查看其对应的w
    print('the weight of Logistic Regression:',clf.coef_)
    
    ## 查看其对应的w0
    print('the intercept(w0) of Logistic Regression:',clf.intercept_)
    

    输出如下:
    在这里插入图片描述

    # 分别在训练集和测试集上分布利用训练好的模型进行预测
    train_predict = clf.predict(x_train)
    test_predict = clf.predict(x_test)
    
    from sklearn import metrics
    
    ## 利用accuracy(准确度)【预测正确的样本数目占总预测样本数目的比例】评估模型效果
    print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_train,train_predict))
    print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_test,test_predict))
    
    ## 查看混淆矩阵 (预测值和真实值的各类情况统计矩阵)
    confusion_matrix_result = metrics.confusion_matrix(test_predict,y_test)
    print('The confusion matrix result:\n',confusion_matrix_result)
    
    # 利用热力图对于结果进行可视化
    plt.figure(figsize=(8, 6))
    sns.heatmap(confusion_matrix_result, annot=True, cmap='Blues')
    #annot表示在图中每个框都写入数字,cmap设置颜色渐变为蓝色
    plt.xlabel('Predicted labels')
    plt.ylabel('True labels')
    plt.show()
    

    输出如下:
    在这里插入图片描述

    step 6:逻辑回归模型 在三分类(多分类)上 进行训练和预测

    # 测试集大小为20%, 80%/20%分
    x_train, x_test, y_train, y_test = train_test_split(iris_features, iris_target, test_size = 0.2, random_state = 2020)
    # 定义 逻辑回归模型 
    clf = LogisticRegression(random_state=0, solver='lbfgs')
    # 在训练集上训练逻辑回归模型
    clf.fit(x_train, y_train)
    # 在训练集和测试集上分布利用训练好的模型进行预测
    train_predict = clf.predict(x_train)
    test_predict = clf.predict(x_test)
    
    # 由于逻辑回归模型是概率预测模型(前文介绍的 p = p(y=1|x,\theta)),所有我们可以利用 predict_proba 函数预测其概率
    train_predict_proba = clf.predict_proba(x_train)
    test_predict_proba = clf.predict_proba(x_test)
    
    print('The test predict Probability of each class:\n',test_predict_proba)
    ## 其中第一列代表预测为0类的概率,第二列代表预测为1类的概率,第三列代表预测为2类的概率。
    
    # 利用accuracy(准确度)【预测正确的样本数目占总预测样本数目的比例】评估模型效果
    print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_train,train_predict))
    print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_test,test_predict))
    

    输出如下(仅展示部分):
    在这里插入图片描述

    # 查看混淆矩阵
    confusion_matrix_result = metrics.confusion_matrix(test_predict,y_test)
    print('The confusion matrix result:\n',confusion_matrix_result)
    
    # 利用热力图对于结果进行可视化
    plt.figure(figsize=(8, 6))
    sns.heatmap(confusion_matrix_result, annot=True, cmap='Blues')
    plt.xlabel('Predicted labels')
    plt.ylabel('True labels')
    plt.show()
    

    输出如下:
    在这里插入图片描述
    通过结果我们可以发现,其在三分类的结果的预测准确度上有所下降,其在测试集上的准确度为: 86.67% ,这是由于’versicolor’(1)和 ‘virginica’(2)这两个类别的特征,我们从可视化的时候也可以发现,其特征的边界具有一定的模糊性(边界类别混杂,没有明显区分边界),所有在这两类的预测上出现了一定的错误。

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 382
精华内容 152
关键字:

机器学习算法实践逻辑回归