【发布时间】:2021-04-16 14:34:02
【问题描述】:
我正在制定一种用于二进制分类中的特征选择的算法,该算法通过np.array 或pd.series 以贪婪的方法找到具有良好目标划分的区间。
代码运行良好,但是我使用for 循环和if 条件,因此性能很慢。我想知道是否有更聪明(更快)的方法来做到这一点。我的代码如下所示:
import pandas as pd
df = pd.DataFrame([[51, 35, 1], [52, 3, 1], [53, 11, 1], [61, 8, 0], [75, 23, 0], [83, 45, 0], [95, 56, 1], [13, 66, 1], [1, 0, 1], [22, 68, 1]], columns=['feat1', 'feat2', 'target'])
target = df['target'] # values range from 0 to 1
def my_generic_metric_function(y):
#This is just a generic metric that I'm using as an example.
if len(y)>0:
tgt = sum(y==1)
no_tgt = sum(y==0)
return 1.0*tgt/1.0*(no_tgt+tgt)
else:
return 0
def find_intervals(x, min_metric=10):
## Important: all my features receive a treatment that "fits" them in a range from 0 to 100
## Note that I'm not iterating through the DataFrame, I'm iterating over a range of values and finding the partitions in the dataframe.
print(x.name)
steps = [0]
metric_partition = []
for i in range(0, 101):
## This the target series filtered by the interval in x value
band = target[(x>steps[-1]) & (x<=i)]
partition_metric = my_generic_metric_function(band)
if partition_metric >= min_metric:
steps.append(i)
metric_partition.append(partition_metric)
return {'f':x.name,'s': steps, 'm':metric_partition}
我会使用 .apply() 将此函数应用于整个数据框:
bi_df = df.drop("target", axis=1).apply(find_intervals)
这个问题看起来很像 CART 算法,但是我没有找到任何可以帮助我优化问题的实现。
【问题讨论】:
-
这是RandomForest的某种实现吗?
-
虽然对于贪婪的 CART 算法非常相似,但我实际上正在构建一个针对线性模型的 特征选择 和 分类 算法(我希望主要用于逻辑回归)。
-
my_generic_function 函数的用途是什么?它有一些错误。
-
这个想法是用这个指标来评估剪辑的质量,我用这个指标只是作为一个例子。如果某个时间间隔的此指标高于阈值(在此示例中为 1.2),则它将来自迭代器的当前
i值附加到steps列表和metric_partition列表中的通用指标值以评估下一个可能的时间间隔.我使用的真实指标稍微复杂一些,并且计算它不会耗费大量时间,所以我只是用“通用”函数替换了这个真实指标。 -
当我按原样运行时,我得到一个
KeyError: '[1 0 0 0 1 1 1 1] not found in axis'。似乎应将应用行调整为:bi_df = df.drop("target", axis=1).apply(find_intervals)。但随后它在return tgt / (no_tgt + tgt)上返回ZeroDivisionError: division by zero。你能确认一下吗?
标签: python pandas for-loop optimization