sklearn:计算测试数据集上k-means的准确度分数
sklearn: calculating accuracy score of k-means on the test data set
我正在对包含 2 个簇的 30 个样本集进行 k 均值聚类(我已经知道有两个 类)。我将我的数据分为训练集和测试集,并尝试计算我的测试集的准确度分数。但是有两个问题:首先我不知道我是否真的可以为 k-means 聚类做这个(测试集上的准确度分数)。第二:如果允许我这样做,我的实现是对还是错。这是我尝试过的:
df_hist = pd.read_csv('video_data.csv')
y = df_hist['label'].values
del df_hist['label']
df_hist.to_csv('video_data1.csv')
X = df_hist.values.astype(np.float)
X_train, X_test,y_train,y_test = cross_validation.train_test_split(X,y,test_size=0.20,random_state=70)
k_means = cluster.KMeans(n_clusters=2)
k_means.fit(X_train)
print(k_means.labels_[:])
print(y_train[:])
score = metrics.accuracy_score(y_test,k_means.predict(X_test))
print('Accuracy:{0:f}'.format(score))
k_means.predict(X_test)
print(k_means.labels_[:])
print(y_test[:])
但是,当我为测试集打印 k-means 标签时 (k_means.predict(X_test) print(k_means.labels_[:])) 和 y_test labels (print(k_means.labels_[:])) 在最后三行,我获得与我安装 X-train 时相同的标签,而不是为 X-test 生成的标签。知道我在这里做错了什么吗?我正在做的评估 k-means 性能的工作完全正确吗?
谢谢!
在评估准确性方面。您应该记住 k-means 不是分类工具,因此分析准确性不是一个好主意。你可以这样做,但这不是 k-means 的目的。它应该找到一组最大化簇间距离的数据,它不使用您的标签进行训练。因此,通常使用 RandIndex 和其他聚类指标来测试 k-means 之类的东西。为了最大限度地提高准确性,您应该适合实际的分类器,如 kNN、逻辑回归、SVM 等。
就代码本身而言,k_means.predict(X_test)
returns标签,它不会更新内部labels_
字段,你应该这样做
print(k_means.predict(X_test))
此外,在 python 中,您不必(也不应该)使用 [:]
来打印数组,只需执行
print(k_means.labels_)
print(y_test)
您需要的指标是调整后的兰特指数。但是在整个数据集上评估 k-means。它 return 值从 0 到 1。检查下面的 link:
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.adjusted_rand_score.html
我们标记的无监督学习中的数据可以与 K-means 等无监督算法给出的标签相同,也可以不同。
例如:
数据有两个 classes 一个是垃圾邮件或不是垃圾邮件,垃圾邮件被我们标记为 0 而不是垃圾邮件为 1。但是在 运行 聚类算法之后垃圾邮件被视为 1 而不是垃圾邮件为 0。那个时候下面的代码将不起作用。这将表明准确度较低,但实际上算法运行良好。
score = metrics.accuracy_score(y_test,k_means.predict(X_test))
因此,通过跟踪真实 class 0 和真实 class 1 有多少预测的 0 或 1,我们为每个真实选择最大的 class.因此,如果预测的 class 0 的数量是 90,而对于 true class 1,1 是 10,这意味着聚类算法将 true class 1 视为 0.
true_classes=np.asarray(y_test)
pred_classes=pred
no_correct=0
di={}
for i in range(k):
di[i]={}
for j in range(k):
di[i][j]=[]
for i in range(true_classes.shape[0]):
di[true_classes[i]][pred_classes[i]].append(1)
for i in range(len(di)):
temp=-1
for j in range(len(di[i])):
temp=max(temp,len(di[i][j]))
if temp==len(di[i][j]):
cluser_class=j
print("class {} named as class {} in clustering algo".format(list(di.keys())[i],cluser_class))
no_correct=no_correct+temp
print(no_correct/true_classes.shape[0])
我正在对包含 2 个簇的 30 个样本集进行 k 均值聚类(我已经知道有两个 类)。我将我的数据分为训练集和测试集,并尝试计算我的测试集的准确度分数。但是有两个问题:首先我不知道我是否真的可以为 k-means 聚类做这个(测试集上的准确度分数)。第二:如果允许我这样做,我的实现是对还是错。这是我尝试过的:
df_hist = pd.read_csv('video_data.csv')
y = df_hist['label'].values
del df_hist['label']
df_hist.to_csv('video_data1.csv')
X = df_hist.values.astype(np.float)
X_train, X_test,y_train,y_test = cross_validation.train_test_split(X,y,test_size=0.20,random_state=70)
k_means = cluster.KMeans(n_clusters=2)
k_means.fit(X_train)
print(k_means.labels_[:])
print(y_train[:])
score = metrics.accuracy_score(y_test,k_means.predict(X_test))
print('Accuracy:{0:f}'.format(score))
k_means.predict(X_test)
print(k_means.labels_[:])
print(y_test[:])
但是,当我为测试集打印 k-means 标签时 (k_means.predict(X_test) print(k_means.labels_[:])) 和 y_test labels (print(k_means.labels_[:])) 在最后三行,我获得与我安装 X-train 时相同的标签,而不是为 X-test 生成的标签。知道我在这里做错了什么吗?我正在做的评估 k-means 性能的工作完全正确吗? 谢谢!
在评估准确性方面。您应该记住 k-means 不是分类工具,因此分析准确性不是一个好主意。你可以这样做,但这不是 k-means 的目的。它应该找到一组最大化簇间距离的数据,它不使用您的标签进行训练。因此,通常使用 RandIndex 和其他聚类指标来测试 k-means 之类的东西。为了最大限度地提高准确性,您应该适合实际的分类器,如 kNN、逻辑回归、SVM 等。
就代码本身而言,k_means.predict(X_test)
returns标签,它不会更新内部labels_
字段,你应该这样做
print(k_means.predict(X_test))
此外,在 python 中,您不必(也不应该)使用 [:]
来打印数组,只需执行
print(k_means.labels_)
print(y_test)
您需要的指标是调整后的兰特指数。但是在整个数据集上评估 k-means。它 return 值从 0 到 1。检查下面的 link:
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.adjusted_rand_score.html
我们标记的无监督学习中的数据可以与 K-means 等无监督算法给出的标签相同,也可以不同。 例如: 数据有两个 classes 一个是垃圾邮件或不是垃圾邮件,垃圾邮件被我们标记为 0 而不是垃圾邮件为 1。但是在 运行 聚类算法之后垃圾邮件被视为 1 而不是垃圾邮件为 0。那个时候下面的代码将不起作用。这将表明准确度较低,但实际上算法运行良好。
score = metrics.accuracy_score(y_test,k_means.predict(X_test))
因此,通过跟踪真实 class 0 和真实 class 1 有多少预测的 0 或 1,我们为每个真实选择最大的 class.因此,如果预测的 class 0 的数量是 90,而对于 true class 1,1 是 10,这意味着聚类算法将 true class 1 视为 0.
true_classes=np.asarray(y_test)
pred_classes=pred
no_correct=0
di={}
for i in range(k):
di[i]={}
for j in range(k):
di[i][j]=[]
for i in range(true_classes.shape[0]):
di[true_classes[i]][pred_classes[i]].append(1)
for i in range(len(di)):
temp=-1
for j in range(len(di[i])):
temp=max(temp,len(di[i][j]))
if temp==len(di[i][j]):
cluser_class=j
print("class {} named as class {} in clustering algo".format(list(di.keys())[i],cluser_class))
no_correct=no_correct+temp
print(no_correct/true_classes.shape[0])