regression

1
from ulab import regression

这个库增添了Ridge以及相关的实用函数。

1 Ridge

1
class Ridge(alpha=1.0,fit_interception=True)

Ridge 回归通过对系数大小施加惩罚来解决普通最小二乘法的一些问题。alpha值越大,收缩量越大,因此系数对共线性变得更加鲁棒。alpha 必须是非负浮点数,取值范围 [0, inf) 。当 alpha = 0 时,目标相当于普通最小二乘法,当特征矩阵奇异时,函数会报错。

fit_interception参数决定了是否添加截距项。如果设置为False,则在计算中不会使用截距(即预计会居中),默认为True

methods

fit

1
def fit(self, X: ndarray, y: ndarray) -> None

拟合岭回归模型。

predict

1
def predict(self, X: ndarray) -> ndarray

使用线性模型进行预测。返回预测结果。

get_sse

1
def get_sse(self, X: ndarray,y: ndarray) -> float

计算残差平方和SSE。公式:

get_sst

1
def get_sst(self, y: ndarray) -> float

计算总离差平方和SST。公式:

get_r2score

1
def get_r2score(self, X: ndarray,y: ndarray) -> float

计算决定系数。公式:

get_t_val

1
def get_t_val(self, X: ndarray,y: ndarray) -> (list, ndarray)

根据Xy和拟合参数self.coef_计算t检验值。它表示拟合参数的显著性水平。

在OLS模型下,我们假设拟合参数服从正态分布,因此,对其标准化,服从标准正态分布由于,但未知,因此我们使用无偏估计值代替,因此可以构造t统计量:可以证明,其服从自由度为的t分布,其中分母又称为标准误差SE。

代码实现中,原假设,因此分子只有,它为OLS的估计值,即的第个元素值。

即为,即残差平方和除以自由度。对角线的列元素值。

函数返回对应参数的t统计量值列表和SE。

函数一定要在fit后使用,否则self.coef_None,则会报错。

1
2
3
>>> ridge = regression.Ridge(alpha=1, fit_intercept=False)
>>> ridge.fit(X, y)
>>> t_val,se = ridge.get_t_val(X,y)

Attributes

coef_

1
Ridge.coef_

权重向量。

intercept_

1
Ridge.intercept_

截距项,如果设置fit_interception=False,则永远为0

tools

1
from ulab import tools

这个模块增加了ulab下numpy缺少的实用函数。

1 fillnan

1
def fillnan(arr: ndarray, num: Union[int, float]) -> None

将数组arr中的nan替换为num,原地修改。

2 isnan

1
def isnan(arr: ndarray, axis: int=0, method: str=None) -> ndarray

检查输入数组arr元素是否为nan。返回一个bool类型的数组,其中True代表对应元素为nanFalse代表对应元素不为nan

其中,axis可选,若不填则默认为0,与method配合使用。method可选,只能为any或者all

当同时传入axismethod时,会按照对应的axismethod指定的方法进行聚合,见下面的示例2。

示例1:

1
2
3
4
5
6
7
8
9
10
>>> arr
array([[1.0, nan, 2.0],
[nan, 3.0, 4.0],
[nan, 3.0, 4.0],
[1.0, nan, 2.0]], dtype=float32)
>>> tools.isnan(arr)
array([[False, True, False],
[True, False, False],
[True, False, False],
[False, True, False]], dtype=bool)

示例2:

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> arr
array([[1.0, nan, 2.0],
[1.0, nan, 2.0],
[1.0, nan, 2.0],
[1.0, nan, 2.0]], dtype=float32)
>>> tools.isnan(arr,axis=0,method="any")
array([True, True, True, True], dtype=bool)
>>> tools.isnan(arr,axis=0,method="all")
array([False, False, False, False], dtype=bool)
>>> tools.isnan(arr,axis=1,method="any")
array([False, True, False], dtype=bool)
>>> tools.isnan(arr,axis=1,method="all")
array([False, True, False], dtype=bool)

3 sum_ignore_nan

1
def sum_ignore_nan(arr: ndarray, axis: int=0) -> ndarray

忽略arr中的nan值进行求和。axis默认为0,表示按列方向求和,axis=1表示按行方向求和

示例1:

1
2
3
4
5
6
7
8
9
>>> arr
array([[1.0, nan, 2.0],
[1.0, nan, 2.0],
[1.0, nan, 2.0],
[1.0, nan, 2.0]], dtype=float32)
>>> tools.sum_ignore_nan(arr,0)
array([4.0, 0.0, 8.0], dtype=float32)
>>> tools.sum_ignore_nan(arr,1)
array([3.0, 3.0, 3.0, 3.0], dtype=float32)

4 t_pdf

1
def t_pdf(x: float, df: float) -> float

计算t分布的概率密度,给定x,范围为(-inf,x)df为自由度。

1
2
>>> ulab.tools.t_pdf(-4,2)
0.01309457

5 t_cdf

1
def t_cdf(x: float, df: float) -> float

计算t分布的累积分布函数,给定x,范围为(-inf,x)df为自由度。

6 t_sf

1
def t_sf(x: float, df: float) -> float

计算t分布的生存函数(定义为 1 - cdf ),给定x,范围为(-inf,x)df为自由度。

7 corr

1
def corr(arr: ndarray) -> ndarray

皮尔逊相关性系数(Pearson correlation coefficient,PCC)是衡量两组数据之间线性相关性的相关系数。它是两个变量的协方差与其标准差的乘积之间的比率。因此,它本质上是协方差的归一化测量,使得结果始终介于 -1 和 1 之间。与协方差本身一样,该测量只能反映变量的线性相关性,而无法体现许多其他类型的关系或相关性。

对于总体,皮尔逊相关系数通常由希腊字母 ρ (rho) 表示,并称为总体相关系数或总体皮尔逊相关系数。给定一对随机变量,计算公式为:其中,是协方差,的标准差,的标准差。也可以用均值和期望来表示:因此,相关性计算公式可以改为:其中的均值,的均值,是数学期望。

对于样本,皮尔逊相关系数通常用表示,称为样本相关系数或样本皮尔逊相关系数。通过将基于样本的协方差和方差的估计值代入上面的公式中,我们可以得到的公式。给定由对组成的配对数据定义为:

其中:

  • 是样本数量
  • 是样本中索引为的第对样本
  • ,为样本的均值,同理

在具体代码计算的实现上与上述公式略有不同。本实现参考了pandas中的corr函数实现,参考其内部源码,

1
correl = libalgos.nancorr(mat, minp=min_periods)

其使用的libalgos.nancorr方法支持样本中存在nan值的计算。

8 nan_missrate

1
def nan_missrate(arr: ndarray, axis=0) -> ndarray

根据axis计算arr的缺失率,缺失率定义为:当前行or列中nan的数量/总数据量

1
2
3
4
5
6
7
8
9
>>> arr
array([[1.0, nan, 2.0],
[1.0, nan, 2.0],
[1.0, nan, 2.0],
[1.0, nan, 2.0]], dtype=float32)
>>> tools.nan_missrate(arr,axis=1)
array([0.0, 1.0, 0.0], dtype=float32)
>>> tools.nan_missrate(arr,axis=0)
array([0.3333333, 0.3333333, 0.3333333, 0.3333333], dtype=float32)

cluster

1
from ulab import cluster

添加了聚类相关功能。

1 AgglomerativeClustering

1
mdl = cluster.AgglomerativeClustering()

该类实现了scikit-learn中对应类的子集。

methods

fit

1
def fit(self, corr: ndarray) -> None

拟合模型,目前仅支持precomputed,即传入计算好的距离矩阵进行聚类。

Attributes

labels_

1
mdl.labels_

每个点的聚类标签。

children_

1
mdl.children_

每个非叶节点的子节点矩阵,shape:(n_samples -1 ,2)。小于 n_samples 的值对应于作为原始样本的树的叶子。大于或等于 n_samples 的节点 i 是非叶节点,并且具有子节点 children_[i - n_samples]

其中:

  • children_[:, 0]:左子树标签
  • children_[:, 1]:右子树标签

distances_

1
mdl.distances_

对应节点间距离。

Z_

1
mdl.Z_

聚类结果矩阵,shape:(n_samples - 1,4)

其中:

  • Z_[:, 0]:左子树标签
  • Z_[:, 1]:右子树标签
  • Z_[:, 2]:distance
  • Z_[:, 3]:子树节点数量

n_features_in_

1
mdl.n_features_in_

拟合过程中看到的特征数量。

n_leaves_

1
mdl.n_leaves_

树中的叶子节点数量。

2 fcluster

1
def fcluster(Z: ndarray, threshold: float, criterion: str = "distance") -> ndarray

根据阈值threshold切分Z,具体参考:scipy.cluster.hierarchy.fcluster

1
2
3
4
5
6
7
8
9
10
11
12
Z = np.array([[0., 1., 1., 2.],
[3., 4., 1., 2.],
[9., 10., 1., 2.],
[6., 7., 1., 2.],
[2., 12., 1.11803399, 3.],
[5., 13., 1.11803399, 3.],
[8., 15., 1.11803399, 3.],
[11., 14., 1.11803399, 3.],
[18., 19., 3., 6.],
[16., 17., 3.5, 6.],
[20., 21., 3.25, 12.]])
T = cluster.fcluster(Z,3, criterion='distance')

3 leaders

1
def leaders(Z: ndarray, T: ndarray, n: int) -> (ndarray, ndarray)

返回层次聚类中的非叶节点。参考:scipy.cluster.hierarchy.leaders,与其不同的是,需要额外传入n,为T中子簇的数量。

1
2
3
4
5
6
7
8
9
10
11
12
13
Z = np.array([[0., 1., 1., 2.],
[3., 4., 1., 2.],
[9., 10., 1., 2.],
[6., 7., 1., 2.],
[2., 12., 1.11803399, 3.],
[5., 13., 1.11803399, 3.],
[8., 15., 1.11803399, 3.],
[11., 14., 1.11803399, 3.],
[18., 19., 3., 6.],
[16., 17., 3.5, 6.],
[20., 21., 3.25, 12.]])
T = cluster.fcluster(Z,3, criterion='distance')
res1 = cluster.leaders(Z, T,len(set(T)))

4 maxdists

1
def maxdists(Z: ndarray) -> ndarray

返回任何非单簇之间的最大距离。参考:scipy.cluster.hierarchy.maxdists

1
2
3
4
5
6
7
8
9
10
11
12
Z = np.array([[0., 1., 1., 2.],
[3., 4., 1., 2.],
[9., 10., 1., 2.],
[6., 7., 1., 2.],
[2., 12., 1.11803399, 3.],
[5., 13., 1.11803399, 3.],
[8., 15., 1.11803399, 3.],
[11., 14., 1.11803399, 3.],
[18., 19., 3., 6.],
[16., 17., 3.5, 6.],
[20., 21., 3.25, 12.]])
res = cluster.maxdists(Z)