如何解决从数据集中过滤非“同类群组”
我确信这个话题之前已经被研究过,我不确定它叫什么名字,或者我也应该研究什么技术,所以我为什么要在这里。我主要在Python和Pandas中运行此程序,但不仅限于那些语言/技术。
作为一个例子,让我们假设我有这个数据集:
| PID | A | B | C |
| --- | ---- | ---- | ---- |
| 508 | 0.85 | 0.51 | 0.05 |
| 400 | 0.97 | 0.61 | 0.30 |
| 251 | 0.01 | 0.97 | 0.29 |
| 414 | 0.25 | 0.04 | 0.83 |
| 706 | 0.37 | 0.32 | 0.33 |
| 65 | 0.78 | 0.62 | 0.25 |
| 533 | 0.24 | 0.15 | 0.88 |
PID是该行的唯一ID。 A,B和C是一些因素(在此示例中已标准化)。该数据集可以是历史上某个体育联赛中的运动员,也可以是库存中的产品,也可以是选民数据。具体的上下文并不重要。
现在让我们说一些输入数据:
| A | B | C |
| ---- | ---- | ---- |
| 0.81 | 0.75 | 0.17 |
此输入与原始数据集(A,B,C)共享相同的因子。我要做的是找到与输入数据(“同类群组”)相似的行。解决此问题的最佳方法是什么?
我想到了使用kNN算法进行聚类的方法,但问题是未设置同类群组的数量。您可能有唯一的输入,而很少/没有“同类”,或者您可能有非常普遍的输入,并有数百个“同类”。
我接下来尝试的解决方案是欧氏距离。因此,对于此数据集和输入,我将执行以下操作:
my_cols = ['A','B','C']
inputdata = pd.Series([0.81,0.75,0.17],index=['A','C'])
# df = pandas data frame with above data
df['Dict'] = (df[my_cols] - inputdata).pow(2).sum(1).pow(0.5)
这将在数据集上创建一个新列,例如:
| PID | A | B | C | Dist |
| --- | ---- | ---- | ---- | ---- |
| 508 | 0.85 | 0.51 | 0.05 | 0.27 |
| 400 | 0.97 | 0.61 | 0.30 | 0.25 |
| 251 | 0.01 | 0.97 | 0.29 | 0.84 |
| 414 | 0.25 | 0.04 | 0.83 | 1.12 |
| 706 | 0.37 | 0.32 | 0.33 | 0.63 |
| 65 | 0.78 | 0.62 | 0.25 | 0.16 |
| 533 | 0.24 | 0.15 | 0.88 | 1.09 |
然后您可以“过滤”出低于某个阈值的那些行。
cohorts = df[df['Dist'] <= THRESHOLD]
然后问题变成(1)您如何确定最佳阈值? (2)如果我在数据集和Euclid计算中添加第4个因子(“ D”),似乎“破坏”了结果,因为队列不再具有直观的意义,而是看结果。
所以我的问题是:过滤/选择“同类群组”(类似于输入行的那些行)的技术或更好的方法是什么?
谢谢
解决方法
这是我通过逻辑思维和一些基本统计得出的算法。它使用值的mean
和输入数据的平均值,使用pd.merge_asof
根据standard deviation
查找最接近的匹配项:
factors = ['A','B','C']
df = df.assign(avg=df[factors].mean(axis=1)).sort_values('avg')
input_data = input_data.assign(avg=input_data[factors].mean(axis=1)).sort_values('avg')
dfn = pd.merge_asof(
df,input_data,on='avg',direction='nearest',tolerance=df['avg'].std()
)
PID A_x B_x C_x avg A_y B_y C_y
0 706 0.37 0.32 0.33 0.340000 NaN NaN NaN
1 414 0.25 0.04 0.83 0.373333 NaN NaN NaN
2 251 0.01 0.97 0.29 0.423333 NaN NaN NaN
3 533 0.24 0.15 0.88 0.423333 NaN NaN NaN
4 508 0.85 0.51 0.05 0.470000 NaN NaN NaN
5 65 0.78 0.62 0.25 0.550000 0.81 0.75 0.17
6 400 0.97 0.61 0.30 0.626667 0.81 0.75 0.17
,
您正面临聚类问题,因此您的K均值直觉是正确的。
集群
但是,正如您提到的,K均值是一种参数化方法,因此您需要确定正确的K。有一种自动方法可以找到关于簇质量(形状,稳定性,同质性)的最佳K,这被称为弯头。方法:https://www.scikit-yb.org/en/latest/api/cluster/elbow.html
然后,您可以使用另一种聚类方法(实际上,正确的聚类算法取决于功能的含义),例如,您可以在DBSCAN(https://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html)中使用基于密度的方法。
因此,您需要根据问题确定最佳的聚类算法:https://machinelearningmastery.com/clustering-algorithms-with-python/
使用该解决方案,您可以将聚类算法适合您的训练集(您将其命名为“同类群组”),并使用该模型预测“非同类”样本上的聚类。
统计队列
在某些领域(如市场营销领域),您还将找到基于某些数字属性并使用描述性统计信息创建聚类(群组)的方法。
最好的示例是 RFM分段方法,这是一种非常聪明的进行聚类的方法,同时可以保持对结果聚类的高清晰度:https://towardsdatascience.com/know-your-customers-with-rfm-9f88f09433bc
使用这种方法,您将在整个数据集上构建要素,然后根据要素值获取结果分段。
,我的理解是,您希望与各列的距离被独立考虑,但要在最终结果中一起收集。
要获得独立的会计核算,您可以使用其standard deviation σ(whimsical set of explanations)来找出衡量列中成员差异的方法。
要一起收集最终结果,可以迭代过滤数据框,删除所需范围之外的行。这样也可以连续减少处理时间,尽管除非您有大量数据,否则它可以忽略不计。
如果添加第四列导致没有足够的数据接近,则可能表明
- 您的测试数据确实与任何源数据都不接近,并且是唯一的条目
- 您的数据不是正态分布的(如果有更多数据可用,您可以使用
scikit.stats.normaltest
进行测试) - 您的列不是独立的(即需要更专业的统计处理)
如果是第二种或第三种,则不应使用标准的标准偏差,而应使用另一种分布的标准偏差(list和more tests)
但是,如果您的数据看似随机,则可以在每列中应用标准偏差的某些因子和/或功效(即方差)来获得或多或少的准确结果。
初始数据帧
starting data (df)
PID A B C
508.0 0.85 0.51 0.05
400.0 0.97 0.61 0.3
251.0 0.01 0.97 0.29
414.0 0.25 0.04 0.83
706.0 0.37 0.32 0.33
65.0 0.78 0.62 0.25
533.0 0.24 0.15 0.88
test data (test_data)
A B C
0 0.81 0.75 0.17
df.std()
找出每列的标准偏差并将其收集到新的数据框中
然后用这个组装另一个数据框
stdv = df.std()
PID
A 0.367145
B 0.316965
C 0.312219
test_df = pd.DataFrame()
test_df = test_df.append(test_data - stdv)
test_df = test_df.append(test_data + stdv)
test_df.index = ["low","high"]
test_df
A B C
low 0.442855 0.433035 -0.142219
high 1.177145 1.066965 0.482219
结果
在各列上重复,过滤掉所需范围之外的那些列(pandas Series.between()
可以为您完成!)
for x in df:
df = df[df[x].between(test_df[x]["low"],test_df[x]["high"])]
resulting df
PID A B C
508.0 0.85 0.51 0.05
400.0 0.97 0.61 0.3
65.0 0.78 0.62 0.25
,
由于您实际上并不知道群集(群组)的数量或它们的结构,因此我相信OPTICS算法最适合您。它找到一组堆积在一起的点(使用欧几里得距离),并展开以从中建立聚类。然后,很容易找到一个新点所属的集群。它与DBSCAN类似,但是没有假设簇之间的密度相似。 sklearn
库包括OPTICS的实现。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。