求助:NLP中用Python对数据集Text列分词以实现词袋模型
分词并构建词袋模型的解决方案
方法一:直接用Scikit-learn构建词袋(最简便)
如果你只是为了得到词袋模型,不需要单独保存分词结果,直接用sklearn.feature_extraction.text.CountVectorizer就能一步完成分词+词袋矩阵生成,它会自动处理分词、停用词过滤、小写转换等操作:
import pandas as pd from sklearn.feature_extraction.text import CountVectorizer # 假设你的数据集是pandas DataFrame,名为df df = pd.read_csv("your_dataset.csv") # 替换成你的数据加载方式 # 初始化CountVectorizer,可根据需求调整参数 vectorizer = CountVectorizer( stop_words='english', # 去除英文停用词,中文可去掉此参数 lowercase=True, # 转为小写 token_pattern=r'\b\w+\b' # 分词规则,默认即可 ) # 拟合文本数据并转换为词袋矩阵 bag_of_words = vectorizer.fit_transform(df['Text']) # 查看词袋对应的词汇表 vocabulary = vectorizer.get_feature_names_out() # 词袋矩阵是稀疏矩阵,可转为密集矩阵查看 dense_bow = bag_of_words.toarray()
方法二:手动分词后再构建词袋
如果需要先单独得到每个句子的分词结果,再构建词袋,可以用以下工具库处理,注意:不要用loc做逐行文本处理,loc是用于定位行列的选择器,逐行处理文本应该用apply方法:
1. 用NLTK分词(英文)
import pandas as pd import nltk from nltk.tokenize import word_tokenize from sklearn.feature_extraction.text import CountVectorizer # 先下载NLTK的分词模型(首次运行需要) nltk.download('punkt') # 定义分词函数 def tokenize_text(text): return word_tokenize(text.lower()) # 转为小写后分词 # 对Text列逐行分词,得到分词后的列表列 df['Tokenized_Text'] = df['Text'].apply(tokenize_text) # 如果要基于分词结果构建词袋,需要把分词列表转回字符串(因为CountVectorizer接收字符串输入) df['Tokenized_Text_String'] = df['Tokenized_Text'].apply(lambda x: ' '.join(x)) vectorizer = CountVectorizer() bag_of_words = vectorizer.fit_transform(df['Tokenized_Text_String'])
2. 用SpaCy分词(英文/多语言)
import pandas as pd import spacy # 加载SpaCy的英文模型(首次运行需要下载:python -m spacy download en_core_web_sm) nlp = spacy.load("en_core_web_sm") def tokenize_text(text): doc = nlp(text.lower()) # 过滤掉标点和停用词,只保留实义词 return [token.text for token in doc if not token.is_stop and not token.is_punct] df['Tokenized_Text'] = df['Text'].apply(tokenize_text)
3. 中文分词(用Jieba)
如果你的文本是中文,改用Jieba分词:
import pandas as pd import jieba def tokenize_text(text): # 精确模式分词,可添加自定义词典 return jieba.lcut(text) df['Tokenized_Text'] = df['Text'].apply(tokenize_text)
为什么用loc没成功?
loc的作用是定位DataFrame的特定行、列或单元格,比如df.loc[0, 'Text']是取第一行的Text值,但它不适合对整列的每个元素做批量的文本处理操作。处理整列文本的分词,应该用apply(逐行应用函数)或map方法,这才是针对列元素级操作的正确方式。
内容的提问来源于stack exchange,提问作者Pranav
相关产品推荐
相关产品推荐

