numpy corrcoef来评估与y标注输出相关的最佳x或要素列

mpgws1up  于 2023-06-23  发布在  其他
关注(0)|答案(4)|浏览(117)

我尝试使用np.corrcoef来评估最好的特征x与标签y的比较。但我认为一定有更好的方法来做到这一点。corr数组看起来像--> [0.73117578 0.40620284 0.82562664],然后我选择索引2,这是我最好的特性。

data_x = np.array([[0.885, 0.330, 9.100],[0.725, 0.390, 10.900],[0.560, 0.500, 9.400],[0.735, 0.570, 9.800],[0.610, 0.630, 8.400],[0.260, 0.630, 11.800],[0.500, 0.680, 10.500],[0.320, 0.780, 10.000]])
data_y = np.array([4.000, 5.000, 6.000, 5.000, 3.000, 8.000, 7.000, 6.000])

corr = []
for i in range(0, len(data_y)):
    featureX = data_x[:, i].reshape(-1)
    matrix = np.corrcoef(featureX, data_y)
    corr.append(matrix[1, 0])

corr = np.array(corr)
corr = np.absolute(corr)
splitXi = np.argmax(corr)
splitXi = int(splitXi)
v8wbuo2f

v8wbuo2f1#

您的data_x将列作为特征,将行作为观测。因此,您可以使用np.transposerowvar=False作为np.corrcoef的参数。

data_x = np.array([[0.885, 0.330, 9.100],[0.725, 0.390, 10.900],[0.560, 0.500, 9.400],[0.735, 0.570, 9.800],[0.610, 0.630, 8.400],[0.260, 0.630, 11.800],[0.500, 0.680, 10.500],[0.320, 0.780, 10.000]])
data_y = np.array([4.000, 5.000, 6.000, 5.000, 3.000, 8.000, 7.000, 6.000])

corr = np.abs(np.corrcoef(data_x, data_y, rowvar=False)[-1, :-1])
corr
>>> array([0.73117578, 0.40620284, 0.82562664])

splitXi = int(np.argmax(corr))
splitXi
>>> 2
vwoqyblh

vwoqyblh2#

在我看来,你似乎在寻找 * 特性的重要性 *,而不是相关性(如果我错了,请纠正我)。
找出特征重要性的一种方法是使用RandomForestRegressor

import numpy as np
from sklearn.ensemble import RandomForestRegressor 

data_x = np.array([[0.885, 0.330, 9.100],[0.725, 0.390, 10.900],[0.560, 0.500, 9.400],[0.735, 0.570, 9.800],[0.610, 0.630, 8.400],[0.260, 0.630, 11.800],[0.500, 0.680, 10.500],[0.320, 0.780, 10.000]])
data_y = np.array([4.000, 5.000, 6.000, 5.000, 3.000, 8.000, 7.000, 6.000])

rfr = RandomForestRegressor(n_estimators=1000, random_state=2452354).fit(data_x, data_y)
print(rfr.feature_importances_) # [0.48855445 0.12778678 0.38365877]
lstz6jyr

lstz6jyr3#

特征1为负且强相关(-0.73)特征2为正且弱相关(.40)特征3为正且强相关(.82%)
corrcoef检查来自线的斜率的方差。与线的斜率的距离的变化越小,与数据特征的相关性或线拟合越高。

data_x = np.array([
[0.885, 0.330, 9.100],
[0.725, 0.390, 10.900],
[0.560, 0.500, 9.400],
[0.735, 0.570, 9.800],
[0.610, 0.630, 8.400],
[0.260, 0.630, 11.800],
[0.500, 0.680, 10.500],
[0.320, 0.780, 10.000]])
data_y = np.array([4.000, 5.000, 6.000, 5.000, 3.000, 8.000, 7.000, 6.000])

data=np.concatenate((data_x,data_y[:,None]),axis=1)

#print(data[:,0:3])
#print(data[:,3])
#correlation = np.corrcoef(data[:,0], data[:,3],rowvar=False)[0,1]
#correlation = np.corrcoef(data[:,1], data[:,3],rowvar=False)[0,1]
#correlation = np.corrcoef(data[:,2], data[:,3],rowvar=False)[0,1]
correlation = np.corrcoef(data[:,0:3], data[:,3],rowvar=False)[0,1]

print(correlation)

def combine_data(data_x, data_y):
    data_dict = {}
    for i in range(len(data_x)):
        data_dict[i] = [data_x[i], data_y[i]]
    return data_dict

def sort_data(data_dict):
    sorted_data = sorted(data_dict.items(), key=lambda x: x[1][1])
    return sorted_data

data_dict = combine_data(data_x, data_y)
sorted_data = sort_data(data_dict)

for i in range(len(sorted_data)):
    plt.scatter(sorted_data[i][1][0][0], sorted_data[i][1][0][1], c='b')
plt.show()
for i in range(len(sorted_data)):        
    plt.scatter(sorted_data[i][1][0][1], sorted_data[i][1][0][1], c='r')
plt.show()
for i in range(len(sorted_data)):        
    plt.scatter(sorted_data[i][1][0][2], sorted_data[i][1][0][1], c='g')
plt.show()

如果您正在寻找功能重要性

from sklearn.ensemble import ExtraTreesClassifier

 forest = ExtraTreesClassifier(n_estimators=250, random_state=0)
 forest.fit(data_x, data_y)
 importances = forest.feature_importances_
 std = np.std([tree.feature_importances_ for tree in 
 forest.estimators_],axis=0)
 indices = np.argsort(importances)[::-1]

 print("Feature ranking:")
 for f in range(data_x.shape[1]):
     print("%d. feature %d (%f)" % (f + 1, indices[f], 
     importances[indices[f]]))

输出

features 0 is highest ranking

 Feature ranking:
 1. feature 0 (0.339678)
 2. feature 2 (0.334904)
 3. feature 1 (0.325418)
5anewei6

5anewei64#

编辑:
在这种情况下,您可以自己实现相关性,以便在速度和内存占用方面做得更好:

def corrwith(X, y, rowvar=True):
    X = np.asarray(X)
    if not rowvar:
        X = X.T
    y = np.asarray(y)
    a = np.mean(X * y, axis=1) - np.mean(X, axis=1) * np.mean(y)
    b1 = np.sqrt(np.mean(np.square(X), axis=1) - np.square(np.mean(X, axis=1)))
    b2 = np.sqrt(np.mean(np.square(y)) - np.square(np.mean(y)))
    return a / (b1 * b2)

示例:

corr = corrwith(data_x, data_y, rowvar=False)

针对pandas.corrwith进行测试(下面的“pandas方法”)
原文回答:

已接受答案的澄清

首先我想解释一下为什么armamut's answer可以工作。np.corrcoef(data_x, data_y, rowvar=False)等价于np.corrcoef(np.concatenate([data_x, data_y[:, np.newaxis]], axis=1), rowvar=False),其中索引(i, j)处的返回值对应于data_x的第i列和第j列之间的相关系数。因此,切片[-1, :-1]意味着找到最后一列data_y与除最后一列之外的所有列data_x之间的相关性。

替代方式

显然,有两种方法可以找到相关性:一个使用numpy.corrcoef,另一个使用pandas.DataFrame.corrwith,即:

corr = np.corrcoef(data_x, data_y, rowvar=False)[-1, :-1]

和/或

import pandas as pd
corr = pd.DataFrame(data_x).corrwith(pd.Series(data_y)).to_numpy()

Profiling

使用Python timeit模块进行性能分析,以确定哪种方法最好。分析代码为:

from timeit import timeit
from pathlib import Path

import numpy as np
import pandas as pd
from tqdm import tqdm
from matplotlib import pyplot as plt

setup = '''\
import numpy as np
import pandas as pd
X = np.random.randn(100, {})
y = np.random.randn(100)
'''

def test_match():
    X = np.random.randn(100, 10)
    y = np.random.randn(100)
    c1 = np.corrcoef(X, y, rowvar=False)[-1, :-1]
    c2 = pd.DataFrame(X).corrwith(pd.Series(y)).to_numpy()
    assert c1.shape == c2.shape
    assert np.allclose(c1, c2)

def time_np(n_var):
    k = max(1, 20000 // n_var)
    return timeit(
        '_ = np.corrcoef(X, y, rowvar=False)[-1, :-1]',
        setup.format(n_var),
        number=k) / k

def time_pd(n_var):
    k = max(1, 20000 // n_var)
    return timeit(
        '_ = pd.DataFrame(X).corrwith(pd.Series(y)).to_numpy()',
        setup.format(n_var),
        number=k) / k

def main():
    n_vars = np.array([1, 10, 100, 1000, 10000, 20000])
    np_times = np.array([time_np(n) for n in tqdm(n_vars, desc='np')])
    pd_times = np.array([time_pd(n) for n in tqdm(n_vars, desc='pd')])
    fig, ax = plt.subplots()
    ax.plot(n_vars, np.log10(np_times), '^-', label='numpy method')
    ax.plot(n_vars, np.log10(pd_times), 's-', label='pandas method')
    ax.set_xlabel('# of variables')
    ax.set_ylabel('log10 of seconds consumed')
    ax.legend()
    ax.grid()
    fig.savefig(Path.home() / 'Downloads' / 'prof.jpg')
    plt.close(fig)

if __name__ == '__main__':
    main()

分析结果的图为:

根据结果,当功能不是那么多时,使用numpy比使用pandas要好得多。然而,随着特征数量的增加,性能的差异逐渐减小。在某些时候,使用pandas会比使用numpy更快。
numpy的另一个关键问题是内存消耗是$O(n^2)$,其中$n$是特征的数量。这意味着,至少在我的计算机上,50000个特征的相关矩阵将无法装入内存,因此numpy方法肯定会失败。

总结

如果没有那么多的特性,坚持使用numpy方法。否则,考虑首先使用corrwith将数组转换为pandas DataFrame和Series,最后转换回numpy数组。

相关问题