(2-1)基于内容的推荐:文本特征提取

基于内容的推荐是一种推荐系统的方法,它基于物品(如文章、音乐、电影等)的内容特征和用户的偏好,为用户提供个性化的推荐。这种推荐方法主要依靠对物品的内容进行分析和比较,以确定物品之间的相似性和用户的兴趣匹配度。在本章的内容中,将详细讲解基于内容推荐的知识。

2.1  文本特征提取

文本特征提取是将文本数据转换为可供机器学习算法或其他自然语言处理任务使用的特征表示的过程。文本特征提取的目标是将文本中的信息转化为数值或向量形式,以便计算机可以理解和处理。

2.1.1  词袋模型(Bag-of-Words)

词袋模型(Bag-of-Words)是一种常用的文本特征表示方法,用于将文本转换为数值形式,以便于机器学习算法的处理。它基于假设,认为文本中的词语顺序并不重要,只关注词语的出现频率。词袋模型的基本思想是将文本视为一个袋子(或集合)并忽略其词语之间的顺序。在构建词袋模型时,首先需要进行以下几个步骤:

  1. 分词(Tokenization):将文本划分为词语或其他有意义的单元。通常使用空格或标点符号来分隔词语。
  2. 构建词表(Vocabulary):将文本中的所有词语收集起来构建一个词表,其中每个词语都对应一个唯一的索引。
  3. 计算词频(Term Frequency):对于每个文本样本,统计每个词语在该样本中出现的频率。可以用一个向量表示每个样本的词频,其中向量的维度与词表的大小相同。

通过上述步骤,可以将每个文本样本转换为一个向量,其中向量的每个维度表示对应词语的出现频率或其他相关特征。这样就可以将文本数据转换为数值形式,供机器学习算法使用。

词袋模型的优点是简单易用,适用于大规模文本数据,并能够捕捉到词语的出现频率信息。然而,词袋模型忽略了词语之间的顺序和上下文信息,可能丢失了一部分语义和语境的含义。

注意:词袋模型的优点是简单易用,适用于大规模文本数据,并能够捕捉到词语的出现频率信息。然而,词袋模型忽略了词语之间的顺序和上下文信息,可能丢失了一部分语义和语境的含义。

在Python程序中,有多种工具和库可用于实现词袋模型,具体说明如下。

(1)Scikit-Learn

在Scikit-Learn中提供了用于实现文本特征提取的类CountVectorizer和TfidfVectorizer,例如下面的实例演示了使用Scikit-Learn实现词袋模型,并基于相似度计算进行推荐。读者可以根据自己的具体数据集和应用场景,自定义和扩展这个例子,构建更复杂和个性化的推荐系统。

源码路径:daima/2/skci.py

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics.pairwise import cosine_similarity

# 电影数据集
movies = [
    'The Shawshank Redemption',
    'The Godfather',
    'The Dark Knight',
    'Pulp Fiction',
    'Fight Club'
]

# 电影简介数据集
synopsis = [
    'Two imprisoned men bond over a number of years, finding solace and eventual redemption through acts of common decency.',
    'The aging patriarch of an organized crime dynasty transfers control of his clandestine empire to his reluctant son.',
    'When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, Batman must accept one of the greatest psychological and physical tests of his ability to fight injustice.',
    'The lives of two mob hitmen, a boxer, a gangster and his wife, and a pair of diner bandits intertwine in four tales of violence and redemption.',
    'An insomniac office worker and a devil-may-care soapmaker form an underground fight club that evolves into something much, much more.'
]

# 构建词袋模型
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(synopsis)

# 计算文本之间的相似度
similarity_matrix = cosine_similarity(X)

# 选择一个电影,获取相似推荐
movie_index = 0  # 选择第一部电影作为例子
similar_movies = similarity_matrix[movie_index].argsort()[::-1][1:]

print(f"根据电影 '{movies[movie_index]}' 推荐的相似电影:")
for movie in similar_movies:
    print(movies[movie])

在上述代码中,首先定义了一个包含电影标题和简介的数据集。然后使用Scikit-Learn类CountVectorizer来构建词袋模型,将文本数据转换为词频向量表示。接下来,使用cosine_similarity计算文本之间的余弦相似度,得到一个相似度矩阵。最后,选择一个电影,根据其在相似度矩阵中的索引,获取相似度最高的电影推荐。执行后会输出:

根据电影 'The Shawshank Redemption' 推荐的相似电影:
Pulp Fiction
The Dark Knight
The Godfather
Fight Club

(2)NLTK

在库NLTK中提供了用于实现文本分词和特征提取的函数和工具,例如下面是一个使用NLTK实现词袋模型的基础例子,假设现在有一个电影评论数据集,我们希望根据评论内容来进行情感分类。

源码路径:daima/2/nldk.py

# 下载电影评论数据集
nltk.download('movie_reviews')

# 加载电影评论数据集
reviews = [(list(movie_reviews.words(fileid)), category)
           for category in movie_reviews.categories()
           for fileid in movie_reviews.fileids(category)]

# 构建词袋模型
all_words = [word.lower() for review in reviews for word in review[0]]
all_words_freq = FreqDist(all_words)
word_features = list(all_words_freq)[:2000]

# 定义特征提取函数
def extract_features(document):
    document_words = set(document)
    features = {}
    for word in word_features:
        features[word] = (word in document_words)
    return features

# 构建特征集
featuresets = [(extract_features(review), category) for (review, category) in reviews]

# 划分训练集和测试集
train_set = featuresets[:1500]
test_set = featuresets[1500:]

# 使用朴素贝叶斯分类器进行分类
classifier = nltk.NaiveBayesClassifier.train(train_set)

# 测试分类器的准确率
accuracy = nltk.classify.accuracy(classifier, test_set)
print("分类器准确率:", accuracy)

# 使用SVM分类器进行分类
svm_classifier = SklearnClassifier(SVC())
svm_classifier.train(train_set)

# 测试SVM分类器的准确率
svm_accuracy = nltk.classify.accuracy(svm_classifier, test_set)
print("SVM分类器准确率:", svm_accuracy)

在上述代码中,首先下载了NLTK的电影评论数据集,然后加载评论数据并进行词袋模型的构建。通过计算词频,选择出现频率最高的2000个词语作为特征。接下来,定义了一个特征提取函数,将每个评论文本转换为特征向量表示。然后,构建了特征集,并将其划分为训练集和测试集。最后使用朴素贝叶斯分类器进行情感分类,并计算分类器的准确率。另外,使用SVM分类器进行分类并计算准确率。执行后会输出:

[nltk_data] Downloading package movie_reviews to
[nltk_data]     C:\Users\apple\AppData\Roaming\nltk_data...
[nltk_data]   Unzipping corpora\movie_reviews.zip.
分类器准确率: 0.78
SVM分类器准确率: 0.616

上述例子演示了如何使用NLTK实现词袋模型,并应用于情感分类任务。大家可以根据自己的数据集和任务需求进行定制和扩展。

(3)Gensim

Gensim是一个用于主题建模和文本相似度计算的库,也可以用于词袋模型的构建。例如下面的实例演示了使用 Gensim 实现词袋模型的过程,假设我们有一个新闻文章数据集,我们希望根据文章内容推荐相似的新闻。

源码路径:daima/2/recommendation.py

from gensim import models, similarities
from gensim.corpora import Dictionary

# 新闻文章数据集
documents = [
    "The economy is going strong with positive growth.",
    "Unemployment rates are decreasing, indicating a robust job market.",
    "Stock market is experiencing a bull run, with high trading volumes.",
    "Inflation remains low, providing stability to the economy."
]

# 分词和建立词袋模型
texts = [[word for word in document.lower().split()] for document in documents]
dictionary = Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts]

# 训练TF-IDF模型
tfidf = models.TfidfModel(corpus)
corpus_tfidf = tfidf[corpus]

# 构建相似度索引
index = similarities.MatrixSimilarity(corpus_tfidf)

# 选择一个文章,获取相似推荐
article_index = 0  # 选择第一篇文章作为例子
similarities = index[corpus_tfidf[article_index]]

# 按相似度降序排列并打印推荐文章
sorted_indexes = sorted(range(len(similarities)), key=lambda i: similarities[i], reverse=True)
print(f"根据文章 '{documents[article_index]}' 推荐的相似文章:")
for i in sorted_indexes[1:]:
    print(documents[i])

在上述代码中,首先定义了一个包含新闻文章的数据集。然后,使用Gensim库对文章进行分词,并构建词袋模型。接下来,训练TF-IDF模型来计算每个词语的重要性。使用TF-IDF模型转换文档向量,构建语料库。然后,构建相似度索引,将语料库中的每个文档转换为特征向量表示。然后选择一个文章作为例子,计算其与其他文章的相似度。根据相似度降序排列,打印推荐的相似文章。执行后会输出:

根据文章 'The economy is going strong with positive growth.' 推荐的相似文章:
Stock market is experiencing a bull run, with high trading volumes.
Inflation remains low, providing stability to the economy.
Unemployment rates are decreasing, indicating a robust job market.

2.1.2  n-gram模型

在推荐系统中,n-gram 模型是一种基础的文本建模技术,用于捕捉词序列的局部信息。它是一种基于概率的统计模型,用于预测给定文本序列中下一个词或字符的可能性。n-gram 模型中的 "n" 表示模型考虑的词语或字符的数量。例如,一个2-gram模型(也称为bigram模型)考虑每个词的上下文中的前一个词,而一个3-gram模型(也称为trigram模型)则考虑前两个词。n-gram 模型的基本假设是,当前词的出现仅依赖于前面的 n-1 个词。通过观察大量文本数据,n-gram 模型可以学习到不同词语之间的频率和概率分布,从而对下一个词的出现进行预测。

在 Python 程序中,可以使用库NLTK(Natural Language Toolkit)来实现 n-gram 模型。NLTK 提供了一些工具和函数,用于构建 n-gram 模型并进行文本生成和预测。例如下面的实例演示了使用库NLTK实现 n-gram模型的过程。

源码路径:daima/2/ngram.py

import nltk
nltk.download('punkt')
from nltk import ngrams

# 商品列表
products = [
    "Apple iPhone 12",
    "Samsung Galaxy S21",
    "Google Pixel 5",
    "Apple iPad Pro",
    "Samsung Galaxy Tab S7",
    "Microsoft Surface Pro 7"
]

# 构建 n-gram 模型
n = 2  # n-gram 模型中考虑的词语数量
product_tokens = [product.lower().split() for product in products]
product_ngrams = [list(ngrams(tokens, n)) for tokens in product_tokens]

# 用户输入查询
query = "Apple iPhone"

# 根据查询匹配推荐商品
query_tokens = query.lower().split()
query_ngrams = list(ngrams(query_tokens, n))

recommended_products = []
for i in range(len(products)):
    count = 0
    for query_ngram in query_ngrams:
        if query_ngram in product_ngrams[i]:
            count += 1
    if count == len(query_ngrams):
        recommended_products.append(products[i])

print("Recommended Products:")
for product in recommended_products:
    print(product)

对上述代码的具体说明如下:

  1. 导入NLTK 库,并从中导入了 ngrams 函数。
  2. 定义商品列表:创建了一个包含不同商品名称的列表。
  3. 构建 n-gram 模型:将商品名称分成单词,并使用 ngrams 函数生成 n-gram 序列。这里,我们指定 n 的值为 2,表示使用二元组(bigram)作为 n-gram 模型。
  4. 用户查询输入:定义了一个查询字符串,例如 "Apple iPhone"。
  5. 根据查询匹配推荐商品:将查询字符串分成单词,并生成相应的 n-gram 序列。然后,遍历商品列表,并对每个商品的 n-gram 序列进行匹配。如果查询的所有 n-gram 都在商品的 n-gram 序列中出现,则认为该商品与查询相关,并将其添加到推荐列表中。
  6. 输出推荐商品:最后,打印出推荐的相关商品列表。

执行后会输出:

Recommended Products:

Apple iPhone 12

注意:这只是一个简化的例子,用于说明如何使用 NLTK 实现基于 n-gram 的推荐系统。实际的推荐系统可能包含更多的步骤和复杂的算法,用于处理更大规模的数据和更复杂的推荐逻辑。

2.1.3  特征哈希(Feature Hashing)

特征哈希(Feature Hashing)是一种常用的特征处理技术,用于将高维特征向量映射到固定长度的哈希表中。在推荐系统中,特征哈希可以用于处理稀疏的特征数据,减少内存消耗并加快计算速度。特征哈希的基本原理如下:

  1. 特征表示:在推荐系统中,通常使用特征来表示用户和物品,例如用户的年龄、性别、浏览历史,物品的类别、标签等。这些特征可以形成一个高维的特征向量。
  2. 特征哈希函数:特征哈希使用哈希函数将高维特征向量映射到固定长度的哈希表中。哈希函数将特征的取值范围映射到一个固定大小的哈希表索引。通常,哈希函数的输出是一个整数,表示特征在哈希表中的位置。
  3. 哈希表存储:哈希表可以使用数组或其他数据结构来表示。每个特征都对应哈希表中的一个位置,可以将特征的取值作为索引,将特征的计数或权重作为值存储在哈希表中。
  4. 特征编码:对于每个样本,通过特征哈希函数将特征向量映射到哈希表中,并根据哈希表的索引位置将特征编码为一个固定长度的特征向量。这个特征向量可以作为输入用于训练推荐系统的模型。

特征哈希的主要优点是简单高效,适用于处理大规模的稀疏特征数据。它可以减少内存消耗,因为哈希表的大小是固定的,不受原始特征向量维度的影响。此外,特征哈希还能加快计算速度,因为哈希函数的计算比完整的特征向量计算更快。

在 Python程序中,可以使用类sklearn.feature_extraction.FeatureHasher 和模块hashlib 实现特征哈希处理,并将哈希后的特征用于推荐系统的特征工程和模型训练。假设现在有一个电影推荐系统,其中每个电影有以下特征:电影名称、电影类型、导演、演员。我们可以使用特征哈希(Feature Hashing)来处理这些特征,并将它们转换为固定长度的特征向量。例如下面是一个使用特征哈希处理上述电影特征的例子。

源码路径:daima/2/teha.py

from sklearn.feature_extraction import FeatureHasher

# 电影数据集
movies = [
    {"movie_id": 1, "title": "Movie A", "genre": "Action", "director": "Director X", "actors": ["Actor A", "Actor B"]},
    {"movie_id": 2, "title": "Movie B", "genre": "Comedy", "director": "Director Y", "actors": ["Actor B", "Actor C"]},
    {"movie_id": 3, "title": "Movie C", "genre": "Drama", "director": "Director Z", "actors": ["Actor A", "Actor C"]}
]

# 将列表类型的特征转换为字符串
for movie in movies:
    movie["actors"] = ", ".join(movie["actors"])

# 特征哈希处理
hasher = FeatureHasher(n_features=5, input_type="dict")
hashed_features = hasher.transform({movie["movie_id"]: movie for movie in movies}.values())

# 打印哈希后的特征向量
for i, movie in enumerate(movies):
    print(f"Movie ID: {movie['movie_id']}")
    print(f"Title: {movie['title']}")
    print(f"Hashed Features: {hashed_features[i].toarray()[0]}")
    print("------")

对上述代码的具体说明如下:

  1. 首先创建了电影数据集,其中包含每部电影的一些特征,如电影ID、标题、类型、导演和演员列表。
  2. 然后,需要对演员列表进行处理,将其从列表类型转换为以逗号分隔的字符串,以确保特征是字符串类型。
  3. 接下来,使用类FeatureHasher来进行特征哈希处理。我们指定了哈希后的特征向量的长度(n_features)为5,并设置输入类型为字典(input_type="dict")。
  4. 然后,将电影数据集转换为字典形式,并使用电影ID作为字典的键,电影特征作为字典的值。
  5. 最后,使用特征哈希器对字典形式的电影特征进行转换,得到哈希后的特征向量。最终,通过循环遍历每部电影,并打印出电影ID、标题以及对应的哈希后的特征向量。

执行后会输出每部电影的电影ID、标题以及对应的特征哈希向量。具体输出的内容取决于电影数据集的内容,每行包含一个电影的信息。例如下面的输出内容:

Movie ID: 1
Title: Movie A
Hashed Features: [-3.  0.  1.  0.  1.]
------
Movie ID: 2
Title: Movie B
Hashed Features: [-2.  0.  0. -1. -1.]
------
Movie ID: 3
Title: Movie C
Hashed Features: [-3.  0. -1. -2. -1.]
------

总体来说,上述代码演示了如何使用特征哈希对电影特征进行处理,将其转换为固定长度的特征向量。这种方法适用于处理高维稀疏特征的情况,并能提高计算效率和降低存储成本。

未完待续

  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农三叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值