在python中选择特征
Posted
技术标签:
【中文标题】在python中选择特征【英文标题】:Selecting features in python 【发布时间】:2020-11-15 08:57:30 【问题描述】:我正在尝试做这个算法http://venom.cs.utsa.edu/dmz/techrep/2007/CS-TR-2007-011.pdf
import pandas as pd
import pathlib
import gaitrec
from tsfresh import extract_features
from collections import defaultdict
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from sklearn.metrics.pairwise import euclidean_distances
class PFA(object):
def __init__(self, n_features, q=None):
self.q = q
self.n_features = n_features
def fit(self, X):
if not self.q:
self.q = X.shape[1]
pca = PCA(n_components=self.q).fit(X)
A_q = pca.components_.T
kmeans = KMeans(n_clusters=self.n_features).fit(A_q)
clusters = kmeans.predict(A_q)
cluster_centers = kmeans.cluster_centers_
dists = defaultdict(list)
for i, c in enumerate(clusters):
dist = euclidean_distances(A_q[i, :].reshape(1,-1), cluster_centers[c, :].reshape(1,-1))[0][0]
dists[c].append((i, dist))
self.indices_ = [sorted(f, key=lambda x: x[1])[0][0] for f in dists.values()]
self.features_ = X[:, self.indices_]
p = pathlib.Path(gaitrec.__file__).parent
dataset_file = p / 'DatasetC' / 'subj_001' / 'walk0' / 'subj_0010.csv'
read_csv = pd.read_csv(dataset_file, sep=';', decimal='.', names=['time','x','y', 'z', 'id'])
read_csv['id'] = 0
if __name__ == '__main__':
print(read_csv)
extracted_features = extract_features(read_csv, column_id="id", column_sort="time")
features_withno_nanvalues = extracted_features.dropna(how='all', axis=1)
print(features_withno_nanvalues)
X = features_withno_nanvalues.to_numpy()
pfa = PFA(n_features=2274, q=1)
pfa.fit(X)
Y = pfa.features_
print(Y) #feature extracted
column_indices = pfa.indices_ #index of the features
print(column_indices)
C:\Users\Thund\AppData\Local\Programs\Python\Python37\python.exe C:/Users/Thund/Desktop/RepoBitbucket/Gaitrec/gaitrec/extraction.py
time x y z id
0 0 -0.833333 0.416667 -0.041667 0
1 1 -0.833333 0.416667 -0.041667 0
2 2 -0.833333 0.416667 -0.041667 0
3 3 -0.833333 0.416667 -0.041667 0
4 4 -0.833333 0.416667 -0.041667 0
... ... ... ... ... ..
1337 1337 -0.833333 0.416667 0.083333 0
1338 1338 -0.833333 0.416667 0.083333 0
1339 1339 -0.916667 0.416667 0.083333 0
1340 1340 -0.958333 0.416667 0.083333 0
1341 1341 -0.958333 0.416667 0.083333 0
[1342 rows x 5 columns]
Feature Extraction: 100%|██████████| 3/3 [00:04<00:00, 1.46s/it]
C:\Users\Thund\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\decomposition\_pca.py:461: RuntimeWarning: invalid value encountered in true_divide
explained_variance_ = (S ** 2) / (n_samples - 1)
variable x__abs_energy ... z__variation_coefficient
id ...
0 1430.496338 ... 5.521904
[1 rows x 2274 columns]
C:/Users/Thund/Desktop/RepoBitbucket/Gaitrec/gaitrec/extraction.py:21: ConvergenceWarning: Number of distinct clusters (2) found smaller than n_clusters (2274). Possibly due to duplicate points in X.
kmeans = KMeans(n_clusters=self.n_features).fit(A_q)
[[1430.49633789 66.95824 ]]
[0, 1]
Process finished with exit code 0
我不明白从 2k+ 特征中它只提取前 2 个的警告和原因,这就是我所做的:
-
根据原始数据生成协方差矩阵
使用 SVD 方法计算协方差矩阵的特征向量和特征值
这两个步骤结合起来就是所谓的 PCA。
主成分是原始数据的协方差矩阵的特征向量,然后应用K-means算法。
我的问题是:
-
如何解决它给我的警告?
它只从 2k+ 个特征中选择了 2 个特征,所以有问题吗?
【问题讨论】:
问题是什么? 我不明白警告以及从 2k+ 特征中提取前 2 个特征的原因 不确定警告,但看起来您只是从已使用 kmeans 聚类的特征中选择索引 - 并且 kmeans 已在 PCA 的输出上完成,这减少了数量的尺寸。我认为由于 A_q 的重塑(不确定),你得到了两个特征而不是 q 特征,但是矩阵的索引并不是指相同的东西,所以肯定应该改变。 self.features_ 应该可能来自 A_q @Elenchus 谢谢你的回答。我在欧几里得距离中实施重塑,因为我遇到了这个问题:dpaste.com/847AQ38PZ。 啊,是的,这绝对是为什么你得到 2 个特征而不是 1 个的原因。但是重塑不是真正的问题 - A_q 只会有与出现的维度一样多的特征来自 PCA。如果您想要更多功能,请增加 q。 2274 尺寸降至 1 是相当大的,所以可能会移除 reshape 并将 q 限制为最小 2。但是拟合后的特征应该来自A_q,而不是X 【参考方案1】:如 cmets 中所述,拟合后的特征来自 A_q 矩阵的索引,该矩阵的 PCA 特征数量减少。由于重塑,您将获得两个特征而不是 q 个特征(在本例中为 1 个)。 self.features_ 应该来自 A_q 而不是 X。
【讨论】:
【参考方案2】:我认为您代码中的问题出在以下语句中:
pfa = PFA(n_features=2274, q=1)
我没有读过论文,但你必须观察pca
的行为。如果作者将 q
变量设置为 1,您应该会明白为什么 q
是 1。
例如:
from matplotlib.pyplot import plot
from matplotlib.pyplot import xlabel
from matplotlib.pyplot import ylabel
from matplotlib.pyplot import figure
pca_obj = PCA().fit(X=X)
figure(1, figsize=(6,3), dpi=300)
plot(pca_obj.explained_variance_, linewidth=2)
xlabel('Components')
ylabel('Explained Variaces')
注意:如果您使用的应用程序不是jupyter-notebook
,请在行尾添加show
,以防您看不到任何图表
from matplotlib.pyplot import plot
from matplotlib.pyplot import xlabel
from matplotlib.pyplot import ylabel
from matplotlib.pyplot import figure
from matplotlib.pyplot import show
pca_obj = PCA().fit(X=X)
figure(1, figsize=(6,3), dpi=300)
plot(pca_obj.explained_variance_, linewidth=2)
xlabel('Components')
ylabel('Explained Variaces')
show()
对于我的数据集,结果是:
现在,我可以说:“我的 q
变量是 100,因为 PCA 从 100 个组件开始表现更好。”
可以这样说吗?你怎么知道q
是1?
现在观察你最好的q
性能变量,看看它是否能解决你的问题。
【讨论】:
我还是不明白应该放多少组件。在我拥有的数组中,请记住“错误”给我的 PCA 是什么,行是组件(样本),在这种情况下,我的数据形成如下:每一行代表一次步行,列是步行的特点。因此,如果我将相同的行作为组件放置,则数组是相同的(可能 pca 根据方差对数组进行排序),如果我放置较少的组件,它可能会尝试对一些不太重要的特征求和并在输出中给出更少的数组行。 我的代码现在看起来像这样:dpaste.com/HKF8K5ZRN(我添加了更多示例)。当我的代码执行 kmeans 训练时,它会运行得很慢,并提取 2126 到 2289 个特征。例如,我如何理解它是否正确? (我正在尝试从 2289 个特征中选择一些相关的特征) 在使用PFA
之前,您需要创建一个pca
对象,即pca_obj = PCA()
。然后你需要将你的X
(data) 拟合到声明的pca
对象,即pca_obj.fit(X)
然后你需要绘制并查看合适数量的组件plot(pca_obj.explained_variance_, linewidth=2)
我没有看到使用您的代码打开的任何窗口(图形),为什么? pca_obj = PCA() pca_obj.fit(extracted_features) figure(1, figsize=(6, 3), dpi=300) plot(pca_obj.explained_variance_, linewidth=2)
我使用jupyter-notebook
得到了结果。如果您使用的是 PyCharm 或 Spyder 等 IDE,则可能需要添加 show()
函数。 show()
功能可以实现from matplotlib.pyplot import show
以上是关于在python中选择特征的主要内容,如果未能解决你的问题,请参考以下文章