这里是吴恩达机器学习的编程问题
假如你是芯片厂的技术人员,需要你通过芯片的两次检测来决定,芯片是否丢弃。给出了过去的芯片检测的数据,以及检测结果。
通过上面的描述可以知道这个一个分类问题,而分类问题,一般采用逻辑回归解决。
首先从文件中导入我们需要的数据
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)
得到的
图片.png
这个新构造的数据集有118行,28列。高阶函数可以帮助我们很好的拟合我们的数据但是,也会带来过拟合化的烦恼,导致我们方差偏大,泛化程度低,不适用与其他数据,所以这里还有用正则化,来惩罚我们
正则化代价函数和梯度函数
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优化算法来计算我们的最终,而不是直接使用梯度下降算法
优化算法求
#func是需要优化函数,x0传入的是初始值,fprime传入的是下降梯度函数,
#args传入优化函数的需要传入的参数
result2=opt.fmin_tnc(func=costReg,x0=theta,fprime=gradientReg,args=(X,y,2))
final_theta=result2[0]
检测准确度
自此我们就可以计算出的值了,然后看下准确度为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参考链接