美国议员党派——K均值聚类

Dataset

在美国,参议院表决提案。将一个提案付诸实施的关键一步是获得参议院的通过。需要一个多数投票通过一项法案。这些投票的结果,被称为点名选票,是公开的。参议员通常按照他们的政党路线进行投票。在美国,两个主要政党一个是民主党人D,他们倾向于自由主义,另一个是共和党人R倾向于保守派。参议员们也可以选择作为一个无党派人I士来自由投票,尽管很少选择这样做。114_congress.csv包含了第114届的参议院投票信息,每一行代表一个参议员的信息,每一列代表着选票结果(0是反对,1是同意,0.5是拒绝)下面是一些相关的特征:

  • name – The last name of the Senator.
  • party – the party of the Senator. The valid values are D for Democrat, R for Republican, and I for Independent.
  • Several columns numbered like 00001, 00004, etc. Each of these columns represents the results of a single roll call vote.(实际就是每个提案的编号:值是每个参议员的投票结果)

对这个数据进行聚类分析可以得到很有趣的信息,比如,发现每个党派中的主流参议员。

Exploring The Data

首先计算一些简单的统计:

  • 总共有100个参议员,其中共和党54名,民主党44名,自由党2名。总共有有15个提案。每个提案的平均通过数。
import pandas as pd
votes = pd.read_csv("114_congress.csv")
print(votes["party"].value_counts())
print(votes.mean())
''' R 54 D 44 I 2 dtype: int64 00001 0.325 00004 0.575 00005 0.535 00006 0.945 00007 0.545 00008 0.415 00009 0.545 00010 0.985 00020 0.525 00026 0.545 00032 0.410 00038 0.480 00039 0.510 00044 0.460 00047 0.370 dtype: float64 '''

Distance Between Senators

  • 计算参议员的相似性,根据他们的投票信息可以判断他们的观点是否相似,在sklearn中有一个专门的函数euclidean_distances()用来计算向量之间的欧式距离(在计算距离之时我们只需要投票信息,前三列不需要):
# 计算第0行和第2行的距离
from sklearn.metrics.pairwise import euclidean_distances

distance = euclidean_distances(votes.iloc[0,3:], votes.iloc[2,3:])
''' distance :array([[ 3.31662479]]) '''

Initial Clustering

  • 由于主要政党是两派,因此将k值设为2,利用KMeans函数进行模型创建,下面这个代码就实现了一个KMeans模型的创建,其中的random_state是种子,表示两次随机的种子,如果下一次运行程序还是1那么结果将会相同。
kmeans_model = KMeans(n_clusters=2, random_state=1)
  • 然后再使用fit_transform函数对数据进行拟合得到每个参议员与聚类中心的距离:
import pandas as pd
from sklearn.cluster import KMeans

kmeans_model = KMeans(n_clusters=2, random_state=1) senator_distances = kmeans_model.fit_transform(votes.iloc[:, 3:])
'''
array([[ 3.12141628,  1.3134775 ],
 [ 2.6146248 , 2.05339992],
 [ 0.33960656, 3.41651746],
 [ 3.42004795, 0.24198446],
 [ 1.43833966, 2.96866004],
 ...
'''

Exploring The Clusters

  • 再利用Pandas的crosstab() 方法计算每个参议员最终归为哪一个簇。这个方法的参数是两个Pandas的Series,然后计算一个混淆矩阵,具体就是两个数组中,对应的index的数据组合数,比如:
is_smoker =       [0,1,1,0,0,1]
has_lung_cancer = [1,0,1,0,1,0]
''' has_lung_cancer 0 1 smoker 0 1 2 1 2 1 '''
  • 在前面已经用KMeans构建了一个聚类,并且给予每个参议员一个标签,然后再与真实的标签进行比较,得到一个混淆矩阵:
labels = kmeans_model.labels_
print(pd.crosstab(labels, votes["party"]))
''' party D I R row_0 0 41 2 0 1 3 0 54 '''
  • 解释下这个混淆矩阵的含义:预测结果中第0簇中有41个D,2个I,0个R,第1簇中有3个D,0个I,54个R。这表明第0簇几乎全是D(民主党派人士),但是有3个民主党派人士可能是“卧底”,因为他们的投票和R(共和党派人士)相似。而R(共和党派人士)的投票完全相似,一致得很,很团结。两个I(自由党派人士)更倾向D(民主党派人士)的投票风格。
  • 找出这三个党的叛徒:
democratic_outliers = votes[(labels == 1) & (votes["party"] == "D")] print(democratic_outliers["name"])
'''
42    Heitkamp
56     Manchin
74        Reid
'''

Plotting Out The Clusters

  • 利用matplotlib聚类结果显示出来,之前我们得到每个参议员到聚类中心的距离(总共有N个参议员,那么有N组,每行表示一个参议员到每个内个聚类中心的距离,此处总共有2个聚类小红心,因此是一个2*N的数组),此时我们将第一列当做x轴,第二列当做y轴画出散点图:
plt.scatter(x=senator_distances[:,0], y=senator_distances[:,1], c=labels)
plt.show()

Finding The Most Extreme

  • 最极端的参议员就是那些离聚类中心最远的点。例如,一个激进的共和党人将尽可能远离民主集群,而在两个聚类中间的参议院都是比较温和的人,因为他们的观点在两个党派中都有体现。

    美国议员党派——K均值聚类_第1张图片

  • 因此构造了计算极端人士的公式:就是将每列的值求立方然后求和,因为求立方可以放大每个点到中心的距离,使它们分的更开。

extremism = (senator_distances ** 3).sum(axis=1)
votes["extremism"] = extremism
votes.sort("extremism", inplace=True, ascending=False)
print(votes.head(10))
''' name party state 00001 00004 00005 00006 00007 00008 00009 \ 98 Wicker R MS 0 1 1 1 1 0 1 53 Lankford R OK 0 1 1 0 1 0 1 69 Paul R KY 0 1 1 0 1 0 1 80 Sasse R NE 0 1 1 0 1 0 1 26 Cruz R TX 0 1 1 0 1 0 1 48 Johnson R WI 0 1 1 1 1 0 1 47 Isakson R GA 0 1 1 1 1 0 1 65 Murkowski R AK 0 1 1 1 1 0 1 64 Moran R KS 0 1 1 1 1 0 1 30 Enzi R WY 0 1 1 1 1 0 1 00010 00020 00026 00032 00038 00039 00044 00047 extremism 98 0 1 1 0 0 1 0 0 46.250476 53 1 1 1 0 0 1 0 0 46.046873 69 1 1 1 0 0 1 0 0 46.046873 80 1 1 1 0 0 1 0 0 46.046873 26 1 1 1 0 0 1 0 0 46.046873 48 1 1 1 0 0 1 0 0 40.017540 47 1 1 1 0 0 1 0 0 40.017540 65 1 1 1 0 0 1 0 0 40.017540 64 1 1 1 0 0 1 0 0 40.017540 30 1 1 1 0 0 1 0 0 40.017540 '''

conclusion

  • 在做数据挖掘的时候,得到一个数据集,一开始看不来有什么模式,这个时候建议先用无监督的学习算法去探索一下数据的规律,然后再用有监督的学习算法去挖掘你想要的模式。

你可能感兴趣的:(美国议员党派——K均值聚类)