You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python下K-Means聚类应用:出租车运营区域判定及预处理疑问

用K-Means聚类判断出租车是否本地运营的可行性及预处理步骤

数据集代码与样例

import pandas as pd
import random
random.seed(901)
rand_list1= []
rand_list2= []
rand_list3= []
rand_list4= []
rand_list5= []

for i in range(20):
    x = random.randint(80,1000)
    rand_list1.append(x/100)
    
    y1 = random.randint(-200,200)
    rand_list2.append(y1/10)
    y2 = random.randint(-200,200)
    rand_list3.append(y2/10)
    y3 = random.randint(-200,200)
    rand_list4.append(y3/10)
    y4 = random.randint(-200,200)
    rand_list5.append(y4/10)

df = pd.DataFrame({'Rainfall Recorded':rand_list1, 'TAXI A':rand_list2, 'TAXI B':rand_list3, 'TAXI C':rand_list4, 'TAXI D':rand_list5})

df.head()

数据集前5行预览:

Rainfall RecordedTAXI ATAXI BTAXI CTAXI D
5.2113.7-5.0-14.29.8
2.39-0.318.84.8-6.4
8.0915.0-3.618.612.7
5.79-0.214.60.93.8
7.4810.99.015.4-16.5

问题描述

给定区域降雨量(单位:厘米)及受访出租车上报的营收变化百分比,假设降雨量与营收变化存在关联,请问能否使用K-Means Clustering判定这些出租车是否在本地运营?我从网络获取了一段简单代码:

km = KMeans(n_clusters=2)
y_predicted = km.fit_predict(df[['TAXI','Rainfall Recorded']])
y_predicted

但不确定使用该代码前需执行哪些数据转换操作。


可行性分析

可以尝试用K-Means聚类实现,但核心前提是:本地运营的出租车,营收变化与降雨量的关联模式会高度相似;而非本地运营的出租车,营收变化和本地降雨量的关联会很弱,甚至模式完全不同。如果这个前提成立,K-Means会把关联模式一致的出租车归为同一簇,从而区分本地/非本地车辆。但如果所有车辆的营收-降雨关联都无明显规律,或规律趋同,聚类就起不到区分作用。

数据转换与预处理步骤

你拿到的代码有明显问题:原数据集没有名为TAXI的列,且数据结构不符合K-Means的样本-特征要求,需按以下步骤调整:

1. 重构数据集结构

K-Means需要「单样本对应一组特征」的格式,这里要把宽表转成长表,让每一行对应「某辆出租车某一天的降雨量+营收变化」:

# 宽表转长表,提取出租车ID、对应日期的营收变化
df_long = df.melt(id_vars='Rainfall Recorded', 
                  var_name='Taxi_ID', 
                  value_name='Revenue_Change')

转换后的数据结构示例:

Rainfall RecordedTaxi_IDRevenue_Change
5.21TAXI A13.7
2.39TAXI A-0.3

2. 特征标准化

K-Means是基于距离计算的算法,降雨量(数值范围0.8-10)和营收变化百分比(数值范围-20-20)的量纲差异会干扰距离计算,必须做标准化处理:

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
# 对降雨量和营收变化做标准化,生成新特征列
df_long[['Rainfall_Scaled', 'Revenue_Scaled']] = scaler.fit_transform(
    df_long[['Rainfall Recorded', 'Revenue_Change']]
)

3. 调整聚类输入(两种可选思路)

思路一:基于「营收-降雨相关性」聚类(更直接)

本地出租车的营收与降雨的相关性应该趋同,非本地的相关性则接近0或完全不同。先计算每辆出租车的营收-降雨相关系数,再用该系数做聚类:

from sklearn.cluster import KMeans
import pandas as pd

# 计算每辆出租车的营收变化与降雨量的皮尔逊相关系数
taxi_corr = df_long.groupby('Taxi_ID').apply(
    lambda x: x['Revenue_Change'].corr(x['Rainfall Recorded'])
).reset_index(name='Rainfall_Revenue_Corr')

# 执行K-Means聚类(设定2类:本地/非本地)
km = KMeans(n_clusters=2, random_state=901)
taxi_corr['Cluster'] = km.fit_predict(taxi_corr[['Rainfall_Revenue_Corr']])

思路二:基于「每日数据特征」聚类

用标准化后的降雨量和营收变化作为特征,对每日数据聚类,再统计每辆出租车落在不同簇的比例——比例集中在单个簇的车辆,营收-降雨模式一致(大概率本地):

km = KMeans(n_clusters=2, random_state=901)
df_long['Cluster'] = km.fit_predict(df_long[['Rainfall_Scaled', 'Revenue_Scaled']])

# 统计每辆出租车的簇分布
taxi_cluster_dist = df_long.groupby('Taxi_ID')['Cluster'].value_counts(normalize=True)

4. 可选:验证聚类合理性

用肘部法则验证设定的聚类数(比如n=2)是否合理:

import matplotlib.pyplot as plt

inertias = []
# 尝试1-5个聚类数
for k in range(1,6):
    km = KMeans(n_clusters=k, random_state=901)
    km.fit(df_long[['Rainfall_Scaled', 'Revenue_Scaled']])
    inertias.append(km.inertia_)

plt.plot(range(1,6), inertias, marker='o')
plt.xlabel('聚类数量')
plt.ylabel('簇内平方和')
plt.show()

如果曲线在k=2处出现明显拐点,说明设定2类是合理的。


内容的提问来源于stack exchange,提问作者prashanth manohar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 23:34:52