秒懂算法 | 基于K-Means算法的汽车行驶运动学片段的分类

简介: 汽车在行进过程中会产生连续的一组数据,包含加速度,速度等参数,汽车形式运动学片段是指是从一个怠速开始到下一个怠速开始之间的运动行程,通常包括一个怠速部分和一个行驶部分。而怠速指的是汽车停止运动,但发动机保持最低转速运转的连续过程。行驶部分通常包含加速、巡航和减速三种运动模式。

640.jpg


如图1所示为汽车行进过程中产生的数据,图2为一个汽车行驶运动学的片段。

image.png

■ 图1 汽车行进中产生的数据

640.jpg


■ 图2 运动学片段


本文的任务是将汽车行进的数据切分为一个个的运动学片段,再对这些运动学片段进行分类,从而获得每一类运动学片段的代表片段,合成汽车工况。

01、基于K-Means的汽车行驶运动学片段分类

下面用K-Means来对运动学片段进行聚类。聚类时关键的一点在聚类数目的选取上,本文将采取两种方案来对聚类数目进行选取,如代码清单1所示。首先是定义并计算SSE的函数,并绘制出随着聚类数目变化,SSE变化的折线图。

代码清单1 绘制SSE变化曲线图函数

def getSSE(input):
    # 存储不同簇数的SSE值
    distortions = []
    for i in range(1, 11):
        km = KMeans(n_clusters=i, init="k-means++", n_init=10, max_iter=300, tol=1e-4, random_state=0)
        km.fit(input)
        distortions.append(km.inertia_)
    # 绘制结果
    plt.plot(range(1, 11), distortions, marker='o')
    plt.xlabel("Cluster_num")
    plt.ylabel("SSE")
    plt.show()

由于原始数据中,不同特征的量纲不尽相同,如果使用原始数据直接进行聚类,会存在量纲不一致的问题,即数字较大的特征会对模型产生较大影响,因此在进行聚类之前,还需要进行数据归一化的处理,如代码清单2修改main函数为

代码清单2 主函数1

if __name__ == "__main__":
    feature = cutPart()
    scaler = preprocessing.StandardScaler().fit(feature)
    feature = scaler.transform(feature)
    getSSE(feature)

运行main函数,可得SSE变化图如图3所示。

640.jpg


■ 图3 SSE随聚类数目变化折线图

如图3所示,随着聚类数目增多,并没有出现及其明显的手肘,但通过观察可得,当聚类数目为2或3时,误差下降的幅度是最为明显的,从4开始往后,基本上就处于线性递减的状态。因此,最优的聚类数目可能为2、3、4中的某一个。

下面通过轮廓图从另一个角度进行分析。首先是绘制轮廓图有关的函数,如代码清单2所示。

代码清单2 绘制轮廓图函数

def getSilehotte(input, n_cluster):
    km = KMeans(n_clusters=n_cluster, init="k-means++", n_init=10, max_iter=300, tol=1e-4, random_state=0)
    y_km = km.fit_predict(input, n_cluster)
    # 获取簇的标号
    cluster_labels = np.unique(y_km)
    silehoutte_vals = silhouette_samples(input, y_km, metric="euclidean")
    y_ax_lower, y_ax_upper = 0, 0
    y_ticks = []
    for i, c in enumerate(cluster_labels):
        # 获得不同簇的轮廓系数
        c_silhouette_vals = silehoutte_vals[y_km == c]
        c_silhouette_vals.sort()
        y_ax_upper += len(c_silhouette_vals)
        color = cm.jet(i / n_cluster)
        plt.barh(range(y_ax_lower, y_ax_upper), c_silhouette_vals, height=1.0, edgecolor="none", color=color)
        y_ticks.append((y_ax_lower + y_ax_upper) / 2)
        y_ax_lower += len(c_silhouette_vals)

    silehoutte_avg = np.mean(silehoutte_vals)
    plt.axvline(silehoutte_avg, color="red", linestyle="--")
    plt.yticks(y_ticks, cluster_labels + 1)
    plt.ylabel("Cluster")
    plt.xlabel("Silehotte_value")
plt.show()

该函数的输入为特征以及聚类数目,每个聚类数目可得一个轮廓图。如代码清单3修改main函数为

代码清单3 主函数2

if __name__ == "__main__":
    feature = cutPart()
    scaler = preprocessing.StandardScaler().fit(feature)
    feature = scaler.transform(feature)
    getSilehotte(feature, 2)
    getSilehotte(feature, 3)
    getSilehotte(feature, 4)

分别绘制聚类数目为2、3、4时的轮廓图帮助后期分析,运行脚本可得如图4、图5、图6所示。

640.jpg


■ 图4 聚类数目为2时轮廓图

640.jpg


■ 图5 聚类数目为3时轮廓图

640.jpg


■ 图6 聚类数目为4时轮廓图

如图4、图5、图6所示,当聚类个数为2时,轮廓系数表现不错,说明可以有效地聚类。当聚类数目上升到3时,第一类开始出现负值,即聚类效果开始下降,进一步上升到4时,出现了严重的数目不均等,第4类的数目远远小于前三类,基于对轮廓图的分析,可以选择聚类数目为2或者3。

倘若将运动学片段分为3类,并对每一类进行分析,可以发现这三类中,第1类平均速度最高,怠速时间比例最低,代表在畅通路段行驶的工况;第3类平均车速最低,怠速时间比例最高,代表拥堵路段行驶的工况;第2类代表一般工况。

对每一类按照距离聚类中心的距离从小到大进行排序,就可以得到每一类的典型运动学片段。在将这些运动学片段进行组合,就可以最终获得汽车行驶工况。

如图7所示为基于K-Means方法合成的汽车行驶工况。

640.jpg

■ 图7 合成代表工况

目录
相关文章
|
3天前
|
机器学习/深度学习 算法 数据可视化
算法金 | 再见!!!K-means
**k-means 算法的简要总结:** - **k-means** 是一种非监督学习的聚类算法,用于将数据分为 k 个类别。 - **工作流程** 包括初始化 k 个中心点,分配数据点到最近的中心,更新中心点,然后迭代直到中心点稳定或达到最大迭代次数。 - **优点** 包括简单易懂、计算效率高,适合大规模数据,结果直观。 - **缺点** 包括需要预设 k 值,对初始中心点敏感,假设簇是凸形,受异常值影响大。
12 2
算法金 | 再见!!!K-means
|
5天前
|
算法
【经典LeetCode算法题目专栏分类】【第11期】递归问题:字母大小写全排列、括号生成
【经典LeetCode算法题目专栏分类】【第11期】递归问题:字母大小写全排列、括号生成
|
5天前
|
算法
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
|
5天前
|
算法
【经典LeetCode算法题目专栏分类】【第9期】深度优先搜索DFS与并查集:括号生成、岛屿问题、扫雷游戏
【经典LeetCode算法题目专栏分类】【第9期】深度优先搜索DFS与并查集:括号生成、岛屿问题、扫雷游戏
|
5天前
|
算法
【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串
【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串
|
5天前
|
算法
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
|
5天前
|
算法
【经典LeetCode算法题目专栏分类】【第6期】二分查找系列:x的平方根、有效完全平方数、搜索二位矩阵、寻找旋转排序数组最小值
【经典LeetCode算法题目专栏分类】【第6期】二分查找系列:x的平方根、有效完全平方数、搜索二位矩阵、寻找旋转排序数组最小值
|
5天前
|
算法 机器人
【经典LeetCode算法题目专栏分类】【第5期】贪心算法:分发饼干、跳跃游戏、模拟行走机器人
【经典LeetCode算法题目专栏分类】【第5期】贪心算法:分发饼干、跳跃游戏、模拟行走机器人
|
5天前
|
算法
【经典LeetCode算法题目专栏分类】【第4期】BFS广度优先算法:单词接龙、最小基因变化、二进制矩阵中的最短路径
【经典LeetCode算法题目专栏分类】【第4期】BFS广度优先算法:单词接龙、最小基因变化、二进制矩阵中的最短路径
|
5天前
|
算法
【经典LeetCode算法题目专栏分类】【第3期】回溯问题系列:单词搜索、N皇后问题、判断有效数独、解数独
【经典LeetCode算法题目专栏分类】【第3期】回溯问题系列:单词搜索、N皇后问题、判断有效数独、解数独

热门文章

最新文章