参考内容:
- import numpy as np
- import pandas as pd
- import matplotlib.pyplot as plt
- from scipy.io import loadmat
- from scipy.optimize import minimize
- def load_data(path):
- data=loadmat(path)
- X=data['X']
- y=data['y']
- # print(type(X),type(y))
- return X,y
- path=r'C:\Users\Earth\Desktop\Coursera-ML-using-matlab-python-master\machine-learning-ex3\ex3\ex3data1.mat'
- X,y=load_data(path)
- print(np.unique(y))
- print(X.shape,y.shape)
- print(len(X))
- def plotanimage():
- pick_one=np.random.randint(0,5000)
- image=X[pick_one,:]
- # 选择 pick_one 这一行的所有列
- fig,ax=plt.subplots(figsize=(1,1))
- ax.matshow(image.reshape((20,20)),cmap='gray_r')
- plt.xticks([])
- plt.yticks([])
- plt.show()
- print('this should be {}'.format(y[pick_one]))
- # plotanimage()
- def sigmoid(z):
- return 1/(1+np.exp(-z))
- def costReg(theta,X,y,lam):
- first=np.mean(-y*np.log(sigmoid([email protected]))-(1-y)*np.log(1-sigmoid([email protected])))
- theta1=theta[1:]
- [email protected]*lam/(2*len(X))
- # 此处的 second 需要得到的是一个标量而非矩阵, 所以用θ1 的转置乘以它自身可以得到所有对应元素的平方和, 如果用θ1*θ1 得到的则是一个向量
- return first+second
- def gradient(theta,X,y,lam):
- first=([email protected](sigmoid([email protected])-y))/len(X)
- theta1=theta[1:]
- second=np.concatenate([np.array([0]),lam*theta1/len(X)])
- return first+second
- def one_vs_all(X,y,lam,K):
- all_theta=np.zeros((K,X.shape[1]))
- for i in range(1,K+1):
- theta=np.zeros(X.shape[1])
- y_i=np.array([1 if label==i else 0 for label in y])
- ret=minimize(fun=costReg,x0=theta,args=(X,y_i,lam),method='TNC',jac=gradient,options={'disp':True})
- all_theta[i-1,:]=ret.x
- # 序列为 i-1 的行, 所有列替换成 ret.x
- return all_theta
- def predict_all(X,all_theta):
- h=sigmoid([email protected]_theta.T)
- h_argmax=np.argmax(h,axis=1)
- h_argmax=h_argmax+1
- print('the type of argmax is',type(h_argmax))
- print('the shape of argmax is',h_argmax.shape)
- return h_argmax
- raw_X,raw_y=load_data(path)
- X=np.insert(raw_X,0,1,axis=1)
- print('the shape of X is',X.shape)
- # raw_X 要修改的对象, 0 要在第 0 行或列前插入对象, 要插入的值, axis=1 要插入的维度, 如果为 0 则插入的是行, 为 1 则插入的是列
- y=raw_y.flatten()
- print('the shape of y is',y.shape)
- all_theta=one_vs_all(X,y,1,10)
- print('the shape of all theta is',all_theta.shape)
- result=predict_all(X,all_theta)
- print(result.shape)
- def cal_accuracy(result,y):
- res=[1 if result[i]==y[i] else 0 for i in range(len(y))]
- return np.mean(res)
- print(result==y)
- # print(cal_accuracy(result,y))
- # theta2=np.zeros((10,X.shape[1]))
- # theta2 = theta2[1:]
- # print(theta2.shape)
- # t=([email protected]) / (2*len(X))
- # print(t.shape)
- # t1=theta2*theta2
- # print(t1.shape)
思路总结:
1, 首先从指定的数据中读取到 X,y, 根据需要初始化一个θ
2, 写出假设函数和代价函数, 其中需要注意的是正规化的代价函数不惩罚第一项θ0, 因此需要将θ进行变化处理
3, 根据公式写出梯度函数
4, 用高级算法对θ进行优化, 需要注意的是多分类问题根据每种分类分别去优化, 最后再把值赋给θ, 中间可以用 for 循环来实现
5, 训练好θ以后将其代假设函数中, 对于多分类问题, 认为概率最大的值即为预测出的类别
6, 对预测结果进行统计整理, 再和实际的值进行比较, 计算准确率
在练习过程中发现对 numpy 的一些常用函数掌握得还不够深刻, 包括切片, 降维等操作, 另外对画图这一块更生疏, 需要查漏补缺
套用公式矩阵相乘时, 对于谁和谁相乘, 是否需要转置有时候反应不过来, 最好的办法就是打出它们的 shape 根据矩阵相乘的特点进行操作.
来源: http://www.bubuko.com/infodetail-3087229.html