偏差和方差
偏差
定义:期望值和观察值之间的差距,衡量的是准确性。
解决高偏差的方法:
- 尝试获得更多的特征,从数据入手,进行特征交叉,或者特征的embedding化。
- 尝试增加多项式特征。
- 从模型入手,增加更多线性及非线性变化,提高模型的复杂度。
- 尝试减少正则化程度 λ \lambda λ。
方差
期望值和观察值之间的波动程度,衡量的是稳定性。
解决高方差的方法:
- 在模型复杂程度不变的情况下,增加更多数据,不一定有效。
- 在数据量不变的情况下,减少特征维度,不一定有效。
- 在数据和模型都不变的情况下,加入正则化,基本有效。
样本不均衡问题
后果
假设正:负=1:100,则如果不对负样本进行处理,则模型学出来的规律是有偏的,因为即便是把所有的样本都预测成负样本,模型的准召依然很高,但是效果很差。
解决方案
weighted_logloss:加重对正样本预测为负样本的惩罚力度。
L
=
∑
i
[
w
i
y
i
l
o
g
(
p
i
)
+
(
1
−
y
i
)
l
o
g
(
1
−
p
i
)
]
L = \sum_i [w_i y_i log(p_i) + (1-y_i) log(1-p_i)]
L=i∑[wiyilog(pi)+(1−yi)log(1−pi)]
过采样:正样本多采一些。
降采样:负样本少采一些。
SMOTE:制造一些新的正样本。
值得注意的是,采样前后会对原始数据的分布进行改变,可能导致泛化能力大大下降。采样有一定概率会造成过拟合,当原始数据过少而采样量又很大时,造成大量数据被重复,造成模型训练的结果有一定的过拟合。
异常点识别
定义:训练数据中常常有离群异常点,这些异常点会造成模型在学习过程中被带偏。
检测方法:
- 3 σ \sigma σ检测方法检测某一个具体取值是否为异常点:离群异常点的取值在 [ μ − 3 σ , μ + 3 σ ] [\mu-3\sigma, \mu+3\sigma] [μ−3σ,μ+3σ]范围之外。
- 卡方检验检测某一维特征是否为异常特征:看 ∑ i ( o i − e i ) 2 e i \sum_i \frac{(o_i-e_i)^2}{e_i} ∑iei(oi−ei)2是否偏离置信区间,其中 e i e_i ei为这维特征的均值。
- 箱状图判定:从箱状图中检测异常点。
- 孤立森林:后续补充…
异常点处理方法:
- 视为缺失值:将异常值视为缺失值,利用缺失值处理的方法进行处理。
- 平均值修正:可用前后两个观测值的平均值修正该异常值。
- 直接删除。
LR模型tf代码demo
import tensorflow as tf
import numpy as np
# hyper param
learning_rate = 0.001
n_features = 20
w1_output_dim = 10
n_class = 1
total_size = 100
batch_size = 10
epoch = 5
# input init
x = tf.placeholder(tf.float32, shape=[None, n_features])
y = tf.placeholder(tf.float32, shape=[None, n_class])
# initializer
w_initializer = tf.truncated_normal_initializer(mean=0.0, stddev=0.01, dtype=tf.float32)
b_initializer = tf.constant_initializer(value=1, dtype=tf.float32)
# weight init
w1 = tf.get_variable(name="w1", shape=[n_features, w1_output_dim], dtype=tf.float32, initializer=w_initializer)
b1 = tf.get_variable(name="b1", shape=[w1_output_dim], dtype=tf.float32, initializer=b_initializer)
w2 = tf.get_variable(name="w2", shape=[w1_output_dim, n_class], dtype=tf.float32, initializer=w_initializer)
b2 = tf.get_variable(name="b2", shape=[n_class], dtype=tf.float32, initializer=b_initializer)
# matrix multiply
o1 = tf.matmul(x, w1) + b1
o2 = tf.matmul(o1, w2) + b2
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=o2))
opt = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(loss)
init = tf.initialize_all_variables()
# data
x_data = np.random.rand(total_size, n_features)
y_data = np.random.randint(0, 2, size=(total_size, n_class))
def get_data():
indices = np.arange(0, total_size)
start = 0
count = 0
while count < epoch:
np.random.shuffle(indices)
start = 0
while start < total_size:
selected_indices = indices[start: start + batch_size]
x_data_batch = x_data[selected_indices]
y_data_batch = y_data[selected_indices]
start += batch_size
yield x_data_batch, y_data_batch
count += 1
sess = tf.Session()
sess.run(init)
for x_data_batch, y_data_batch in get_data():
feed_dict = {
x: x_data_batch,
y: y_data_batch
}
opt_run, loss_run = sess.run([opt, loss], feed_dict=feed_dict)
print(loss_run)
缺失值
处理方法:
- 均值
- 中位数
- 众数
缺失值是否一定要处理:否,如果缺失值比例过高,则需要把这一维特征抛弃。
特征选择
利用方差进行特征选择
移出方差小的特征,这些特征具体取值变化较小,不具代表性。
利用相关性进行特征选择
- 皮尔逊系数: ρ x , y = c o v ( x , y ) ρ x ρ y \rho_{x,y}=\frac{cov(x,y)}{\rho_x\rho_y} ρx,y=ρxρycov(x,y)。
- 熵检验:KL散度(相对熵)。
数据变换
数据变换原因:
- 避免异常点:比如对连续变量进行份桶离散化。
- 使得原始数据的信息量更大:比如log/sqrt变换。
归一化(min_max)和标准化(z-score)的区别:
- min_max只是去量纲的过程,数据分布可能会变;z-score变换不会导致分布变化,但z-score的假设是原始数据大致服从高斯分布。
- 特征数据上下限明显异常的时候使用z-score,min_max会造成数据差异模糊,整体方差下降。
常见特征变换方法:
- min_max
- z_score
- log
- sqrt
- exp
- 特征交叉:FM or FFM
TF-IDF
TF:在一个文本内,一个单词对于一个文本的重要性,
T
F
=
n
d
,
t
∑
k
n
d
,
k
TF=\frac{n_{d,t}}{\sum_kn_{d,k}}
TF=∑knd,knd,t,其中
n
d
,
t
n_{d,t}
nd,t代表的是单词
t
t
t在文档
d
d
d中出现的频次。
IDF:在文本粒度下一个单词对于整个语料库的重要性,
I
D
F
=
1
+
l
o
g
∣
D
∣
d
f
t
IDF=1+log\frac{|D|}{df_t}
IDF=1+logdft∣D∣,其中
∣
D
∣
|D|
∣D∣代表的是语料库中文本个数,
d
f
t
df_t
dft代表的是单词
t
t
t以文本为单位在语料库出现的次数。
TF-IDF:在语料内,一个单词对于一个文本的重要性:
T
F
−
I
D
F
=
T
F
×
I
D
F
TF-IDF=TF \times IDF
TF−IDF=TF×IDF。