作业一
作业要求
本此作业给出的数据是一份空气质量的检测资料,train.csv给出了整个2014年,每个月前20天的数据,这些数据包含了共计18个特征,在这些天每一个小时的变化。我们所需要的根据这些数据训练出一个模型,要求根据前九个小时的数据,预测出第10个小时的PM2.5。
作业要点
本此作业考察的是regression,模型本身很简单,并不是本此作业的重点,我认为本此作业的重点在于对数据的处理,也就是将给予的两个数据文件处理成模型需要的样子。
读取数据
import pandas as pd
data = pd.read_csv('./train.csv', encoding = 'big5')
数据提取与变换
data = data.iloc[:, 3:] #取出第三列之后的数据
data[data == 'NR'] = 0 #把非数字转为数字
raw_data = data.to_numpy()
将资料按照每月划分
month_data = {}
for month in range(12):
sample = np.empty([18, 480])
for day in range(20):
sample[:, day * 24 : (day + 1) * 24] = raw_data[18 * (20 * month + day) : 18 * (20 * month + day + 1), :]
month_data[month] = sample
这样month_data所存储的就是这个月的相关数据。
根据题目的要求,我们需要按照前九个小时的数据来得到第十个小时的数据,也就是前9个小时的18个features作为特征,第十个小时的PM2.5作为结果来构建regression回归,实际上所需要得到的就是一个含有18*9=162个系数的一维特征数组。而我们需要根据到手的数据制作训练集与测试集。
特征提取
x = np.empty([12 * 471, 18 * 9], dtype = float)
y = np.empty([12 * 471, 1], dtype = float)
for month in range(12):
for day in range(20):
for hour in range(24):
if day == 19 and hour > 14:
continue
x[month * 471 + day * 24 + hour, :] = month_data[month][:,day * 24 + hour : day * 24 + hour + 9].reshape(1, -1)
y[month * 471 + day * 24 + hour, 0] = month_data[month][9, day * 24 + hour + 9] #value
Normalize归一化
mean_x = np.mean(x, axis = 0) #18 * 9
std_x = np.std(x, axis = 0) #18 * 9
for i in range(len(x)): #12 * 471
for j in range(len(x[0])): #18 * 9
if std_x[j] != 0:
x[i][j] = (x[i][j] - mean_x[j]) / std_x[j]
到此数据处理基本完毕,接下来就是训练过程,比较简单,不多赘述。
作业二
作业要求
本此作业是一个简单的二分类问题,参考答案给出了两种方案,第一种是逻辑回归+激活函数,第二种使用generative model。
数据处理
读取数据
X_train_fpath = './data/X_train'
Y_train_fpath = './data/Y_train'
X_test_fpath = './data/X_test'
output_fpath = './output_{}.csv'
# Parse csv files to numpy array
with open(X_train_fpath) as f:
next(f)
X_train = np.array([line.strip('\n').split(',')[1:] for line in f], dtype = float)
with open(Y_train_fpath) as f:
next(f)
Y_train = np.array([line.strip('\n').split(',')[1] for line in f], dtype = float)
with open(X_test_fpath) as f:
next(f)
X_test = np.array([line.strip('\n').split(',')[1:] for line in f], dtype = float)
归一化函数
def _normalize(X, train = True, specified_column = None, X_mean = None, X_std = None):
if specified_column == None:
specified_column = np.arange(X.shape[1])
if train:
X_mean = np.mean(X[:, specified_column] ,0).reshape(1, -1)
X_std = np.std(X[:, specified_column], 0).reshape(1, -1)
X[:,specified_column] = (X[:, specified_column] - X_mean) / (X_std + 1e-8)
return X, X_mean, X_std
方法一 —— 梯度下降
使用小批量梯度下降法,通过计算其梯度和损失对w和b计算,与作业一相类似,区别在于最后要连接一个激活函数,以及损失函数的计算采用交叉熵。
激活函数
def _sigmoid(z):
# Sigmoid function can be used to calculate probability.
# To avoid overflow, minimum/maximum output value is set.
return np.clip(1 / (1.0 + np.exp(-z)), 1e-8, 1 - (1e-8))
def _f(X, w, b):
# This is the logistic regression function, parameterized by w and b
#
# Arguements:
# X: input data, shape = [batch_size, data_dimension]
# w: weight vector, shape = [data_dimension, ]
# b: bias, scalar
# Output:
# predicted probability of ea
损失函数
def _cross_entropy_loss(y_pred, Y_label):
# This function computes the cross entropy.
#
# Arguements:
# y_pred: probabilistic predictions, float vector
# Y_label: ground truth labels, bool vector
# Output:
# cross entropy, scalar
cross_entropy = -np.dot(Y_label, np.log(y_pred)) - np.dot((1 - Y_label), np.log(1 - y_pred))
return cross_entropy
方法二——生成模型
generative model 又叫生成概率模型,它先假设数据的概率分布,然后用概率公式去计算x所属于的类型的概率。通俗点理解,我们假设数据的分布符合某一种分布(例如高斯分布),我们需要的是把这种分布找出来,计算他的概率公式,使概率最大的公式就是我们需要的模型。
假设x为正向情况
C
1
C_{1}
C1的概率为
P
(
C
1
∣
x
)
P(C_{1}|x)
P(C1∣x)。而x是正向情况的数据集。那么
P
(
C
1
∣
x
)
P(C_{1}|x)
P(C1∣x)就要尽可能接近1。
假设数据服从高斯分布时,对应的公式如下:
P ( C 1 ∣ x ) = σ ( z ) P(C_{1}|x)=\sigma(z) P(C1∣x)=σ(z)
z = ( μ 1 − μ 2 ) T Σ − 1 x − 1 2 ( μ 1 ) T ( Σ 1 ) − 1 μ 1 + 1 2 ( μ 2 ) T ( Σ 2 ) − 1 μ 2 + l n N 1 N 2 z=(\mu^1-\mu^2)^T\Sigma^{-1}x-\frac{1}{2}(\mu^1)^T(\Sigma^{1})^{-1}\mu^1+\frac{1}{2}(\mu^2)^T(\Sigma^{2})^{-1}\mu^2+ln\frac{N_{1}}{N_{2}} z=(μ1−μ2)TΣ−1x−21(μ1)T(Σ1)−1μ1+21(μ2)T(Σ2)−1μ2+lnN2N1
μ 1 和 μ 2 \mu^1和\mu^2 μ1和μ2表示两类的均值。
( μ 1 − μ 2 ) T Σ − 1 (\mu^1-\mu^2)^T\Sigma^{-1} (μ1−μ2)TΣ−1 作为 w, − 1 2 ( μ 1 ) T ( Σ 1 ) − 1 μ 1 + 1 2 ( μ 2 ) T ( Σ 2 ) − 1 μ 2 + l n N 1 N 2 -\frac{1}{2}(\mu^1)^T(\Sigma^{1})^{-1}\mu^1+\frac{1}{2}(\mu^2)^T(\Sigma^{2})^{-1}\mu^2+ln\frac{N_{1}}{N_{2}} −21(μ1)T(Σ1)−1μ1+21(μ2)T(Σ2)−1μ2+lnN2N1 作为***b*** ,就转化成了线性的逻辑回归。那么带入公式计算即可。
对应的代码:
u, s, v = np.linalg.svd(cov, full_matrices=False)
inv = np.matmul(v.T * 1 / s, u.T)
# Directly compute weights and bias
w = np.dot(inv, mean_0 - mean_1)
b = (-0.5) * np.dot(mean_0, np.dot(inv, mean_0)) + 0.5 * np.dot(mean_1, np.dot(inv, mean_1))\
+ np.log(float(X_train_0.shape[0]) / X_train_1.shape[0])