我有100个包含系统调用追踪的文件。每个文件的格式如下所示:
setpgrp ioctl setpgrp ioctl ioctl ....
我试图加载这些文件并对它们进行Kmean计算,以便根据相似性对它们进行聚类。根据sklearn网页上的教程,我编写了以下代码:
from sklearn.decomposition import TruncatedSVDfrom sklearn.feature_extraction.text import TfidfVectorizerfrom sklearn.feature_extraction.text import TfidfTransformerfrom sklearn.pipeline import make_pipelinefrom sklearn.preprocessing import Normalizerfrom sklearn import metricsfrom sklearn.datasets import load_filesfrom sklearn.cluster import KMeans, MiniBatchKMeansimport numpy as np# 解析命令行参数op = OptionParser()op.add_option("--lsa", dest="n_components", type="int", help="使用潜在语义分析预处理文档。")op.add_option("--no-minibatch", action="store_false", dest="minibatch", default=True, help="使用普通的k-means算法(批处理模式)。")op.add_option("--use-idf", action="store_false", dest="use_idf", default=True, help="禁用逆文档频率特征加权。")op.add_option("--n-features", type=int, default=10000, help="从文本中提取的最大特征数(维度)")op.add_option("--verbose", action="store_true", dest="verbose", default=False, help="在k-means算法内部打印进度报告。")print(__doc__)op.print_help()(opts, args) = op.parse_args()if len(args) > 0: op.error("此脚本不接受任何参数。") sys.exit(1)print("加载训练数据:")trainingdata = load_files('C:\data\Training data')print("%d 个文档" % len(trainingdata.data))print() print("使用稀疏向量化器从训练数据中提取特征")if opts.use_idf: vectorizer = TfidfVectorizer(input="file",min_df=1) X = vectorizer.fit_transform(trainingdata.data)print("样本数: %d, 特征数: %d" % X.shape)print()if opts.n_components: print("使用LSA进行降维处理") # 向量化结果已被归一化,这使得KMeans表现为球形k-means以获得更好的结果。由于LSA/SVD结果未被归一化,我们必须重新进行归一化。 svd = TruncatedSVD(opts.n_components) lsa = make_pipeline(svd, Normalizer(copy=False)) X = lsa.fit_transform(X) explained_variance = svd.explained_variance_ratio_.sum() print("SVD步骤的解释方差: {}%".format( int(explained_variance * 100))) print()
然而,尽管数据集目录中的所有文件都可用,但似乎没有一个文件被加载到内存中。执行程序时,我得到了以下错误:
raise ValueError("empty vocabulary; perhaps the documents only"ValueError: empty vocabulary; perhaps the documents only contain stop words
谁能告诉我为什么数据集没有被加载?我做错了什么?
回答:
我最终成功加载了文件。在sklearn中使用Kmean的方法是首先对训练数据进行向量化(使用tfidf或count_vectorizer),然后使用训练数据的向量化来转换你的测试数据。完成这些后,你可以初始化Kmean参数,使用训练数据集向量创建kmean聚类。最后,你可以根据训练数据的中心点对测试数据进行聚类。以下代码实现了上述说明的操作。
#读取目录中的数据:def readfile(dataDir): data_set = [] for file in os.listdir(dataDir): trainingfiles = os.path.join(dataDir, file) if os.path.isfile(trainingfiles): data = open(trainingfiles, 'r') dataread=str.decode(data.read()) data_set.append(dataread) return data_set #对训练数据进行tfidf转换tfidf_vectorizer_trainingset = tfidf_vectorizer.fit_transform(readfile(trainingdataDir)).toarray()#基于训练集转换测试集tfidf_vectorizer_testset = tfidf_vectorizer.transform(readfile(testingdataDir)).toarray()# Kmean聚类参数kmean_parameters = KMeans(n_clusters=number_of_clusters, init='k-means++', max_iter=100, n_init=1)#基于参数对训练数据进行聚类KmeanAnalysis_training = kmean_parameters.fit(tfidf_vectorizer_trainingset)#基于训练数据的聚类转换测试数据KmeanAnalysis_test = kmean_parameters.transform(tfidf_vectorizer_testset)