Python 机器学习 基础 之 处理文本数据 【停用词/用tf-idf缩放数据/模型系数/多个单词的词袋/高级分词/主题建模/文档聚类】的简单说明

本文主要是介绍Python 机器学习 基础 之 处理文本数据 【停用词/用tf-idf缩放数据/模型系数/多个单词的词袋/高级分词/主题建模/文档聚类】的简单说明,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Python 机器学习 基础 之 处理文本数据 【停用词/用tf-idf缩放数据/模型系数/多个单词的词袋/高级分词/主题建模/文档聚类】的简单说明

目录

Python 机器学习 基础 之 处理文本数据 【停用词/用tf-idf缩放数据/模型系数/多个单词的词袋/高级分词/主题建模/文档聚类】的简单说明

一、简单介绍

二、停用词

三、用tf-idf缩放数据

四、研究模型系数

五、多个单词的词袋(n 元分词)

六、高级分词、词干提取与词形还原

七、主题建模与文档聚类

1、隐含狄利克雷分布

附录:

一、参考文献

二、spacy 环境配置


一、简单介绍

Python是一种跨平台的计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。Python是一种解释型脚本语言,可以应用于以下领域: Web 和 Internet开发、科学计算和统计、人工智能、教育、桌面界面开发、软件开发、后端开发、网络爬虫。

Python 机器学习是利用 Python 编程语言中的各种工具和库来实现机器学习算法和技术的过程。Python 是一种功能强大且易于学习和使用的编程语言,因此成为了机器学习领域的首选语言之一。Python 提供了丰富的机器学习库,如Scikit-learn、TensorFlow、Keras、PyTorch等,这些库包含了许多常用的机器学习算法和深度学习框架,使得开发者能够快速实现、测试和部署各种机器学习模型。

Python 机器学习涵盖了许多任务和技术,包括但不限于:

  1. 监督学习:包括分类、回归等任务。
  2. 无监督学习:如聚类、降维等。
  3. 半监督学习:结合了有监督和无监督学习的技术。
  4. 强化学习:通过与环境的交互学习来优化决策策略。
  5. 深度学习:利用深度神经网络进行学习和预测。

通过 Python 进行机器学习,开发者可以利用其丰富的工具和库来处理数据、构建模型、评估模型性能,并将模型部署到实际应用中。Python 的易用性和庞大的社区支持使得机器学习在各个领域都得到了广泛的应用和发展。

二、停用词

删除没有信息量的单词还有另一种方法,就是舍弃那些出现次数太多以至于没有信息量的单词。有两种主要方法:使用特定语言的停用词(stopword)列表,或者舍弃那些出现过于频繁的单词。scikit-learn 的 feature_extraction.text 模块中提供了英语停用词的内置列表:

from sklearn.feature_extraction.text import ENGLISH_STOP_WORDS
print("Number of stop words: {}".format(len(ENGLISH_STOP_WORDS)))
print("Every 10th stopword:\n{}".format(list(ENGLISH_STOP_WORDS)[::10]))
Number of stop words: 318
Every 10th stopword:
['up', 'upon', 'can', 'even', 'few', 'could', 'whenever', 'though', 'system', 'seem', 'how', 'always', 'whereas', 'perhaps', 'rather', 'ltd', 'will', 'became', 'thru', 'if', 're', 'last', 'yet', 'anyone', 'become', 'although', 'from', 'four', 'find', 'it', 'etc', 'two']

显然,删除上述列表中的停用词只能使特征数量减少 318 个(即上述列表的长度),但可能会提高性能。我们来试一下:

# 指定stop_words="english"将使用内置列表。
# 我们也可以扩展这个列表并传入我们自己的列表。
vect = CountVectorizer(min_df=5, stop_words="english").fit(text_train)
X_train = vect.transform(text_train)
print("X_train with stop words:\n{}".format(repr(X_train)))
X_train with stop words:
<25000x26966 sparse matrix of type '<class 'numpy.int64'>'with 2149958 stored elements in Compressed Sparse Row format>

现在数据集中的特征数量减少了 305 个(27271-26966),说明大部分停用词(但不是所有)都出现了。我们再次运行网格搜索:

grid = GridSearchCV(LogisticRegression(), param_grid, cv=5)
grid.fit(X_train, y_train)
print("Best cross-validation score: {:.2f}".format(grid.best_score_))
Best cross-validation score: 0.88

使用停用词后的网格搜索性能略有下降——不至于担心,但鉴于从 27 000 多个特征中删除 305 个不太可能对性能或可解释性造成很大影响,所以使用这个列表似乎是不值得的。固定的列表主要对小型数据集很有帮助,这些数据集可能没有包含足够的信息,模型从数据本身无法判断出哪些单词是停用词。作为练习,你可以尝试另一种方法,即通过设置 CountVectorizer 的 max_df 选项来舍弃出现最频繁的单词,并查看它对特征数量和性能有什么影响。

三、用tf-idf缩放数据

另一种方法是按照我们预计的特征信息量大小来缩放特征,而不是舍弃那些认为不重要的特征。最常见的一种做法就是使用词频 - 逆向文档频率 (term frequency - inverse document frequency,tf-idf)方法。这一方法对在某个特定文档中经常出现的术语给予很高的权重,但对在语料库的许多文档中都经常出现的术语给予的权重却不高。如果一个单词在某个特定文档中经常出现,但在许多文档中却不常出现,那么这个单词很可能是对文档内容的很好描述。scikit-learn 在两个类中实现了 tf-idf 方法:TfidfTransformerTfidfVectorizer ,前者接受 CountVectorizer 生成的稀疏矩阵并将其变换,后者接受文本数据并完成词袋特征提取与 tf-idf 变换。tf-idf 缩放方案有几种变体,你可以在维基百科上阅读相关内容(https://en.wikipedia.org/wiki/Tf-idf )。单词 w 在文档 d 中的 tf-idf 分数在 TfidfTransformer 类和 TfidfVectorizer 类中都有实现,其计算公式如下所示(这里给出这个公式主要是为了完整性,你在使用 tf-idf 时无需记住它):

其中 N 是训练集中的文档数量,Nw 是训练集中出现单词 w 的文档数量,tf (词频)是单词 w 在查询文档 d (你想要变换或编码的文档)中出现的次数。两个类在计算 tf-idf 表示之后都还应用了 L2 范数。换句话说,它们将每个文档的表示缩放到欧几里得范数为 1。利用这种缩放方法,文档长度(单词数量)不会改变向量化表示。

由于 tf-idf 实际上利用了训练数据的统计学属性,所以我们将使用在之前介绍过的管道,以确保网格搜索的结果有效。这样会得到下列代码:

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.pipeline import make_pipeline
pipe = make_pipeline(TfidfVectorizer(min_df=5),LogisticRegression())
param_grid = {'logisticregression__C': [0.001, 0.01, 0.1, 1, 10]}grid = GridSearchCV(pipe, param_grid, cv=5)
grid.fit(text_train, y_train)
print("Best cross-validation score: {:.2f}".format(grid.best_score_))
Best cross-validation score: 0.89

如你所见,使用 tf-idf 代替仅统计词数对性能有所提高。我们还可以查看 tf-idf 找到的最重要的单词。请记住,tf-idf 缩放的目的是找到能够区分文档的单词,但它完全是一种无监督技术。因此,这里的“重要”不一定与我们感兴趣的“正面评论”和“负面评论”标签相关。首先,我们从管道中提取 TfidfVectorizer :

vectorizer = grid.best_estimator_.named_steps["tfidfvectorizer"]
# 变换训练数据集
X_train = vectorizer.transform(text_train)
# 找到数据集中每个特征的最大值
max_value = X_train.max(axis=0).toarray().ravel()
sorted_by_tfidf = max_value.argsort()
# 获取特征名称
feature_names = np.array(vectorizer.get_feature_names_out())print("Features with lowest tfidf:\n{}".format(feature_names[sorted_by_tfidf[:20]]))print("Features with highest tfidf: \n{}".format(feature_names[sorted_by_tfidf[-20:]]))
Features with lowest tfidf:
['suplexes' 'gauche' 'hypocrites' 'oncoming' 'songwriting' 'galadriel''emerald' 'mclaughlin' 'sylvain' 'oversee' 'cataclysmic' 'pressuring''uphold' 'thieving' 'inconsiderate' 'ware' 'denim' 'reverting' 'booed''spacious']
Features with highest tfidf: 
['gadget' 'sucks' 'zatoichi' 'demons' 'lennon' 'bye' 'dev' 'weller''sasquatch' 'botched' 'xica' 'darkman' 'woo' 'casper' 'doodlebops''smallville' 'wei' 'scanners' 'steve' 'pokemon']

tf-idf 较小的特征要么是在许多文档里都很常用,要么就是很少使用,且仅出现在非常长的文档中。有趣的是,许多 tf-idf 较大的特征实际上对应的是特定的演出或电影。这些术语仅出现在这些特定演出或电影的评论中,但往往在这些评论中多次出现。例如,对于 "pokemon" 、"smallville" 和 "doodlebops" 是显而易见的,但这里的 "scanners" 实际上指的也是电影标题。这些单词不太可能有助于我们的情感分类任务(除非有些电影的评价可能普遍偏正面或偏负面),但肯定包含了关于评论的大量具体信息。

我们还可以找到逆向文档频率较低的单词,即出现次数很多,因此被认为不那么重要的单词。训练集的逆向文档频率值被保存在 idf_ 属性中:

sorted_by_idf = np.argsort(vectorizer.idf_)
print("Features with lowest idf:\n{}".format(feature_names[sorted_by_idf[:100]]))
Features with lowest idf:
['the' 'and' 'of' 'to' 'this' 'is' 'it' 'in' 'that' 'but' 'for' 'with''was' 'as' 'on' 'movie' 'not' 'have' 'one' 'be' 'film' 'are' 'you' 'all''at' 'an' 'by' 'so' 'from' 'like' 'who' 'they' 'there' 'if' 'his' 'out''just' 'about' 'he' 'or' 'has' 'what' 'some' 'good' 'can' 'more' 'when''time' 'up' 'very' 'even' 'only' 'no' 'would' 'my' 'see' 'really' 'story''which' 'well' 'had' 'me' 'than' 'much' 'their' 'get' 'were' 'other''been' 'do' 'most' 'don' 'her' 'also' 'into' 'first' 'made' 'how' 'great''because' 'will' 'people' 'make' 'way' 'could' 'we' 'bad' 'after' 'any''too' 'then' 'them' 'she' 'watch' 'think' 'acting' 'movies' 'seen' 'its''him']

正如所料,这些词大多是英语中的停用词,比如 "the" 和 "no" 。但有些单词显然是电影评论特有的,比如 "movie" 、"film" 、"time" 、"story" 等。有趣的是,"good" 、"great" 和 "bad" 也属于频繁出现的单词,因此根据 tf-idf 度量也属于“不太相关”的单词,尽管我们可能认为这些单词对情感分析任务非常重要。

四、研究模型系数

最后,我们详细看一下 Logistic 回归模型从数据中实际学到的内容。由于特征数量非常多(删除出现次数不多的特征之后还有 27 271 个),所以显然我们不能同时查看所有系数。但是,我们可以查看最大的系数,并查看这些系数对应的单词。我们将使用基于 tf-idf 特征训练的最后一个模型。

下面这张条形图(图 7-2)给出了 Logistic 回归模型中最大的 25 个系数与最小的 25 个系数,其高度表示每个系数的大小:

import mglearn
import matplotlib.pyplot as pltmglearn.tools.visualize_coefficients(grid.best_estimator_.named_steps["logisticregression"].coef_,feature_names, n_top_features=40)plt.tight_layout()
plt.savefig('Images/00HandleTextData-01.png', bbox_inches='tight')
plt.show()
图 7-2:在 tf-idf 特征上训练的 Logistic 回归的最大系数和最小系数

左侧的负系数属于模型找到的表示负面评论的单词,而右侧的正系数属于模型找到的表示正面评论的单词。大多数单词都是非常直观的,比如 "worst" (最差)、"waste" (浪费)、"disappointment" (失望)和 "laughable" (可笑)都表示不好的电影评论,而 "excellent" (优秀)、"wonderful" (精彩)、"enjoyable" (令人愉悦)和 "refreshing" (耳目一新)则表示正面的电影评论。有些词的含义不那么明确,比如 "bit" (一点)、"job" (工作)和 "today" (今天),但它们可能是类似 "good job" (做得不错)和“best today ”(今日最佳)等短语的一部分。

五、多个单词的词袋(n 元分词)

使用词袋表示的主要缺点之一是完全舍弃了单词顺序。因此,“it's bad, not good at all”(电影很差,一点也不好)和“it's good, not bad at all”(电影很好,还不错)这两个字符串的词袋表示完全相同,尽管它们的含义相反。将“not”(不)放在单词前面,这只是上下文很重要的一个例子(可能是一个极端的例子)。幸运的是,使用词袋表示时有一种获取上下文的方法,就是不仅考虑单一词例的计数,而且还考虑相邻的两个或三个词例的计数。

两个词例被称为二元分词 (bigram),三个词例被称为三元分词 (trigram),更一般的词例序列被称为 n 元分词 (n -gram)。我们可以通过改变 CountVectorizer 或 TfidfVectorizer 的 ngram_range 参数来改变作为特征的词例范围。ngram_range 参数是一个元组,包含要考虑的词例序列的最小长度和最大长度。下面是在之前用过的玩具数据上的一个示例:

print("bards_words:\n{}".format(bards_words))
bards_words:
['The fool doth think he is wise,', 'but the wise man knows himself to be a fool']

默认情况下,为每个长度最小为 1 且最大为 1 的词例序列(或者换句话说,刚好 1 个词例)创建一个特征——单个词例也被称为一元分词 (unigram):

cv = CountVectorizer(ngram_range=(1, 1)).fit(bards_words)
print("Vocabulary size: {}".format(len(cv.vocabulary_)))
print("Vocabulary:\n{}".format(cv.get_feature_names_out()))
Vocabulary size: 13
Vocabulary:
['be' 'but' 'doth' 'fool' 'he' 'himself' 'is' 'knows' 'man' 'the' 'think''to' 'wise']

要想仅查看二元分词(即仅查看由两个相邻词例组成的序列),可以将 ngram_range 设置为 (2, 2) :

cv = CountVectorizer(ngram_range=(2, 2)).fit(bards_words)
print("Vocabulary size: {}".format(len(cv.vocabulary_)))
print("Vocabulary:\n{}".format(cv.get_feature_names_out()))
Vocabulary size: 14
Vocabulary:
['be fool' 'but the' 'doth think' 'fool doth' 'he is' 'himself to''is wise' 'knows himself' 'man knows' 'the fool' 'the wise' 'think he''to be' 'wise man']

使用更长的词例序列通常会得到更多的特征,也会得到更具体的特征。bard_words 的两个短语中没有相同的二元分词:

print("Transformed data (dense):\n{}".format(cv.transform(bards_words).toarray()))
Transformed data (dense):
[[0 0 1 1 1 0 1 0 0 1 0 1 0 0][1 1 0 0 0 1 0 1 1 0 1 0 1 1]]

对于大多数应用而言,最小的词例数量应该是 1,因为单个单词通常包含丰富的含义。在大多数情况下,添加二元分词会有所帮助。添加更长的序列(一直到五元分词)也可能有所帮助,但这会导致特征数量的大大增加,也可能会导致过拟合,因为其中包含许多非常具体的特征。原则上来说,二元分词的数量是一元分词数量的平方,三元分词的数量是一元分词数量的三次方,从而导致非常大的特征空间。在实践中,更高的 n 元分词在数据中的出现次数实际上更少,原因在于(英语)语言的结构,不过这个数字仍然很大。

下面是在 bards_words 上使用一元分词、二元分词和三元分词的结果:

cv = CountVectorizer(ngram_range=(1, 3)).fit(bards_words)print("Vocabulary size: {}".format(len(cv.vocabulary_)))
print("Vocabulary:\n{}".format(cv.get_feature_names_out()))
Vocabulary size: 39
Vocabulary:
['be' 'be fool' 'but' 'but the' 'but the wise' 'doth' 'doth think''doth think he' 'fool' 'fool doth' 'fool doth think' 'he' 'he is''he is wise' 'himself' 'himself to' 'himself to be' 'is' 'is wise''knows' 'knows himself' 'knows himself to' 'man' 'man knows''man knows himself' 'the' 'the fool' 'the fool doth' 'the wise''the wise man' 'think' 'think he' 'think he is' 'to' 'to be' 'to be fool''wise' 'wise man' 'wise man knows']

我们在 IMDb 电影评论数据上尝试使用 TfidfVectorizer ,并利用网格搜索找出 n 元分词的最佳设置:

pipe = make_pipeline(TfidfVectorizer(min_df=5), LogisticRegression())
# 运行网格搜索需要很长时间,因为网格相对较大,且包含三元分词
param_grid = {"logisticregression__C": [0.001, 0.01, 0.1, 1, 10, 100],"tfidfvectorizer__ngram_range": [(1, 1), (1, 2), (1, 3)]}grid = GridSearchCV(pipe, param_grid, cv=5)
grid.fit(text_train, y_train)
print("Best cross-validation score: {:.2f}".format(grid.best_score_))
print("Best parameters:\n{}".format(grid.best_params_))
Best cross-validation score: 0.91
Best parameters:
{'logisticregression__C': 100, 'tfidfvectorizer__ngram_range': (1, 3)}

从结果中可以看出,我们添加了二元分词特征与三元分词特征之后,性能提高了一个百分点多一点。我们可以将交叉验证精度作为 ngram_range 和 C 参数的函数并用热图可视化,正如我们在之前所做的那样(见图 7-3):

def drawHeatmap(scores, xlabel,ylabel='True label', fmt='{:0.2f}', colorbar=None):# 反转scores数组的行顺序,以便(0, 0)在左下角  scores = scores[::-1, :]  # 绘制热图  fig, ax = plt.subplots()  if(colorbar is None):colorbar = scorescax = ax.matshow(colorbar, cmap='viridis')  fig.colorbar(cax)  # 假设param_grid['gamma']和param_grid['C']已经定义  # 这里我们使用字符串列表作为示例  param_grid = {  'gamma': ['0.001','0.01', '0.1', '1', '10', '100'],  'C':   ['(1,1)','(1,2)','(1,3)']}  # 设置xticks和yticks的位置  ticks_x = np.arange(len(param_grid['gamma']))  ticks_y = np.arange(len(param_grid['C']))[::-1]  # 反转yticks的顺序以匹配反转的scores  # 设置xticklabels和yticklabels  ax.set_xticks(ticks_x)  ax.set_xticklabels(param_grid['gamma'])  ax.xaxis.set_tick_params(rotation=45)  ax.set_yticks(ticks_y)  ax.set_yticklabels(param_grid['C'])  # 设置x轴和y轴的标签  ax.set_xlabel(xlabel)  ax.set_ylabel(ylabel)  # 添加数值到每个单元格  for (i, j), z in np.ndenumerate(scores):  ax.text(j, i, fmt.format(z), ha='center', va='center')  # 从网格搜索中提取分数
scores = grid.cv_results_['mean_test_score'].reshape(-1, 3).T
# 热图可视化
# heatmap = mglearn.tools.heatmap(
#    scores, xlabel="C", ylabel="ngram_range", cmap="viridis", fmt="%.3f",
#    xticklabels=param_grid['logisticregression__C'],
#    yticklabels=param_grid['tfidfvectorizer__ngram_range'])drawHeatmap(scores,xlabel="C", ylabel="ngram_range",fmt='{:0.3f}')plt.tight_layout()
plt.savefig('Images/00HandleTextData-02.png', bbox_inches='tight')
plt.show()
图 7-3:交叉验证平均精度作为参数 ngram_range 和 C 的函数的热图可视化

从热图中可以看出,使用二元分词对性能有很大提高,而添加三元分词对精度只有很小贡献。为了更好地理解模型是如何改进的,我们可以将最佳模型的重要系数可视化,其中包含一元分词、二元分词和三元分词(见图 7-4):

# 提取特征名称与系数
vect = grid.best_estimator_.named_steps['tfidfvectorizer']
feature_names = np.array(vect.get_feature_names_out())
coef = grid.best_estimator_.named_steps['logisticregression'].coef_
mglearn.tools.visualize_coefficients(coef, feature_names, n_top_features=40)plt.tight_layout()
plt.savefig('Images/00HandleTextData-03.png', bbox_inches='tight')
plt.show()
图 7-4:同时使用 tf-idf 缩放与一元分词、二元分词和三元分词时的最重要特征

有几个特别有趣的特征,它们包含单词 "worth" (值得),而这个词本身并没有出现在一元分词模型中:"not worth" (不值得)表示负面评论,而 "definitely worth" (绝对值得)和 "well worth" (很值得)表示正面评论。这是上下文影响 "worth" 一词含义的主要示例。

接下来,我们只将三元分词可视化,以进一步深入了解这些特征有用的原因。许多有用的二元分词和三元分词都由常见的单词组成,这些单词本身可能没有什么信息量,比如 "none of the" (没有一个)、"the only good" (唯一好的)、"on and on" (不停地)、"this is one" (这是一部)、"of the most" (最)等短语中的单词。但是,与一元分词特征的重要性相比,这些特征的影响非常有限,正如图 7-5 所示。

# 找到三元分词特征
mask = np.array([len(feature.split(" ")) for feature in feature_names]) == 3
# 仅将三元分词特征可视化
mglearn.tools.visualize_coefficients(coef.ravel()[mask],feature_names[mask], n_top_features=40)plt.tight_layout()
plt.savefig('Images/00HandleTextData-04.png', bbox_inches='tight')
plt.show()
图 7-5:仅将对模型重要的三元分词特征可视化

六、高级分词、词干提取与词形还原

如前所述,CountVectorizerTfidfVectorizer 中的特征提取相对简单,还有更为复杂的方法。在更加复杂的文本处理应用中,通常需要改进的步骤是词袋模型的第一步:分词(tokenization)。这一步骤为特征提取定义了一个单词是如何构成的。

我们前面看到,词表中通常同时包含某些单词的单数形式和复数形式,比如 "drawback""drawbacks""drawer""drawers""drawing""drawings" 。对于词袋模型而言,"drawback""drawbacks" 的语义非常接近,区分二者只会增加过拟合,并导致模型无法充分利用训练数据。同样我们还发现,词表中包含像 "replace""replaced""replace ment""replaces""replacing" 这样的单词,它们都是动词“to replace”的不同动词形式或相关名词。与名词的单复数形式一样,将不同的动词形式及相关单词视为不同的词例,这不利于构建具有良好泛化性能的模型。

这个问题可以通过用词干 (word stem)表示每个单词来解决,这一方法涉及找出 [ 或合并 (conflate)] 所有具有相同词干的单词。如果使用基于规则的启发法来实现(比如删除常见的后缀),那么通常将其称为词干提取 (stemming)。如果使用的是由已知单词形式组成的字典(明确的且经过人工验证的系统),并且考虑了单词在句子中的作用,那么这个过程被称为词形还原 (lemmatization),单词的标准化形式被称为词元 (lemma)。词干提取和词形还原这两种处理方法都是标准化 (normalization)的形式之一,标准化是指尝试提取一个单词的某种标准形式。标准化的另一个有趣的例子是拼写校正,这种方法在实践中很有用,但超出了本书的范围。

为了更好地理解标准化,我们来对比一种词干提取方法(Porter 词干提取器,一种广泛使用的启发法集合,从 nltk 包导入)与 spacy 包 (安装 spacy 包之后需要下载相应的语言包,你可以在命令行输入 python3 -m spacy download en 来下载英语语言包) 中实现的词形还原(想了解接口的细节,请参阅 nltk (NLTK :: Natural Language Toolkit )和 spacy (spaCy · Industrial-strength Natural Language Processing in Python )的文档。我们这里更关注一般性原则):

import spacy
import nltk# 加载spacy的英语模型
en_nlp = spacy.load('en_core_web_sm')
# 将nltk的Porter词干提取器实例化
stemmer = nltk.stem.PorterStemmer()# 定义一个函数来对比spacy中的词形还原与nltk中的词干提取
def compare_normalization(doc):# 在spacy中对文档进行分词doc_spacy = en_nlp(doc)# 打印出spacy找到的词元print("Lemmatization:")print([token.lemma_ for token in doc_spacy])# 打印出Porter词干提取器找到的词例print("Stemming:")print([stemmer.stem(token.norm_.lower()) for token in doc_spacy])

我们将用一个句子来比较词形还原与 Porter 词干提取器,以显示二者的一些区别(1.7.5 版的 spacy 将 'our' 、'i' 等代词全部还原为 '-PRON-' ,详情请参见 spacy 官方文档):

compare_normalization(u"Our meeting today was worse than yesterday, ""I'm scared of meeting the clients tomorrow.")
Lemmatization:
['our', 'meeting', 'today', 'be', 'bad', 'than', 'yesterday', ',', 'I', 'be', 'scared', 'of', 'meet', 'the', 'client', 'tomorrow', '.']
Stemming:
['our', 'meet', 'today', 'wa', 'wors', 'than', 'yesterday', ',', 'i', 'am', 'scare', 'of', 'meet', 'the', 'client', 'tomorrow', '.']

词干提取总是局限于将单词简化成词干,因此 "was" 变成了 "wa" ,而词形还原可以得到正确的动词基本词形 "be" 。同样,词形还原可以将 "worse" 标准化为 "bad" ,而词干提取得到的是 "wors" 。另一个主要区别在于,词干提取将两处 "meeting" 都简化为 "meet" 。利用词形还原,第一处 "meeting" 被认为是名词,所以没有变化,而第二处 "meeting" 被认为是动词,所以变为 "meet" 。一般来说,词形还原是一个比词干提取更复杂的过程,但用于机器学习的词例标准化时通常可以给出比词干提取更好的结果。

虽然 scikit-learn 没有实现这两种形式的标准化,但 CountVectorizer 允许使用 tokenizer 参数来指定使用你自己的分词器将每个文档转换为词例列表。我们可以使用 spacy 的词形还原了创建一个可调用对象,它接受一个字符串并生成一个词元列表:

# 技术细节:我们希望使用由CountVectorizer所使用的基于正则表达式的分词器,
# 并仅使用spacy的词形还原。
# 为此,我们将en_nlp.tokenizer(spacy分词器)替换为基于正则表达式的分词。
# 引入 CountVectorizer
from sklearn.feature_extraction.text import CountVectorizer
import re
# 在CountVectorizer中使用的正则表达式
regexp = re.compile('(?u)\\b\\w\\w+\\b')# 加载spacy语言模型,并保存旧的分词器
en_nlp = spacy.load('en_core_web_sm')
old_tokenizer = en_nlp.tokenizer
# 将分词器替换为前面的正则表达式
en_nlp.tokenizer = lambda string: old_tokenizer.tokens_from_list(regexp.findall(string))# 用spacy文档处理管道创建一个自定义分词器
# (现在使用我们自己的分词器)
def custom_tokenizer(document):doc_spacy = en_nlp(document, entity=False, parse=False)return [token.lemma_ for token in doc_spacy]# 利用自定义分词器来定义一个计数向量器
lemma_vect = CountVectorizer(tokenizer=custom_tokenizer, min_df=5)

我们变换数据并检查词表的大小:

text_train = reviews_train.data
# 利用带词形还原的CountVectorizer对text_train进行变换
X_train_lemma = lemma_vect.fit_transform(text_train)
print("X_train_lemma.shape: {}".format(X_train_lemma.shape))# 标准的CountVectorizer,以供参考
vect = CountVectorizer(min_df=5).fit(text_train)
X_train = vect.transform(text_train)
print("X_train.shape: {}".format(X_train.shape))
X_train_lemma.shape: (25000, 91079)
X_train.shape: (25000, 27272)

从输出中可以看出,词形还原将特征数量从 27 271 个(标准的 CountVectorizer 处理过程)减少到 21 596 个。词形还原可以被看作是一种正则化,因为它合并了某些特征。因此我们预计,数据集很小时词形还原对性能的提升最大。为了说明词形还原的作用,我们将使用 StratifiedShuffleSplit 做交叉验证,仅使用 1% 的数据作为训练数据,其余数据作为测试数据:

# 仅使用1%的数据作为训练集来构建网格搜索
from sklearn.model_selection import StratifiedShuffleSplitparam_grid = {'C': [0.001, 0.01, 0.1, 1, 10]}
cv = StratifiedShuffleSplit(n_splits=5, test_size=0.99,train_size=0.01, random_state=0)
grid = GridSearchCV(LogisticRegression(), param_grid, cv=cv)
# 利用标准的CountVectorizer进行网格搜索
grid.fit(X_train, y_train)
print("Best cross-validation score ""(standard CountVectorizer): {:.3f}".format(grid.best_score_))
# 利用词形还原进行网格搜索
grid.fit(X_train_lemma, y_train)
print("Best cross-validation score ""(lemmatization): {:.3f}".format(grid.best_score_))
Best cross-validation score (standard CountVectorizer): 0.717
Best cross-validation score (lemmatization): 0.743

在这个例子中,词形还原对性能有较小的提高。与许多特征提取技术一样,其结果因数据集的不同而不同。词形还原与词干提取有时有助于构建更好的模型(或至少是更简洁的模型),所以我们建议你,在特定任务中努力提升最后一点性能时可以尝试下这些技术。

七、主题建模与文档聚类

常用于文本数据的一种特殊技术是主题建模 (topic modeling),这是描述将每个文档分配给一个或多个主题的任务(通常是无监督的)的概括性术语。这方面一个很好的例子是新闻数据,它们可以被分为“政治”“体育”“金融”等主题。如果为每个文档分配一个主题,那么这是一个文档聚类任务。如果每个文档可以有多个主题,那么这个任务与之前的分解方法有关。我们学到的每个成分对应于一个主题,文档表示中的成分系数告诉们这个文档与该主题的相关性强弱。通常来说,人们在谈论主题建模时,他们指的是一种叫作隐含狄利克雷分布 (Latent Dirichlet Allocation,LDA)的特定分解方法。

1、隐含狄利克雷分布

从直观上来看,LDA 模型试图找出频繁共同出现的单词群组(即主题)。LDA 还要求,每个文档可以被理解为主题子集的“混合”。重要的是要理解,机器学习模型所谓的“主题”可能不是我们通常在日常对话中所说的主题,而是更类似于 PCA 或 NMF 所提取的成分,它可能具有语义,也可能没有。即使 LDA“主题”具有语义,它可能也不是我们通常所说的主题。回到新闻文章的例子,我们可能有许多关于体育、政治和金融的文章,由两位作者所写。在一篇政治文章中,我们预计可能会看到“州长”“投票”“党派”等词语,而在一篇体育文章中,我们预计可能会看到类似“队伍”“得分”和“赛季”之类的词语。这两组词语可能会同时出现,而例如“队伍”和“州长”就不太可能同时出现。但是,这并不是我们预计可能同时出现的唯一的单词群组。这两位记者可能偏爱不同的短语或者选择不同的单词。可能其中一人喜欢使用“划界”(demarcate)这个词,而另一人喜欢使用“两极分化”(polarize)这个词。其他“主题”可能是“记者 A 常用的词语”和“记者 B 常用的词语”,虽然这并不是通常意义上的主题。

我们将 LDA 应用于电影评论数据集,来看一下它在实践中的效果。对于无监督的文本文档模型,通常最好删除非常常见的单词,否则它们可能会支配分析过程。我们将删除至少在 15% 的文档中出现过的单词,并在删除前 15% 之后,将词袋模型限定为最常见的 10 000 个单词(还有另一种机器学习模型通常也简称为 LDA,那就是线性判别分析(Linear Discriminant Analysis),一种线性分类模型。这造成了很多混乱。在本书中,LDA 是指隐含狄利克雷分布。):


vect = CountVectorizer(max_features=10000, max_df=.15)
X = vect.fit_transform(text_train)

我们将学习一个包含 10 个主题的主题模型,它包含的主题个数很少,我们可以查看所有主题。与 NMF 中的分量类似,主题没有内在的顺序,而改变主题数量将会改变所有主题(事实上,NMF 和 LDA 解决的是非常相关的问题,我们也可以用 NMF 来提取主题)。 我们将使用 "batch" 学习方法,它比默认方法("online" )稍慢,但通常会给出更好的结果。我们还将增大 max_iter ,这样会得到更好的模型:

from sklearn.decomposition import LatentDirichletAllocation
# 创建 LDA 模型实例
lda = LatentDirichletAllocation(n_components=10, learning_method="batch",max_iter=25, random_state=0)
# 我们在一个步骤中构建模型并变换数据
# 计算变换需要花点时间,二者同时进行可以节省时间
document_topics = lda.fit_transform(X)

与之前中所讲的分解方法类似,LatentDirichletAllocation 有一个 components_ 属性,其中保存了每个单词对每个主题的重要性。components_ 的大小为 (n_topics, n_words) :


lda.components_.shape
(10, 10000)

为了更好地理解不同主题的含义,我们将查看每个主题中最重要的单词。print_topics 函数为这些特征提供了良好的格式:

# 对于每个主题(components_的一行),将特征排序(升序)
# 用[:, ::-1]将行反转,使排序变为降序
sorting = np.argsort(lda.components_, axis=1)[:, ::-1]
# 从向量器中获取特征名称
feature_names = np.array(vect.get_feature_names_out())# 打印出前10个主题:
mglearn.tools.print_topics(topics=range(10), feature_names=feature_names,sorting=sorting, topics_per_chunk=5, n_words=10)
topic 0       topic 1       topic 2       topic 3       topic 4       
--------      --------      --------      --------      --------      
director      show          book          family        funny         
work          series        original      young         comedy        
performance   war           10            father        cast          
actors        episode       now           us            role          
cast          tv            again         woman         humor         
screen        years         world         own           fun           
performances  american      saw           world         jokes         
role          episodes      read          real          actors        
both          world         didn          mother        performance   
quite         shows         am            between       always        topic 5       topic 6       topic 7       topic 8       topic 9       
--------      --------      --------      --------      --------      
horror        music         original      thing         action        
gore          john          team          worst         police        
effects       old           series        didn          murder        
blood         young         jack          nothing       killer        
pretty        girl          action        minutes       crime         
budget        song          new           guy           plays         
house         gets          down          actually      lee           
zombie        dance         tarzan        want          gets          
dead          songs         freddy        going         role          
low           rock          indian        re            cop   

从重要的单词来看,主题 1 似乎是关于历史和战争的电影,主题 2 可能是关于糟糕的喜剧,主题 3 可能是关于电视连续剧,主题 4 可能提取了一些非常常见的单词,而主题 6 似乎是关于儿童电影,主题 8 似乎提取了与获奖相关的评论。仅使用 10 个主题,每个主题都需要非常宽泛,才能共同涵盖我们的数据集中所有不同类型的评论。

接下来,我们将学习另一个模型,这次包含 100 个主题。使用更多的主题,将使得分析过程更加困难,但更可能使主题专门针对于某个有趣的数据子集:

lda100 = LatentDirichletAllocation(n_components=100, learning_method="batch",max_iter=25, random_state=0)
document_topics100 = lda100.fit_transform(X)

查看所有 100 个主题可能有点困难,所以我们选取了一些有趣的而且有代表性的主题:

topics = np.array([7, 16, 24, 25, 28, 36, 37, 45, 51, 53, 54, 63, 89, 97])sorting = np.argsort(lda100.components_, axis=1)[:, ::-1]
feature_names = np.array(vect.get_feature_names_out())
mglearn.tools.print_topics(topics=topics, feature_names=feature_names,sorting=sorting, topics_per_chunk=7, n_words=20)
topic 7       topic 16      topic 24      topic 25      topic 28      topic 36      topic 37      
--------      --------      --------      --------      --------      --------      --------      
drew          didn          ben           emma          years         role          ship          
baseball      going         lines         elvira        saw           oscar         titanic       
maria         seemed        actors        jeremy        again         award         crew          
sports        things        director      hudson        remember      actor         day           
whale         doesn         audience      paltrow       ago           picture       world         
ben           interesting   every         sirk          now           won           air           
red           nothing       worst         austen        watched       roles         sea           
angels        bit           without       bacall        old           supporting    lost          
barrymore     lot           simply        mr            am            academy       plane         
pitch         felt          dialogue      kyle          since         nominated     macarthur     
fever         thing         parody        malone        before        performance   events        
frankie       seems         us            thompson      last          grant         real          
sox           ending        script        stack         didn          winning       death         
team          might         self          dorothy       few           cast          war           
irish         work          less          preston       came          actors        earth         
wendigo       feel          care          wind          year          year          captain       
deaf          though        attempt       robert        day           years         disaster      
casper        actually      mind          written       thought       century       james         
deer          thought       shallow       jane          found         three         water         
gypo          quite         imagine       toni          find          comedy        london        topic 45      topic 51      topic 53      topic 54      topic 63      topic 89      topic 97      
--------      --------      --------      --------      --------      --------      --------      
documentary   world         moon          show          drugs         jack          our           
footage       green         mike          shows         drug          king          us            
festival      new           columbo       tv            freeman       hotel         human         
interviews    bus           cat           television    money         stephen       world         
documentaries heston        hat           episode       disturbing    kubrick       own           
media         streets       mel           season        real          shining       reality       
interesting   panic         mst3k         episodes      experiment    nicholson     every         
stooges       city          brooks        always        ll            danny         real          
subject       orleans       cassidy       air           morgan        stanley       mind          
history       health        austin        funny         abuse         wendy         need          
chavez        palance       hyde          program       rat           wang          understand    
wrestling     plague        baldwin       reality       rats          zombi         feel          
scorsese      3d            skull         every         spacey        gere          want          
shorts        director      tall          lot           less          room          things        
making        macy          ho            new           10            flock         different     
verhoeven     kazan         myers         abc           justin        claire        nature        
gerard        around        cure          seasons       nothing       bruno         lives         
christine     mario         gackt         now           kevin         birds         without       
international soylent       full          sitcom        addicted      snow          soul          
narration     big           ken           real          timberlake    find          makes     

这次我们提取的主题似乎更加具体,不过很多都难以解读。主题 7 似乎是关于恐怖电影和惊悚片,主题 16 和 54 似乎是关于不好的评论,而主题 63 似乎主要是关于喜剧的正面评论。如果想要利用发现的主题做出进一步的推断,那么我们应该查看分配给这些主题的文档,以验证我们通过查看每个主题排名最靠前的单词所得到的直觉。例如,主题 45 似乎是关于音乐的。我们来查看哪些评论被分配给了这个主题:

# 按主题45“music”进行排序
music = np.argsort(document_topics100[:, 45])[::-1]
# 打印出这个主题最重要的前5个文档
for i in music[:10]:# 显示前两个句子print(b".".join(text_train[i].split(b".")[:2]) + b".\n")
b"This movie is basically a documentary of the chronologically ordered series of events that took place from April 10, 2002 through April 14, 2002 in the Venezuelan Presidential Palace, Caracas Venezuela.<br /><br />The pathos of the movie is real and one feels the pain, sorrow and joy of the people who lived through this failed coup d'etat of President Hugo Chavez.\n"
b'Reviewed at the World Premiere screening Sept. 9, 2006 at the Isabel Bader Theatre during the Toronto International Film Festival (TIFF).\n'
b'Moe and Larry are newly henpecked husbands, having married Shemp\'s demanding sisters. At his music studio, Shemp learns he will inherit a fortune if he marries someone himself! <br /><br />"Husbands Beware" is a remake of 1947\'s "Brideless Groom," widely considered by many to be one of the best Stooge films with Shemp.\n'
b'Sharp, well-made documentary focusing on Mardi Gras beads. I have always liked this approach to film-making - communicate ideas about a larger, more complex, and often inscrutable phenomenon by breaking the issue down into something familiar and close to home.\n'
b"This is a great movie, it shows what our government will to to other countries if we don't like their government. This isn't as bad as what Reagan and Bush number one did to South America, but the US still has no business messing around with other countries like this.\n"
b'Another good Stooge short!Christine McIntyre is so lovely and evil and the same time in this one!She is such a great actress!The Stooges are very good and especially Shemp and Larry!This to is a good one to watch around Autumn time!.\n'
b'"Why did they make them so big? Why didn\'t they just give the money to the poor?" The question about cathedrals was asked by a student to Mr. Harvey during a school field trip to Salisbury Cathedral.\n'
b'In Micro Phonies the stooges are at there best. In this short the trio are handymen working in a recording studio.\n'
b'This documentary has been aired on both RTE and BBC in the last number of months. Having seen it twice now I would recommend it to anyone with an interest in media and documentary film making.\n'
b'This three stooges flick is at a tie with my other favorite flick "Disorder in the Court". This is an uproar of laughter for any Three Stooges fan to enjoy.\n'

可以看出,这个主题涵盖许多以音乐为主的评论,从音乐剧到传记电影,再到最后一条评论中难以归类的类型。查看主题还有一种有趣的方法,就是通过对所有评论的 document_topics 进行求和来查看每个主题所获得的整体权重。我们用最常见的两个单词为每个主题命名。图 7-6 给出了学到的主题权重:

fig, ax = plt.subplots(1, 2, figsize=(10, 10))
topic_names = ["{:>2} ".format(i) + " ".join(words)for i, words in enumerate(feature_names[sorting[:, :2]])]
# 两列的条形图:
for col in [0, 1]:start = col * 50end = (col + 1) * 50ax[col].barh(np.arange(50), np.sum(document_topics100, axis=0)[start:end])ax[col].set_yticks(np.arange(50))ax[col].set_yticklabels(topic_names[start:end], ha="left", va="top")ax[col].invert_yaxis()ax[col].set_xlim(0, 2000)yax = ax[col].get_yaxis()yax.set_tick_params(pad=130)plt.tight_layout()
plt.savefig('Images/00HandleTextData-05.png', bbox_inches='tight')
plt.show()
图 7-6:LDA 学到的主题权重

最重要的主题是主题 97,它可能主要包含停用词,可能还有一些稍负面的单词;主题 16 明显是有关负面评论的;然后是一些特定类型的主题与主题 36 和 37,这二者似乎都包含表示赞美的单词。

除了几个不太具体的主题之外,LDA 似乎主要发现了两种主题:特定类型的主题与特定评分的主题。这是一个有趣的发现,因为大部分评论都由一些与电影相关的评论与一些证明或强调评分的评论组成。

在没有标签的情况下(或者像本章的例子这样,即使有标签的情况下),像 LDA 这样的主题模型是理解大型文本语料库的有趣方法。不过 LDA 算法是随机的,改变 random_state 参数可能会得到完全不同的结果。虽然找到主题可能很有用,但对于从无监督模型中得出的任何结论都应该持保留态度,我们建议通过查看特定主题中的文档来验证你的直觉。 LDA.transform 方法生成的主题有时也可以用于监督学习的紧凑表示。当训练样例很少时,这一方法特别有用。

附录:

一、参考文献

参考文献:[德] Andreas C. Müller [美] Sarah Guido 《Python Machine Learning Basics Tutorial》

二、spacy 环境配置

1、spacy 如何安装,以及数据集使用,官网介绍如下

https://github.com/explosion/spacy-models/releases

进入后,可以看到如下界面,并下载支持对应spacy版本的Spacy-models;

此处的  lg 为large的缩写,根据spacy官方文档的解读,

模型指示符 如英文模型en,

后缀为 sm:en_core_web_sm-3.7.1 代表 small 模型;

后缀为 md: 代表 middle 模型;

后缀为 lg: 代表 large 模型;

后缀为 trf: 代表涵盖 transformer 模型;

2、选择需要的模型并找到适合的版本号下载

建议直接按照如下方式 下载到本地(放到python解释器安装的目录,经测试这样的下载速度较快。

查看python解释器安装目录指令:

python -c "import sys; print(sys.executable)"

3、这里以en_core_web_sm-3.5.0 为例

en_core_web_sm-3.5.0地址:Release en_core_web_sm-3.5.0 · explosion/spacy-models · GitHub

首先安装 spacy ,pip install spacy

然后 下载 en_core_web_sm 数据,python -m spacy download en_core_web_sm

如果下载 en_core_web_sm 数据,报如下类似的错:

requests.exceptions.SSLError: HTTPSConnectionPool(host='raw.githubusercontent.com', port=443): Max retries exceeded with url: /explosion/spacy-models/master/compatib ility.json (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl. c:992)')))

4、下载 en_core_web_sm-3.5.0-py3-none-any.whl

5、可以在安装了spacy 的环境中,安装下载的 en_core_web_sm-3.5.0-py3-none-any.whl

pip install en_core_web_sm-3.5.0-py3-none-any.whl

6、使用下面代码,运行检验即可

import spacynlp = spacy.load("en_core_web_lg")

如果上两行代码运行都未报错,即表明安装spacy成功,模型可以正常调用。

这篇关于Python 机器学习 基础 之 处理文本数据 【停用词/用tf-idf缩放数据/模型系数/多个单词的词袋/高级分词/主题建模/文档聚类】的简单说明的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1021230

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd