【问题标题】:Any alternatives to speeding up brute force 'tally' algorithm?加速蛮力“统计”算法的任何替代方法?
【发布时间】:2019-12-05 01:22:08
【问题描述】:

如果发布此问题的位置有误,请提前道歉。如果有更好的堆栈交换站点,请告诉我。

因此,目前正在开发一种犯罪预测算法,该算法基本上在城市上空放置一个网格,并预测每个网格条目在接下来的 30 天内是否会成为热点(至少发生一起袭击犯罪)。

我目前使用的是纳什维尔市,网格覆盖有 3446 个网格。我有一个网格数据集,其中包含显示网格所需的所有数据、每个网格的地图坐标以及它周围的相邻网格(底部的邻居、右侧的邻居……等等)

以下是预测的示例:

在这种情况下,绿色表示正确的预测。红色表示假阴性,紫色表示机器学习算法的假阳性。

为了训练我的神经网络,我使用了如下所示的特征集:

这里的 Hotspot 是目标值(1 和 0)。周、月、年是从去年(上周、上个月和去年发生的犯罪)中提取的犯罪事件的犯罪统计。我的问题是创建这些功能集需要大量时间(脚本需要 6 多个小时)

#Loop through each grid in the dataset
for grid_index, grid_row in grid.iterrows():
    print("On grid number: ", grid_row['id'])
    near=0
    #Loop through all of the crimes 
    for crime_index, crime_row in crime.iterrows():

        #Parse out the month, day, and year
        date = crime_row['Incident Occurred']
        date_pars = date.split('/')
        month = int(date_pars[0])
        day= int(date_pars[1])
        year =int(date_pars[2].split(' ')[0])

        if grid_row['top '] == crime_row['grid']:
            near +=1
        if grid_row['bottom '] == crime_row['grid']:
            near +=1
        if grid_row['left '] == crime_row['grid']:
            near +=1
        if grid_row['right '] == crime_row['grid']:
            near +=1
        if grid_row['topleft'] == crime_row['grid']:
            near +=1
        if grid_row['topright'] == crime_row['grid']:
            near +=1
        if grid_row['bottomright'] == crime_row['grid']:
            near +=1
        if grid_row['bottomleft'] == crime_row['grid']:
            near +=1

        if month == 12 and grid_row['id'] == crime_row['grid']:
            countMonth = countMonth+1
        if day >= 25 and month == 12 and grid_row['id'] == crime_row['grid']:
            countWeek = countWeek + 1

        if  year == 2017 and grid_row['id'] == crime_row['grid']:
            countYear=countYear+1

    #Update the output for the specific grid
    output = output.append({'Grid': grid_row['id'], 'Hotspot': 0, 'week': countWeek, 'month': 
    countMonth, 'year': countYear,'near': near}, ignore_index=True)
    countMonth = 0
    countYear = 0
    countWeek = 0

目前,此代码循环遍历每个网格(总共 3446 个),并在每个网格内循环遍历每个犯罪(大约 18,000 个)计算计数并将其附加到 pandas 数据帧...3446*18000 大约是 6200 万次计算创建此数据集。我觉得这不会花太长时间,但理想情况下需要更长的时间。

关于如何有效加快速度的任何想法?我需要在过去三年的每个月运行这个算法,所以每次运行时间超过 5 小时,运行 36 次对于我的时间限制来说太长了。

提前感谢您提供任何见解。

编辑:澄清“grid_row”是网格 CSV 文件中的每条记录,我在上面发布了列(每个网格和相邻网格的位置),“crime_row”是去年发生的每起犯罪事件:

【问题讨论】:

  • 似乎对于每个网格,您都遍历了每个 crime_row...您应该描述什么是 crime_row 及其与 grid_row 的关系(例如,为什么它们是相同的它们是某个对象??) .您还应该考虑提供一个非常小的数据集和您的复制脚本
  • 可以将这些单独的 if 语句(来自 grid_row[top],bottom, ......, [bottomleft])链接为 if-else 构造吗?我想这样做不会影响您的要求。对于 countMonth、countWeek 和 countYear,将条件 grid_row['id'] == crime_row['grid'] 作为第一个检查,因为它的限制性更强。或者,可能是,它可以是检查 grid_row['id'] == crime_row['grid'] 的高级 'IF' 语句,然后是 countMonth、countWeek 和 countYear 的三个内部 IF 语句.希望对性能有所帮助。
  • @user753642 是的,我正在遍历地图上的每个网格,并且对于每个网格,我都在统计该特定网格在上周、上个月和去年发生的犯罪数量。 Crime_row 是去年在整个纳什维尔市发生的每一宗单独的犯罪事件。我在上面添加了犯罪记录的示例。
  • 我想我误解了,所以请纠正我:每个犯罪都有一个“网格编号”,那么您为什么要针对每个网格单元查找每个犯罪?扫描犯罪列表,为每个犯罪获取网格编号,更新您要保留的计数器,转到下一个犯罪,...
  • “在每个网格中,它循环遍历每个犯罪(大约 18,000 个)”我不明白。是否有 18k 类型 犯罪,并且您正在为每个网格计算这些犯罪发生的频率,或者这 18k 中的每一个是否对应于一个实际的犯罪实例?在那种情况下,犯罪可以在多个网格单元中吗?你可以只创建一个地图{crime_id: grid_id} 而不是一个 CRIMExGRID 表吗?

标签: python algorithm performance machine-learning counting


【解决方案1】:

你做事的方式可以简化为

forall grid
  forall crimes
    if crime.cell == grid.cell
      do something

复杂度是O(|grid| * |crimes|)

如果你有 3k 个犯罪和 5k 个网格,这将是 15e6 次迭代

更好的方法是遍历犯罪并将它们中的任何一个推送到其关联的网格,将具有相同 grid_index 的所有犯罪堆叠到...相同的位置

gridIdxToCrimes = {} // to a grid_index you associate all the crimes

for crime_row in crime.iterrows():
  grid_index = crime_row['grid']
  if grid_index not in gridIdxToCrimes:
    gridIdxToCrimes[grid_index] = []
  gridIdxToCrimes[grid_index].push(crime_row)

forall grid_index, grid_row in grid.iterrows():
  topIndex = grid_row['top ']
  if topIndex in gridIdxToCrimes:
    # you get all the crimes above your current grid
    near += count(gridIdxToCrimes[topIndex])

这样你做了 O(|crimes|+|grid|) = 5k 次迭代

【讨论】:

  • 是的,这就是我正在寻找的东西......我知道这将是一个像数据结构这样的字典来跟踪和省去嵌套循环。我将尽快实施这个想法并回复您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 2015-06-22
  • 2015-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-04
相关资源
最近更新 更多