机器学习:均值漂移(Mean Shift)详细解释

2023-11-11

1. 均值漂移的基本概念

Mean Shift算法和k-means相似,都是一个迭代的过程,即先算出当前点的偏移均值,将该点移动到该偏移均值,以此为新的起始点,继续移动,直到满足最终的条件。
(1)设想在一个有N个样本点的特征空间,初始确定一个中心点center;
(2)计算在设置的半径为D的圆形空间内所有的点(xi)与中心点center的向量;
(3)计算整个圆形空间内所有向量的平均值,得到一个偏移均值
(4)将中心点center移动到偏移均值位置;
(5)重复移动,直到满足一定条件结束。
在这里插入图片描述

2. 均值漂移计算

2.1 实施步骤

1、在未被分类的数据点中随机选择一个点作为中心点;
2、找出离中心点距离在带宽之内的所有点,记做集合M,认为这些点属于簇c。
3、计算从中心点开始到集合M中每个元素的向量,将这些向量相加,得到偏移向量。
4、中心点沿着shift的方向移动,移动距离是偏移向量的模。
5、重复步骤2、3、4,直到偏移向量的大小满足设定的阈值要求,记住此时的中心点。
6、重复1、2、3、4、5直到所有的点都被归类。
7、分类:根据每个类,对每个点的访问频率,取访问频率最大的那个类,作为当前点集的所属类。

2.2 第一种方法:Mean Shift基础公式

偏移均值(中心点减去每个样本点,然后求和,除以点的个数得到):
在这里插入图片描述
这里的S(h)是一个以x为中心点,半径为h的高维球区域,满足以下等式关系的y点的集合,
上面等式中的k值表示在这n个样本点x(i)中,有k个点落入S(h)区域,在上式中,我们可以看到(x(i) - x)是样本x(i)相对于点x的偏移向量,上面式子做的就是落入区域S(h)中的k个样本点相对于点x偏移向量求和然后再平均,那么如果样本点x(i)从一个概率密度函数f(x)中采样得到,由于非零的概率密度梯度指向概率密度增大的最大的方向,
因此从平均上来说,S(h)的样本点更多的是落在沿着概率密度梯度的方向,因此,对应的,
Mean Shift向量M(x)应该指向概率密度梯度的方向。
在这里插入图片描述
如上图所示,大圆圈所圈住的是S区域,小圆圈表示落入S区域的样本点x(i), 黑色的点就是Mean Shift的
基准点x
,箭头表示样本点相对于基准点x的偏移向量,很明显我们可以看出,平均的偏移M(x)会指向样本分布最多的区域,也就是概率密度函数梯度的方向。
注:在上面式子中看到,只要是落入S区域的采样点,无论其离中心点x的远近,对最终M(x)的计算的贡献是一样的。然而在这个迭代的过程中,每个x(i)对于求解均值时的贡献是不同的,所以这里引入了其他类型的核函数。

中心点更新,将中心点移动到偏移均值位置
在这里插入图片描述
Mt为t状态下求得的偏移均值; xt为t状态下的中心

下面讲引入高斯核函数的方式。

2.3 第二种方法:引入核函数改进Mean Shift算法

核函数的定义:
在Mean Shift算法中引入核函数的目的是使得随着样本与被偏移点的距离的不同,其偏移量对均值偏移向量的贡献也不同,下面看下核函数的定义:
在这里插入图片描述
在这里插入图片描述
核函数也叫窗口函数,在核估计中起到平滑的作用。

高斯核函数:
高斯核函数只是用来计算映射到高维空间之后的内积的一种简便方法,目的为让低维的不可分数据变成高维可分。利用核函数,可以忽略映射关系,直接在低维空间中完成计算。

引入高斯核函数的偏移均值
在均值漂移中引入核函数的概念,能够使计算中距离中心的点具有更大的权值,反映距离越短,权值越大的特性。改进的偏移均值如下:
在这里插入图片描述
在这里插入图片描述
把mh代入Mh则可以得到下列公式,正好印证了梯度上升的过程:
在这里插入图片描述
其中,x为中心点;xi为带宽范围内的点;n为带宽范围内的点的数量;g(x)为对核函数的导数求负。

高斯核函数如下公式所示:
在这里插入图片描述
式子中的H如下面这个矩阵。
在这里插入图片描述

3. 均值漂移的应用

Mean Shift算法在很多领域都有成功应用,例如图像平滑、图像分割、物体跟踪等,这些属于人工智能里面模式识别或计算机视觉的部分;另外也包括常规的聚类应用。

图像平滑:图像最大质量下的像素压缩;
图像分割:跟图像平滑类似的应用,但最终是将可以平滑的图像进行分离已达到前后景或固定物理分割的目的;
目标跟踪:例如针对监控视频中某个人物的动态跟踪;
常规聚类,如用户聚类等。聚类(K均值聚类)
对象轮廓检验(光线传播算法)

4. Python算法实现


import numpy as np
import matplotlib.pyplot as plt
# Input data set
X = np.array([
    [-4, -3.5], [-3.5, -5], [-2.7, -4.5],
    [-2, -4.5], [-2.9, -2.9], [-0.4, -4.5],
    [-1.4, -2.5], [-1.6, -2], [-1.5, -1.3],
    [-0.5, -2.1], [-0.6, -1], [0, -1.6],
    [-2.8, -1], [-2.4, -0.6], [-3.5, 0],
    [-0.2, 4], [0.9, 1.8], [1, 2.2],
    [1.1, 2.8], [1.1, 3.4], [1, 4.5],
    [1.8, 0.3], [2.2, 1.3], [2.9, 0],
    [2.7, 1.2], [3, 3], [3.4, 2.8],
    [3, 5], [5.4, 1.2], [6.3, 2]
])
 
def mean_shift(data, radius=2.0):
    clusters = []
    for i in range(len(data)):
        cluster_centroid = data[i]
        cluster_frequency = np.zeros(len(data))
 
        # Search points in circle
        while True:
            temp_data = []
            for j in range(len(data)):
                v = data[j]
                # Handle points in the circles
                if np.linalg.norm(v - cluster_centroid) <= radius:
                    temp_data.append(v)
                    cluster_frequency[i] += 1
 
            # Update centroid
            old_centroid = cluster_centroid
            new_centroid = np.average(temp_data, axis=0)
            cluster_centroid = new_centroid
            # Find the mode
            if np.array_equal(new_centroid, old_centroid):
                break
        # Combined 'same' clusters
        has_same_cluster = False
        for cluster in clusters:
            if np.linalg.norm(cluster['centroid'] - cluster_centroid) <= radius:
                has_same_cluster = True
                cluster['frequency'] = cluster['frequency'] + cluster_frequency
                break
        if not has_same_cluster:
            clusters.append({
                'centroid': cluster_centroid,
                'frequency': cluster_frequency
            })
    print('clusters (', len(clusters), '): ', clusters)
    clustering(data, clusters)
    show_clusters(clusters, radius)
 
# Clustering data using frequency
def clustering(data, clusters):
    t = []
    for cluster in clusters:
        cluster['data'] = []
        t.append(cluster['frequency'])
    t = np.array(t)
    # Clustering
    for i in range(len(data)):
        column_frequency = t[:, i]
        cluster_index = np.where(column_frequency == np.max(column_frequency))[0][0]
        clusters[cluster_index]['data'].append(data[i])
  
# Plot clusters
def show_clusters(clusters, radius):
    colors = 10 * ['r', 'g', 'b', 'k', 'y']
    plt.figure(figsize=(5, 5))
    plt.xlim((-8, 8))
    plt.ylim((-8, 8))
    plt.scatter(X[:, 0], X[:, 1], s=20)
    theta = np.linspace(0, 2 * np.pi, 800)
    for i in range(len(clusters)):
        cluster = clusters[i]
        data = np.array(cluster['data'])
        plt.scatter(data[:, 0], data[:, 1], color=colors[i], s=20)
        centroid = cluster['centroid']
        plt.scatter(centroid[0], centroid[1], color=colors[i], marker='x', s=30)
        x, y = np.cos(theta) * radius + centroid[0], np.sin(theta) * radius + centroid[1]
        plt.plot(x, y, linewidth=1, color=colors[i])
    plt.show()
 
mean_shift(X, 2.5)
import numpy as np
import math 

MIN_DISTANCE = 0.00001  # 最小误差
def euclidean_dist(pointA, pointB):
    # 计算pointA和pointB之间的欧式距离
    total = (pointA - pointB) * (pointA - pointB).T
    return math.sqrt(total)
def gaussian_kernel(distance, bandwidth):
    ''' 高斯核函数
    :param distance: 欧氏距离计算函数
    :param bandwidth: 核函数的带宽
    :return: 高斯函数值
    '''
    m = np.shape(distance)[0]  # 样本个数
    right = np.mat(np.zeros((m, 1)))
    for i in range(m):
        right[i, 0] = (-0.5 * distance[i] * distance[i].T) / (bandwidth * bandwidth)
        right[i, 0] = np.exp(right[i, 0])
    left = 1 / (bandwidth * math.sqrt(2 * math.pi))
    gaussian_val = left * right
    return gaussian_val

def shift_point(point, points, kernel_bandwidth):
    '''
    计算均值漂移点
    :param point: 需要计算的点
    :param points: 所有的样本点
    :param kernel_bandwidth: 核函数的带宽
    :return:
        point_shifted:漂移后的点
    '''
    points = np.mat(points)
    m = np.shape(points)[0]  # 样本个数
    # 计算距离
    point_distances = np.mat(np.zeros((m, 1)))
    for i in range(m):
        point_distances[i, 0] = euclidean_dist(point, points[i])
    # 计算高斯核
    point_weights = gaussian_kernel(point_distances, kernel_bandwidth)

    # 计算分母
    all = 0.0
    for i in range(m):
        all += point_weights[i, 0]
    # 均值偏移
    point_shifted = point_weights.T * points / all
    return point_shifted
def group_points(mean_shift_points):
    '''
    计算所属的类别
    :param mean_shift_points:漂移向量
    :return: group_assignment:所属类别
    '''
    group_assignment = []
    m, n = np.shape(mean_shift_points)
    index = 0
    index_dict = {}
    for i in range(m):
        item = []
        for j in range(n):
            item.append(str(("%5.2f" % mean_shift_points[i, j])))
        item_1 = "_".join(item)
        if item_1 not in index_dict:
            index_dict[item_1] = index
            index += 1
    for i in range(m):
        item = []
        for j in range(n):
            item.append(str(("%5.2f" % mean_shift_points[i, j])))
        item_1 = "_".join(item)
        group_assignment.append(index_dict[item_1])
    return group_assignment

def train_mean_shift(points, kernel_bandwidth=2):
    '''
    训练Mean Shift模型
    :param points: 特征数据
    :param kernel_bandwidth: 核函数带宽
    :return:
        points:特征点
        mean_shift_points:均值漂移点
        group:类别
    '''
    mean_shift_points = np.mat(points)
    max_min_dist = 1
    iteration = 0
    m = np.shape(mean_shift_points)[0]  # 样本的个数
    need_shift = [True] * m  # 标记是否需要漂移
    # 计算均值漂移向量
    while max_min_dist > MIN_DISTANCE:
        max_min_dist = 0
        iteration += 1
        print("iteration : " + str(iteration))
        for i in range(0, m):
            # 判断每一个样本点是否需要计算偏置均值
            if not need_shift[i]:
                continue
            p_new = mean_shift_points[i]
            p_new_start = p_new
            p_new = shift_point(p_new, points, kernel_bandwidth)  # 对样本点进行偏移
            dist = euclidean_dist(p_new, p_new_start) 
             # 计算该点与漂移后的点之间的距离
            if dist > max_min_dist:  # 记录是有点的最大距离
                max_min_dist = dist
            if dist < MIN_DISTANCE:  # 不需要移动
                need_shift[i] = False
            mean_shift_points[i] = p_new
    # 计算最终的group
    group = group_points(mean_shift_points) 
    # 计算所属的类别
    return np.mat(points), mean_shift_points, group

以上代码实现了基本的流程,但是执行效率很慢,正式使用时建议使用scikit-learn库中的MeanShift。
scikit-learn MeanShift演示:

import numpy as np
from sklearn.cluster import MeanShift, estimate_bandwidth

data = []
f = open("k_means_sample_data.txt", 'r')#换成自己的数据所在的路径
for line in f:
    data.append([float(line.split(',')[0]), float(line.split(',')[1])])
data = np.array(data)

# 通过下列代码可自动检测bandwidth值
# 从data中随机选取1000个样本,计算每一对样本的距离,然后选取这些距离的0.2分位数作为返回值,当n_samples很大时,这个函数的计算量是很大的。

bandwidth = estimate_bandwidth(data, quantile=0.2, n_samples=1000)
print(bandwidth)

# bin_seeding设置为True就不会把所有的点初始化为核心位置,从而加速算法

ms = MeanShift(bandwidth=bandwidth, bin_seeding=True)
ms.fit(data)
labels = ms.labels_
cluster_centers = ms.cluster_centers_

# 计算类别个数
labels_unique = np.unique(labels)
n_clusters = len(labels_unique)

print("number of estimated clusters : %d" % n_clusters)

# 画图
import matplotlib.pyplot as plt
from itertools import cycle
plt.figure(1)
plt.clf()  # 清楚上面的旧图形
# cycle把一个序列无限重复下去
colors = cycle('bgrcmyk')
for k, color in zip(range(n_clusters), colors):
    # current_member表示标签为k的记为true 反之false

    current_member = labels == k
    cluster_center = cluster_centers[k]

    # 画点
    plt.plot(data[current_member, 0], data[current_member, 1], color + '.')

    #画圈
    plt.plot(cluster_center[0], cluster_center[1], 'o',
             markerfacecolor=color,  #圈内颜色
             markeredgecolor='k',  #圈边颜色
             markersize=14)  #圈大小
plt.title('Estimated number of clusters: %d' % n_clusters)
plt.show()

scikit-learn MeanShift源码分析:

def mean_shift(X, bandwidth=None, seeds=None, bin_seeding=False,
               min_bin_freq=1, cluster_all=True, max_iter=300,
               n_jobs=1):

    """Perform mean shift clustering of data using a flat kernel.
    Read more in the :ref:`User Guide <mean_shift>`.
    Parameters
    ----------
    X : array-like, shape=[n_samples, n_features]
        Input data.
    bandwidth : float, optional
        Kernel bandwidth.
        If bandwidth is not given, it is determined using a heuristic based on
        the median of all pairwise distances. This will take quadratic time in
        the number of samples. The sklearn.cluster.estimate_bandwidth function
        can be used to do this more efficiently.
    seeds : array-like, shape=[n_seeds, n_features] or None
        Point used as initial kernel locations. If None and bin_seeding=False,
        each data point is used as a seed. If None and bin_seeding=True,
        see bin_seeding.
    bin_seeding : boolean, default=False
        If true, initial kernel locations are not locations of all
        points, but rather the location of the discretized version of
        points, where points are binned onto a grid whose coarseness
        corresponds to the bandwidth. Setting this option to True will speed
        up the algorithm because fewer seeds will be initialized.
        Ignored if seeds argument is not None.
    min_bin_freq : int, default=1
       To speed up the algorithm, accept only those bins with at least
       min_bin_freq points as seeds.
    cluster_all : boolean, default True
        If true, then all points are clustered, even those orphans that are
        not within any kernel. Orphans are assigned to the nearest kernel.
        If false, then orphans are given cluster label -1.
    max_iter : int, default 300
        Maximum number of iterations, per seed point before the clustering
        operation terminates (for that seed point), if has not converged yet.
    n_jobs : int
        The number of jobs to use for the computation. This works by computing
        each of the n_init runs in parallel.
        If -1 all CPUs are used. If 1 is given, no parallel computing code is
        used at all, which is useful for debugging. For n_jobs below -1,
        (n_cpus + 1 + n_jobs) are used. Thus for n_jobs = -2, all CPUs but one are used.
        .. versionadded:: 0.17
           Parallel Execution using *n_jobs*.
  Returns
    -------
    cluster_centers : array, shape=[n_clusters, n_features]
        Coordinates of cluster centers.
    labels : array, shape=[n_samples]
        Cluster labels for each point.
    Notes
    -----
    See examples/cluster/plot_mean_shift.py for an example.
    """
    #没有定义bandwidth执行函数estimate_bandwidth估计带宽
    if bandwidth is None:
        bandwidth = estimate_bandwidth(X, n_jobs=n_jobs)
    #带宽小于0就报错
    elif bandwidth <= 0:
        raise ValueError("bandwidth needs to be greater than zero or None,\got %f" % bandwidth)
    #如果没有设置种子
    if seeds is None:
        #通过get_bin_seeds选取种子
        #min_bin_freq指定最少的种子数目
        if bin_seeding:
            seeds = get_bin_seeds(X, bandwidth, min_bin_freq)
        #把所有点设为种子
        else:
            seeds = X
    #根据shape得到样本数量和特征数量
    n_samples, n_features = X.shape
    #中心强度字典 键为点 值为强度
    center_intensity_dict = {}
    #近邻搜索 fit的返回值为
    #radius意思是半径 表示参数空间的范围
    #用作于radius_neighbors 可以理解为在半径范围内找邻居
    nbrs = NearestNeighbors(radius=bandwidth, n_jobs=n_jobs).fit(X)
    #并行地在所有种子上执行迭代
    #all_res为所有种子的迭代完的中心以及周围的邻居数
    # execute iterations on all seeds in parallel
    all_res = Parallel(n_jobs=n_jobs)(
        delayed(_mean_shift_single_seed)
        (seed, X, nbrs, max_iter) for seed in seeds)
    #遍历所有结果
    # copy results in a dictionary
    for i in range(len(seeds)):
        #只有这个点的周围没有邻居才会出现None的情况
        if all_res[i] is not None:
            #一个中心点对应一个强度(周围邻居个数)
            center_intensity_dict[all_res[i][0]] = all_res[i][1]
    #要是一个符合要求的点都没有,就说明bandwidth设置得太小了
    if not center_intensity_dict:
        # nothing near seeds
        raise ValueError("No point was within bandwidth=%f of any seed."
                         " Try a different seeding strategy \
                         or increase the bandwidth."
                         % bandwidth)
    # POST PROCESSING: remove near duplicate points
    # If the distance between two kernels is less than the bandwidth,
    # then we have to remove one because it is a duplicate. Remove the
    # one with fewer points.
    #按照强度来排序
    #dict.items()返回值形式为[(key1,value1),(key2,value2)...]
    #reverse为True表示由大到小
    #key的lambda表达式用来指定用作比较的部分为value
    sorted_by_intensity = sorted(center_intensity_dict.items(),
                                 key=lambda tup: tup[1], reverse=True)
    #单独把排好序的点分出来
    sorted_centers = np.array([tup[0] for tup in sorted_by_intensity])
    #返回长度和点数量相等的bool类型array
    unique = np.ones(len(sorted_centers), dtype=np.bool)
    #在这些点里再来一次找邻居
    nbrs = NearestNeighbors(radius=bandwidth,                          n_jobs=n_jobs).fit(sorted_centers)
    '''
    enumerate返回的是index,value
    还是类似于之前的找邻居 不过这次是为了剔除相近的点 就是去除重复的中心,因为是按强度由大到小排好序的 所以优先将靠前的当作确定的中心
    '''
    for i, center in enumerate(sorted_centers):
        if unique[i]:
            neighbor_idxs = nbrs.radius_neighbors([center],                                                  return_distance=False)[0]
            #中心的邻居不能作为候选
            unique[neighbor_idxs] = 0
            #因为这个范围内肯定包含自己,所以要单独标为1
            unique[i] = 1  
            # leave the current point as unique    
            #把筛选过后的中心拿出来 就是最终的聚类中心
    cluster_centers = sorted_centers[unique]
    '''
    分配标签:最近的类就是这个点的类
    ASSIGN LABELS: a point belongs to the cluster that it is closest to
    把中心放进去 用kneighbors来找邻居
    n_neighbors标为1 使找到的邻居数为1 也就成了标签
    '''
    nbrs = NearestNeighbors(n_neighbors=1, n_jobs=n_jobs).fit(cluster_centers)
    #labels用来存放标签
    labels = np.zeros(n_samples, dtype=np.int)
    #所有点带进去求
    distances, idxs = nbrs.kneighbors(X)
    #cluster_all为True表示所有的点都会被聚类
    if cluster_all:
        #flatten可以简单理解如下
        #>>> np.array([[[[1,2]],[[3,4]],[[5,6]]]]).flatten()
        #array([1, 2, 3, 4, 5, 6])
        
        labels = idxs.flatten()
    #为False就把距离大于bandwidth的点类别标为-1
    else:
        #先全标-1
        labels.fill(-1)
        #距离小于bandwidth的标False
        bool_selector = distances.flatten() <= bandwidth
        #标True的才能参与聚类

        labels[bool_selector] = idxs.flatten()[bool_selector]
    #返回的结果为聚类中心和每个样本的标签
    return cluster_centers, labels
# separate function for each seed's iterative loop
def _mean_shift_single_seed(my_mean, X, nbrs, max_iter):
    #对于每个种子,梯度上升,直到收敛或者到达max_iter次迭代次数
    # For each seed, climb gradient until convergence or max_iter
    bandwidth = nbrs.get_params()['radius']
    #表示收敛时的阈值
    stop_thresh = 1e-3 * bandwidth  # when mean has converged
    #记录完成的迭代次数
    completed_iterations = 0
    while True:
        '''
        radius_neighbors寻找my_mean周围的邻居
        i_nbrs是符合要求的邻居的下标
        Find mean of points within bandwidth
        '''
        i_nbrs = nbrs.radius_neighbors([my_mean], bandwidth,                                       return_distance=False)[0]
        #根据下标找点
        points_within = X[i_nbrs]
        #找不到点就跳出迭代
        if len(points_within) == 0:
            break  # Depending on seeding strategy this condition may occur
        #保存旧的均值
        my_old_mean = my_mean  # save the old mean
        #移动均值,这就是mean-shift名字的由来,每一步的迭代就是计算新的均值点
        my_mean = np.mean(points_within, axis=0)
        '''
        用欧几里得范数与阈值进行比较判断收敛 或者
        判断迭代次数达到上限
        If converged or at max_iter, adds the cluster
        '''
        if (extmath.norm(my_mean - my_old_mean) < stop_thresh or
                completed_iterations == max_iter):
            #返回收敛时的均值中心和周围邻居个数
            #tuple表示转换成元组 因为之后的center_intensity_dict键不能为列表

            return tuple(my_mean), len(points_within)
        #迭代次数增加
        completed_iterations += 1

参考文献

  1. 均值漂移运算
  2. 均值漂移计算
  3. https://blog.csdn.net/jiaoyangdetian/article/details/79426078
  4. 算法实现-源码地址
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

机器学习:均值漂移(Mean Shift)详细解释 的相关文章

  • Python:在列表理解本身中引用列表理解?

    这个想法刚刚出现在我的脑海中 假设您出于某种原因想要通过 Python 中的列表理解来获取列表的唯一元素 i if i in created comprehension else 0 for i in 1 2 1 2 3 1 2 0 0 3
  • 使用 psycopg2 在 python 中执行查询时出现“编程错误:语法错误位于或附近”

    我正在运行 Python v 2 7 和 psycopg2 v 2 5 我有一个 postgresql 数据库函数 它将 SQL 查询作为文本字段返回 我使用以下代码来调用该函数并从文本字段中提取查询 cur2 execute SELECT
  • 没有名为 crypto.cipher 的模块

    我现在正在尝试加密一段时间 我最近得到了这个基于 python 的密码器 名为PythonCrypter https github com jbertman PythonCrypter 我对 Python 相当陌生 当我尝试通过终端打开 C
  • 如何在flask中使用g.user全局

    据我了解 Flask 中的 g 变量 它应该为我提供一个全局位置来存储数据 例如登录后保存当前用户 它是否正确 我希望我的导航在登录后在整个网站上显示我的用户名 我的观点包含 from Flask import g among other
  • 使用 matplotlib 绘制时间序列数据并仅在年初显示年份

    rcParams date autoformatter month b n Y 我正在使用 matpltolib 来绘制时间序列 如果我按上述方式设置 rcParams 则生成的图会在每个刻度处标记月份名称和年份 我怎样才能将其设置为仅在每
  • 使用 on_bad_lines 将 pandas.read_csv 中的无效行写入文件

    我有一个 CSV 文件 我正在使用 Python 来解析该文件 我发现文件中的某些行具有不同的列数 001 Snow Jon 19801201 002 Crom Jake 19920103 003 Wise Frank 19880303 l
  • 是否可以忽略一行的pyright检查?

    我需要忽略一行的pyright 检查 有什么特别的评论吗 def create slog group SLogGroup data Optional dict None SLog insert one SLog group group da
  • 基于代理的模拟:性能问题:Python vs NetLogo & Repast

    我正在 Python 3 中复制一小段 Sugarscape 代理模拟模型 我发现我的代码的性能比 NetLogo 慢约 3 倍 这可能是我的代码的问题 还是Python的固有限制 显然 这只是代码的一个片段 但 Python 却花费了三分
  • 以编程方式停止Python脚本的执行? [复制]

    这个问题在这里已经有答案了 是否可以使用命令在任意行停止执行 python 脚本 Like some code quit quit at this point some more code that s not executed sys e
  • Python pickle:腌制对象不等于源对象

    我认为这是预期的行为 但想检查一下 也许找出原因 因为我所做的研究结果是空白 我有一个函数可以提取数据 创建自定义类的新实例 然后将其附加到列表中 该类仅包含变量 然后 我使用协议 2 作为二进制文件将该列表腌制到文件中 稍后我重新运行脚本
  • OpenCV 无法从 MacBook Pro iSight 捕获

    几天后 我无法再从 opencv 应用程序内部打开我的 iSight 相机 cap cv2 VideoCapture 0 返回 并且cap isOpened 回报true 然而 cap grab 刚刚返回false 有任何想法吗 示例代码
  • AWS EMR Spark Python 日志记录

    我正在 AWS EMR 上运行一个非常简单的 Spark 作业 但似乎无法从我的脚本中获取任何日志输出 我尝试过打印到 stderr from pyspark import SparkContext import sys if name m
  • IO 密集型任务中的 Python 多线程

    建议仅在 IO 密集型任务中使用 Python 多线程 因为 Python 有一个全局解释器锁 GIL 只允许一个线程持有 Python 解释器的控制权 然而 多线程对于 IO 密集型操作有意义吗 https stackoverflow c
  • Jupyter Notebook 内核一直很忙

    我已经安装了 anaconda 并且 python 在 Spyder IPython 等中工作正常 但是我无法运行 python 笔记本 内核被创建 它也连接 但它始终显示黑圈忙碌符号 防火墙或防病毒软件没有问题 我尝试过禁用两者 我也无法
  • 如何在Python中对类别进行加权随机抽样

    给定一个元组列表 其中每个元组都包含一个概率和一个项目 我想根据其概率对项目进行采样 例如 给出列表 3 a 4 b 3 c 我想在 40 的时间内对 b 进行采样 在 python 中执行此操作的规范方法是什么 我查看了 random 模
  • 为字典中的一个键附加多个值[重复]

    这个问题在这里已经有答案了 我是 python 新手 我有每年的年份和值列表 我想要做的是检查字典中是否已存在该年份 如果存在 则将该值附加到特定键的值列表中 例如 我有一个年份列表 并且每年都有一个值 2010 2 2009 4 1989
  • 解释 Python 中的数字范围

    在 Pylons Web 应用程序中 我需要获取一个字符串 例如 关于如何做到这一点有什么建议吗 我是 Python 新手 我还没有找到任何可以帮助解决此类问题的东西 该列表将是 1 2 3 45 46 48 49 50 51 77 使用
  • 使用其构造函数初始化 OrderedDict 以便保留初始数据的顺序的正确方法?

    初始化有序字典 OD 以使其保留初始数据的顺序的正确方法是什么 from collections import OrderedDict Obviously wrong because regular dict loses order d O
  • Rocket UniData/UniVerse:ODBC 无法分配足够的内存

    每当我尝试使用pyodbc连接到 Rocket UniData UniVerse 数据时我不断遇到错误 pyodbc Error 00000 00000 Rocket U2 U2ODBC 0302810 Unable to allocate
  • Python Selenium:如何在文本文件中打印网站上的值?

    我正在尝试编写一个脚本 该脚本将从 tulsaspca org 网站获取以下 6 个值并将其打印在 txt 文件中 最终输出应该是 905 4896 7105 23194 1004 42000 放置的动物 的 HTML span class

随机推荐

  • 万能密码学习

    select userid from cms users where username 用户名 and password md5 密码 如上 如果知道用户名 注入类型为字符型使用admin and 1 1 即可完成绕过验证 数字型省去闭合即
  • build.gradle详解

    简述 1 gt java开发中有两个大名鼎鼎的项目构建ANT Maven 2 gt Google推荐使用的Android Studio是采用Gradle来构建项目的 Gradle是一个非常先进的项目构建工具 Gradle是用了一种基于Gro
  • 性能测试的基本流程

    本文主要介绍下性能测试的基本流程 性能测试从实际执行层面来看 测试的过程一般分为这么几个阶段 如下图 下面分别介绍下每个阶段具体需要做什么 一 性能需求分析 性能需求分析是整个性能测试工作开展的基础 如果连性能的需求都没弄清楚 后面的性能测
  • 数据库中存储过程、函数、触发器的区别

    存储过程 函数 触发器的区别 比较项目 存储过程 函数 是否有返回值 可以有 也可以没有 必须有且只有一个 是否可以单独执行 可以 必须通过execute执行 SQL语句 DML或SELECT 可否调用 不可以 可以 且可以位于FROM关键
  • MySQL导入frm文件

    前几天我心爱的Windows Server 2003系统忽然崩溃里面装的东西全完了 还好我是装双系统的 还能有个系统用用 在恢复过程中试了很多办法都不行哦 后来去百度搜索一下 mysql导入frm文件 终于找到办法了 现在把这些记在这里 以
  • python获取文件后缀名及批量更新目录下文件后缀名的方法

    coding utf 8 import os 获取文件后缀名称 dict 存放文件后缀名 path r E test for dirpath dirnames filenames in os walk path for filename i
  • QT容器详解

    QString类 隐式共享 隐式数据共享机制去最大化资源有效利用和最小化复制克隆操作 隐式数据共享类当作为函数参数传递的时候 不仅安全而且效率很高 因为传递的时候只是传递了数据的指针 数据本身只当自己被修改的时候才会去复制 简称写时复制 数
  • vue引入vue-jsonp实现解决跨域(例:在项目里调用百度api/腾讯api获取定位)

    第一步 添加依赖npm install vue jsonp save 第二步 在vue cli项目main js中添加 import VueJsonp from vue jsonp 网上很多博客引用不加 会报错 Vue use VueJso
  • 基于STL的演讲流程管理系统

    完整项目代码已上传gitCode 地址 https gitcode net m0 46663240 stl 1 system pause 按任意键之后才会执行下一步 system cls 清屏 2 vector 清空函数 clear 3 s
  • 各类学习资料(网址)汇总~

    移动开发设计 英文 http davidbcalhoun com 2010 viewport metatag 伯乐论坛http blog jobbole com 这里面的东西感觉好有难度 保存起来再看 什么是响应式网站设计 http www
  • 区块链体系架构

    区块链技术经过多年的发展 它们在实现上各有不同 但是在整体架构上是大体上相同的 区块链平台整体上可以划分为网络层 共识层 数据层 智能合约层以及应用层五个部分 一 网络层 区块链平台通常选择完全分布式且可容忍单点故障的P2P协议作为网络传输
  • Mysql load data local命令详解

    1 load data local命令使用方法 不指定字段名 此写法数据文件内字段数必须跟数据库表一致 load data local infile C test txt into table tableName CHARACTER SET
  • python Elasticsearch update

    备注 如果更新没有成功 原因有几个 1 更改字段在实际中没有 2 多层结构要用用字典来更新 不能用car color方式更新 res es update index index doc type doc type id data id bo
  • 【linux】定时任务讲解

    文章目录 一 在某时刻只执行一次 at 1 设置定时任务 2 查看和删除定时任务 二 周期性执行任务 cron 1 启动crond进程 2 编辑定时任务 3 查看和删除 4 用户权限 4 1 黑名单 4 2指定用户 三 etc cronta
  • Head First Design Mode(5)-工厂模式

    该系列文章系个人读书笔记及总结性内容 任何组织和个人不得转载进行商业活动 工厂模式 烘烤OO的精华 烘烤某些松耦合的OO设计 除了使用new操作符之外 还有更多制造对象的方法 本章我们将了解到实例化的这个活动不应该总是公开的进行 认识到初始
  • 按照目的来分,设计模式可以分为创建型模式、结构型模式和行为型模式。

    引用 软件秘笈 设计模式那点事 书籍 按照目的来分 设计模式可以分为创建型模式 结构型模式和行为型模式 创建型模式用来处理对象的创建过程 结构型模式用来处理类或者对象的组合 行为型模式用来对类或对象怎样交互和怎样分配职责进行描述 创建型模式
  • redis集群主流架构方案分析

    阿伊土鳖小码农 2017 02 10 09 29 Redis在互联网大数据平台有着广泛的应用 主要被用来缓存热点数据 避免海量请求压垮数据库 同时可以提升服务节点的响应速度和并发量 随着数据量的增多 由于redis是占用单台物理机或虚机的内
  • 【vue3+ts+vant】上传图片

    1 使用 van upload 组件 进行样式和功能配置 组件基础结构 配置文字和图标 配置最多数量和最大体积 支持双向数据绑定 支持选择图片后触发函数 支持点击删除事件函数 基础结构
  • STM32学习(一)-- stm32简介

    目录 前言 一 STM32简介 1 STM32 是什么 2 STM32 应用领域 3 STM32 优势 二 ARM简介 三 STM32芯片 1 芯片命名规则 2 型号分类及缩写 四 STM32F103C8T6 1 STM32F103C8T6
  • 机器学习:均值漂移(Mean Shift)详细解释

    1 均值漂移的基本概念 Mean Shift算法和k means相似 都是一个迭代的过程 即先算出当前点的偏移均值 将该点移动到该偏移均值 以此为新的起始点 继续移动 直到满足最终的条件 1 设想在一个有N个样本点的特征空间 初始确定一个中