3 逻辑回归----复杂边界问题

这里是吴恩达机器学习的编程问题

假如你是芯片厂的技术人员,需要你通过芯片的两次检测来决定,芯片是否丢弃。给出了过去的芯片检测的数据,以及检测结果。
 通过上面的描述可以知道这个一个分类问题,而分类问题,一般采用逻辑回归解决。

首先从文件中导入我们需要的数据
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize as opt #优化算法需要的包
data_path='F:/BrowserDown/机器学习/machine-learning-ex2/ex2/ex2data2.txt'
data=pd.read_csv(data_path,names=['Test1','Test2','Accept'])
然后对数据进行可视化
def plot_data():
    positive=data[data['Accept'].isin([1])] #注意语法类型:pandas.core.frame.DataFrame
    negative =data[data['Accept'].isin([0])]
    fig,ax=plt.subplots(figsize=(8,5))
    ax.scatter(positive['Test1'],positive['Test2'],s=50,c='b',marker='o',label='Accept')
    ax.scatter(negative['Test1'], negative['Test2'], s=50, c='r', marker='x', label='Not-Accept')
    plt.legend()
    ax.set_xlabel('Test 1 Score')
    ax.set_ylabel('Test 2 Score')
    plt.show()

这里的positive,negative其是两个表格,是将原来的表格通过data['Accept']等于0,或1来区分开。目的是为了在数据可视化时,将正样本与负样本进行区分开来。

可视化结果

图片.png

从可视化化结果来看,可以猜测决策函数是一个复杂的无规则的圆圈,而数据集只有test1,test2 两个特征值,很明显两个特征值是不够的这会造成较高的偏差(欠拟合)。所以我们需要扩充我们的特征值,让我们的具有高阶因子,来表示复杂的圆圈。

特征映射

def feature_mapping(x1,x2,power):
    data ={}
    for i in np.arange(power+1):
        for p in np.arange(i+1):
            data["f{}{}".format(i-p,p)]=np.power(x1,i-p)*np.power(x2,p)
    return pd.DataFrame(data)
x1=data['Test1'].as_matrix()
x2=data['Test2'].as_matrix()
_data=feature_mapping(x1,x2,power=6) 

得到的X=1+x_1+x_1x_2+x_1^2+x_1^2x_2+x_1^2x_2^2+....+x_1^6x_2^6(一共有28项)所以系数的\theta_{x}也应该有28项

图片.png

这个新构造的数据集有118行,28列。高阶函数可以帮助我们很好的拟合我们的数据但是,也会带来过拟合化的烦恼,导致我们方差偏大,泛化程度低,不适用与其他数据,所以这里还有用正则化,来惩罚我们\theta_{x}(不包含x=0)

正则化代价函数和梯度函数

def costReg(theta,X,y,l=1): #/alha=1
    #不惩罚第一项
    _theta=theta[1:]
    reg=(l/(2*len(X)))*(_theta@_theta)
    return cost(theta ,X,y)+reg

def gradient1(theta,X,y):
    return (X.T @ (sigmod(X @theta)-y))/len(X)
#梯度下降函数
#同样不惩罚第一个theta
def gradientReg(theta,X,y,l=1):
    reg=(l/len(X))*theta
    reg[0]=0
    return gradient1(theta,X,y)+reg

这里导入了scipy优化算法来计算我们的最终\theta,而不是直接使用梯度下降算法

优化算法求\theta

#func是需要优化函数,x0传入的是初始值,fprime传入的是下降梯度函数,
#args传入优化函数的需要传入的参数
result2=opt.fmin_tnc(func=costReg,x0=theta,fprime=gradientReg,args=(X,y,2))
final_theta=result2[0]

检测准确度

自此我们就可以计算出\theta的值了,然后看下准确度为0.83

def predict(theta,X):
    probability=sigmod(X@theta)
    return [1 if x>0.5 else 0 for x in probability] #return list
predictions=predict(final_theta,X)
correct=[1 if a==b else 0 for (a,b) in zip(predictions,y)]
accuracy=sum(correct)/len(X)
print(accuracy)
图片.png

最后绘制等高线代表决策边界

x=np.linspace(-1,1.5,250)
xx,yy=np.meshgrid(x,x)  #坐标向量返回坐标矩阵

z=feature_mapping(xx.ravel(),yy.ravel(),6).as_matrix()  #(62500, 28)
z=z @ final_theta
z=z.reshape(xx.shape)
positive = data[data['Accept'].isin([1])]  # 注意语法类型:pandas.core.frame.DataFrame
negative = data[data['Accept'].isin([0])]
fig,ax=plt.subplots(figsize=(8,5))
ax.scatter(positive['Test1'],positive['Test2'],s=50,c='b',marker='o',label='Accept')
ax.scatter(negative['Test1'], negative['Test2'], s=50, c='r', marker='x', label='Not-Accept')
plt.legend()
ax.set_xlabel('Test 1 Score')
ax.set_ylabel('Test 2 Score')
plt.contour(xx,yy,z,0) #等高线
plt.ylim(-0.8,1.2) #设置当前y轴范围
plt.show()

图片.png

CSDN参考链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。