import os, sys
import numpy as np
from random import shuffle
import argparse
from math import log, floor
import pandas as pd
def load_data(train_data_path, train_label_path, test_data_path):
X_train = pd.read_csv(train_data_path, sep=',', header=0)
X_train = np.array(X_train.values)
Y_train = pd.read_csv(train_label_path, sep=',', header=0)
Y_train = np.array(Y_train.values)
X_test = pd.read_csv(test_data_path, sep=',', header=0)
X_test = np.array(X_test.values)
return (X_train, Y_train, X_test)
def _shuffle(X, Y):
randomize = np.arange(len(X))
np.random.shuffle(randomize)
return (X[randomize], Y[randomize])
# 数据标准化, 使数据便于处理
# 做特征缩放 : Feature Scaling
def normalize(X_all, X_test):
# Feature normalization with train and test X
X_train_test = np.concatenate((X_all, X_test)) # 先做拼接处理
print(X_train_test.shape)
mu = (sum(X_train_test) / X_train_test.shape[0])
sigma = np.std(X_train_test, axis=0) # 计算标准差
# 将mu sigma处理(复制)成可以直接操作的数组
mu = np.tile(mu, (X_train_test.shape[0], 1))
sigma = np.tile(sigma, (X_train_test.shape[0], 1))
X_train_test_normed = (X_train_test - mu) / sigma
# Split to train, test again
X_all = X_train_test_normed[0:X_all.shape[0]]
X_test = X_train_test_normed[X_all.shape[0]:]
return X_all, X_test
def split_valid_set(X_all, Y_all, percentage):
all_data_size = len(X_all)
valid_data_size = int(floor(all_data_size * percentage))
X_all, Y_all = _shuffle(X_all, Y_all) #打乱顺序
X_train, Y_train = X_all[0:valid_data_size], Y_all[0:valid_data_size]
X_valid, Y_valid = X_all[valid_data_size:], Y_all[valid_data_size:]
return X_train, Y_train, X_valid, Y_valid
def sigmoid(z):
res = 1 / (1.0 + np.exp(-z))
return np.clip(res, 1e-8, 1-(1e-8))
def valid(w, b, X_valid, Y_valid):
valid_data_size = len(X_valid)
z = (np.dot(X_valid, np.transpose(w)) + b)
y = sigmoid(z)
y_ = np.around(y)
result = (np.squeeze(Y_valid) == y_)
print('Validation acc = %f' % (float(result.sum()) / valid_data_size))
return
# train的目的是得到 w, b 参数
def train(X_all, Y_all, save_dir):
pass
# Split a 10%-validation set from the training set
# ???不懂为什么只取10%作为training data
valid_set_percentage = 0.1
X_train, Y_train, X_valid, Y_valid = split_valid_set(X_all, Y_all, valid_set_percentage) #把X_train和Y_train分别分成十份,取10%作为training set
# Initiallize parameter, hyperparameter
w = np.zeros((106,))
b = np.zeros((1,))
l_rate = 0.1
batch_size = 32
train_data_size = len(X_train)
step_num = int(floor(train_data_size / batch_size))
epoch_num = 1000
save_param_iter = 50
# Start training
total_loss = 0.0
for epoch in range(1, epoch_num):
# Do validation and parameter saving
# 每epoch_num个epoch保存一次
if (epoch) % save_param_iter == 0:
print('=====Saving Param at epoch %d=====' % epoch)
if not os.path.exists(save_dir):
os.mkdir(save_dir)
np.savetxt(os.path.join(save_dir, 'w'), w)
np.savetxt(os.path.join(save_dir, 'b'), [b,])
# 打印 trianing set 的loss
print('epoch avg loss = %f' % (total_loss / (float(save_param_iter) * train_data_size)))
total_loss = 0.0
# 打印valid中的正确率
valid(w, b, X_valid, Y_valid)
# Random shuffle
X_train, Y_train = _shuffle(X_train, Y_train)
# Train with batch
for idx in range(step_num):
# 取出一个batch
X = X_train[idx*batch_size:(idx+1)*batch_size]
Y = Y_train[idx*batch_size:(idx+1)*batch_size]
# logistic过程
z = np.dot(X, np.transpose(w)) + b
y = sigmoid(z)
# loss function : cross entropy
cross_entropy = -1 * (np.dot(np.squeeze(Y), np.log(y)) + np.dot((1 - np.squeeze(Y)), np.log(1 - y)))
total_loss += cross_entropy
w_grad = np.mean(-1 * X * (np.squeeze(Y) - y).reshape((batch_size,1)), axis=0)
b_grad = np.mean(-1 * (np.squeeze(Y) - y))
# SGD updating parameters
# 用随机梯度递减法, 不断更新
w = w - l_rate * w_grad
b = b - l_rate * b_grad
return
def infer(X_test, save_dir, output_dir):
test_data_size = len(X_test)
# Load parameters
print('=====Loading Param from %s=====' % save_dir)
w = np.loadtxt(os.path.join(save_dir, 'w'))
b = np.loadtxt(os.path.join(save_dir, 'b'))
# predict
z = (np.dot(X_test, np.transpose(w)) + b)
y = sigmoid(z)
y_ = np.around(y)
print('=====Write output to %s =====' % output_dir)
if not os.path.exists(output_dir):
os.mkdir(output_dir)
output_path = os.path.join(output_dir, 'log_prediction.csv')
with open(output_path, 'w') as f:
f.write('id,label\n')
for i, v in enumerate(y_):
f.write('%d,%d\n' %(i+1, v))
return
def main(opts):
# Load feature and label
X_all, Y_all, X_test = load_data(opts.train_data_path, opts.train_label_path, opts.test_data_path)
# Normalization
X_all, X_test = normalize(X_all, X_test)
# To train or to infer
if opts.train:
pass
# train(X_all, Y_all, opts.save_dir)
elif opts.infer:
infer(X_test, opts.save_dir, opts.output_dir)
else:
print("Error: Argument --train or --infer not found")
return
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Logistic Regression with Gradient Descent Method')
group = parser.add_mutually_exclusive_group()
group.add_argument('--train', action='store_true', default=False,
dest='train', help='Input --train to Train')
group.add_argument('--infer', action='store_true',default=False,
dest='infer', help='Input --infer to Infer')
parser.add_argument('--train_data_path', type=str,
default='C:/Users/liky\Desktop/PY/2017fall-ml-hw2-gh-pages/2017fall-ml-hw2-gh-pages/feature/X_train', dest='train_data_path',
help='Path to training data')
parser.add_argument('--train_label_path', type=str,
default='C:/Users/liky\Desktop/PY/2017fall-ml-hw2-gh-pages/2017fall-ml-hw2-gh-pages/feature/Y_train', dest='train_label_path',
help='Path to training data\'s label')
parser.add_argument('--test_data_path', type=str,
default='C:/Users/liky\Desktop/PY/2017fall-ml-hw2-gh-pages/2017fall-ml-hw2-gh-pages/feature/X_test', dest='test_data_path',
help='Path to testing data')
parser.add_argument('--save_dir', type=str,
default='C:/Users/liky\Desktop/PY/2017fall-ml-hw2-gh-pages/2017fall-ml-hw2-gh-pages/logistic_params/', dest='save_dir',
help='Path to save the model parameters')
parser.add_argument('--output_dir', type=str,
default='C:/Users/liky\Desktop/PY/2017fall-ml-hw2-gh-pages/2017fall-ml-hw2-gh-pages/logistic_output/', dest='output_dir',
help='Path to save the model parameters')
opts = parser.parse_args()
main(opts)
HW2 Logistic Regression 代码解析
猜你喜欢
转载自blog.csdn.net/li_k_y/article/details/84589347
今日推荐
周排行