人工智能,应该如何测试?(六)推荐系统拆解

简介: 该文介绍了推荐系统的基本概念和实现思路。推荐系统通过预处理筛选候选集合,然后利用二分类模型预测用户对内容的喜好概率,再按概率排序选择Top N内容推荐给用户。文中提供了一个使用Spark ML库的简单模型训练DEMO,涉及数据预处理、特征工程和逻辑回归模型。此外,还提及了词向量在处理文本特征中的重要性,它能捕捉词与词之间的关联性。推荐系统的实际应用远比示例复杂,但这个例子有助于理解其核心流程。

推荐系统简介

推荐系统的问题

根据之前学习到的内容,我们已经基本了解到了要如何构建一个二分类模型。我们都知道模型大体可以分成,回归,二分类和多分类。但推荐系统是属于哪一种场景呢,比如我们常见的广告推荐或者内容推荐,这些场景都是由系统来判断用户的喜好来推送广告或者视频内容,以追求更高的点击率和转化率。这种场景怎么看都不像跟这三种类型的算法有关系。

实现思路

其实解决这个问题的思路也比较简单, 我们可以遵循如下的原则:

  1. 借助专家系统,根据用户的信息初筛一个候选的视频集合(比如 1000 个),比如可以先简单根据用户的年龄,性别,爱好,职业进行推测他喜欢的类型并过滤出候选集合。 这是一种预处理机制, 在人工智能系统中,模型往往无法处理所有的情况,需要一些预处理与后处理辅助模型。在推荐系统中这个步骤往往被称为大排序,先根据规则来筛选候选集合。这么做有多种原因,其中一种比较典型的是担心模型的性能无法支撑过多的候选集合的计算。
  2. 训练一个二分类模型,这个模型用于推理出用户是否会点击这个视频(根据业务场景来,有可能是点击,有可能是点赞,也有可能是转化)。
  3. 将候选集合分别输入给模型进行推理。计算出每个视频会被用户点击的概率。
  4. 把模型的推理结果进行排序,取 top n 个概率最高的视频推送给用户。这一步就与传统的二分类模型不同, 我们已经知道模型输出的是目标属于某个类别的概率。而在传统二分类模型中, 需要用户自己设定一个阈值(也叫置信度)来辅助判断目标的类别, 概率大于这个阈值的判定为正例,小于这个阈值的判定为负例,这正是二分类模型的原理。但是在推荐系统中, 我们并不会因为用户喜欢这个内容的概率超过了某个阈值就进行推送, 因为候选集合太多了, 我们不能把超过某个阈值的都推送过去(广告位或者内容推送是有数量限制的)。 所以最终选择的是根据用户喜欢这个内容的概率进行排序,然后取 topN 来进行推送。

如此我们就把一个推荐系统的问题转换成了一个二分类的问题。 我们可以理解为世界上所有的监督学习场景,都是由二分类,多分类和回归问题变种而来。

写一个简单的模型训练 DEMO(使用 spark ml 库)

from pyspark.sql import SparkSession
from pyspark.ml import Pipeline
from pyspark.ml.feature import Tokenizer, StopWordsRemover, CountVectorizer
from pyspark.ml.classification import LogisticRegression
from pyspark.ml.evaluation import BinaryClassificationEvaluator


from pyspark import SparkContext, SparkConf, SQLContext
from pyspark.sql import functions as F
from pyspark.sql.window import Window

conf = SparkConf().setMaster("local").setAppName("My App")
sc = SparkContext(conf=conf)
sqlContext = SQLContext(sc)


# 定义数据
dicts = [
    ['man', 'The Shawshank Redemption', 1.0],
    ['man', 'The Godfather', 1.0],
    ['man', 'Forrest Gump', 1.0],
    ['woman', 'Titanic', 1.0],
    ['woman', 'Forrest Gump', 0.0],
    ['woman', 'The Godfather', 0.0],
    ['woman', 'The Shawshank Redemption', 0.0],
    ['man', 'Titanic', 0.0],
    ['man', 'A Beautiful Mind', 0.0],
    ['woman', 'A Beautiful Mind', 1.0],
]
rdd = sc.parallelize(dicts, 3)
dataf = sqlContext.createDataFrame(rdd, ['gender', 'title', 'interested'])


# 将性别进行独热编码,以便把数据转换成算法可以识别的形式
from pyspark.ml.feature import StringIndexer, OneHotEncoder, VectorAssembler
stringIndexer = StringIndexer(inputCol="gender", outputCol="gender_num")
data_indexed = stringIndexer.fit(dataf).transform(dataf)
encoder = OneHotEncoder(inputCol="gender_num", outputCol="gender_onehot")
data_encoded = encoder.fit(data_indexed).transform(data_indexed)
data = data_encoded.select('gender_onehot', 'interested', 'title')
data.show()

# 使用分词器
tokenizer = Tokenizer(inputCol="title", outputCol="words")
# 使用停用词
remover = StopWordsRemover(inputCol="words", outputCol="filtered_words")
# 将文本数据转换成特征向量,注意下面被注释的代码,这里是词向量转换,在NLP中,我们经常会把文本进行词向量转换,我们在下面会详细讲解词向量的内容。
# word2vec.fit(remover)
vectorizer = CountVectorizer(inputCol="filtered_words", outputCol="final_words")

# 将所有特征组合成一个特征向量
vectorAssembler = VectorAssembler(inputCols=["gender_onehot", "final_words"], outputCol="features")

# 定义逻辑回归
classifier = LogisticRegression(labelCol="interested", featuresCol="features", maxIter=10)
# 定义流水线, 当数据来了以后就可以按顺序处理数据
pipeline = Pipeline(stages=[tokenizer, remover, vectorizer, vectorAssembler, classifier])
# 模型训练
model = pipeline.fit(data)

# 模型推理
predictions = model.transform(data)
evaluator = BinaryClassificationEvaluator(labelCol="interested", rawPredictionCol="rawPrediction")
accuracy = evaluator.evaluate(predictions)
print("Accuracy:", accuracy)
predictions.show()

df_desc = predictions.orderBy(F.desc("probability"))
df_desc.show()

词向量

上面用于训练模型的数据中有一列是视频的标题,我们会发现代码中我们使用了一系列 NLP(Natural Language Processing,自然语言处理)的算法:

  • 分词器(tokenizer):用于在一个句子中提取一个一个的词
  • 停用词(stop words):用于去掉一些语义无关的语气词,介词等,比如the或者中文中的语气词。 在模型训练中往往需要去掉这些词以去除噪音,优化模型空间,减少索引量等等
  • 词向量(也叫词嵌入):可以理解为计算出词与词之间的关联性,从而训练出的围绕中心词的特征向量。

上述概念中可能词向量是最难以理解的,这里尽量尝试用简单易懂的语言来解释这个概念。 我们之前训练反欺诈模型的时候,也遇到过一些离散特征,比如title也是以文本形式存在的数据。
我们在反欺诈中处理这样的使用的 one-hot(独热编码),独热编码也是一种处理离散特征常用的方法。假设我们有一群学生,他们可以通过四个特征来形容,分别是:

  • 性别:[“男”,“女”]

  • 年级:[“初一”,“初二”,“初三”]

  • 学校:[“一中”,“二中”,“三中”,“四中”] 我们用采用 N 位状态寄存器来对 N 个状态进行编码,拿上面的例子来说,就是:[

image.png

因此,当我们再来描述一个学生的时候(男生,初一,来自一中),就可以采用 [1 0 1 0 0 0 1 0 0] 这样的形式来表示。这也一种用于特征组合的实现方法之一。

或者我们也可以使用类似 bitmap 的方法做出一个 one—hot 向量来表示离散特征。 我们可以用类似下面的形式表达:

image.png

假设职业这一列一共有 100 个值, 假设教师在编号 6 这个位置上,编号 6 所在位置 ide 值就是 1,其他的值都是 0,我们以这个向量来代表教师这个特征. 以此类推,如果学生代表的编号是 10,那么
10 这个位置所在的值是 1,其他位置的值都是 0,用词向量来代表学生。 这样最后我们就有 100 个 100 维度的向量来表示这些特征。

上面两种方法都是很常见的用来用来表达文本特征的方法,但它们的问题是词与词之间是独立的,互相没有关联。 比如我们的训练数据中有一个句子this is apple juice,我们期望当
出现 this is orange __ 的时候,模型能够为我们推测出这个空白处也应该填写单词juice。 也就是我们希望模型能通过之前针对第一个句子的训练就能找到单词与单词之间的关系,模型能够知道
appleorange是含义相似的词,从而能推测出orange后面也可以填写juice。 而这正是词向量要做的事情。

image.png

如上图,词向量围绕这一些中心词(性别,事务,高贵程度),计算出每一个词与这些中心词的相关程度。而要得到这个词向量本身就需要相关算法训练出来,比如 world2vec:

from pyspark.ml.feature import Word2Vec

from pyspark.sql import SparkSession

spark = SparkSession \
    .builder \
    .appName("dataFrame") \
    .getOrCreate()

# Input data: Each row is a bag of words from a sentence or document.
documentDF = spark.createDataFrame([
    ("Hi I heard about Spark".split(" "),),
    ("I wish Java could use case classes".split(" "),),
    ("Logistic regression models are neat".split(" "),)
], ["text"])

documentDF.show()

# Learn a mapping from words to Vectors.
word2Vec = Word2Vec(vectorSize=5, minCount=0, inputCol="text", outputCol="result")
model = word2Vec.fit(documentDF)

result = model.transform(documentDF)
for row in result.collect():
    text, vector = row
    print("Text: [%s] => \nVector: %s\n" % (", ".join(text), str(vector)))

# 运行结果
Text: [Hi, I, heard, about, Spark] => 
Vector: [-0.056896060705184937,-0.029017432034015658,0.020092955231666567,-0.0003222271800041199,-0.02170231742784381]

Text: [I, wish, Java, could, use, case, classes] => 
Vector: [0.003511839745832341,0.025775608922620968,-0.01780955892588411,0.0012207544807876858,-0.0023355478021715365]

Text: [Logistic, regression, models, are, neat] => 
Vector: [0.008233835361897946,-0.01995183974504471,-0.013863331265747549,-0.051928133144974714,-0.014838875085115433]

上面是一个训练词向量的代码,它的计算原理大概可以描述为:在文本中选取中心词并选取中心词前后数个单词,并训练出这些词会出现在中心词周围的概率。

总结

这些就是一个推荐系统中的大概步骤, 当然实际的推荐系统是非常复杂的, 我目前也只是列了一个简单的 DEMO,帮助大家理解推荐系统都在做什么事情。

相关文章
|
2天前
|
人工智能 算法 测试技术
软件测试中的人工智能革命
本文深入探讨了人工智能在软件测试中的应用,揭示了这一技术革新如何改变传统的测试流程。通过分析人工智能技术的优势、具体应用案例以及面临的挑战,文章展示了AI如何提高测试效率、减少人为错误,并预测其在未来软件测试中的趋势。此外,文章还提出了针对当前挑战的解决策略,为软件测试行业的从业者提供了宝贵的参考和启示。
17 4
|
1月前
|
机器学习/深度学习 人工智能 算法
探索软件测试的未来:自动化与人工智能的融合
在数字时代的浪潮中,软件测试作为保障软件质量的重要环节,正面临前所未有的挑战与机遇。本文深入探讨了自动化测试和人工智能技术如何共同推动软件测试领域的革新,以及这一变革对测试人员技能要求的影响。通过分析当前行业趋势、案例研究和技术发展,文章旨在为读者揭示未来软件测试的可能走向,并激发对持续学习和适应新技术重要性的认识。
40 7
|
2天前
|
机器学习/深度学习 人工智能 算法
软件测试中的人工智能:现状与未来
本文探讨了人工智能在软件测试中的应用,包括自动化测试、缺陷预测、测试用例生成等方面。通过分析当前AI技术的优势和不足,提出了未来可能的发展方向,为软件测试领域提供了新的思路和方法。
21 4
|
3天前
|
数据采集 人工智能 自然语言处理
探索软件测试中的人工智能应用
在当今快速发展的技术世界中,软件测试作为确保软件质量的关键环节,正经历着前所未有的变革。随着人工智能技术的不断成熟和应用,其在软件测试领域的潜力逐渐显现,为提升测试效率、准确性和自动化水平提供了新的可能性。本文将深入探讨人工智能在软件测试中的应用现状、面临的挑战以及未来的发展趋势,旨在为读者提供一个关于AI如何改变软件测试行业的全面视角。
|
2天前
|
设计模式 人工智能 算法
PHP中的设计模式:策略模式的深入解析与实践软件测试中的人工智能革命:提升效率与准确性的新篇章
在PHP开发中,理解并运用设计模式是提升代码质量和可维护性的重要途径。本文聚焦于策略模式(Strategy Pattern),一种行为型设计模式,它允许在运行时选择算法或业务规则。通过本文,我们将深入探讨策略模式的定义、结构、使用场景以及如何在PHP项目中有效地实现和利用策略模式。不同于性能优化等技术性摘要,本文着重于提供对策略模式全面而实用的理解,助力开发者编写出更加灵活和可扩展的应用程序。 本文深入探讨了人工智能在软件测试领域的应用,揭示了其如何显著提高测试过程的效率和准确性。通过实际案例分析,展示了AI技术在自动化测试、缺陷检测及结果分析中的关键作用,并讨论了实施AI测试策略时面临的挑
13 3
|
10天前
|
机器学习/深度学习 人工智能 自然语言处理
探索软件测试的未来:自动化与人工智能的融合
在本文中,我们将一起踏上一段激动人心的旅程,探索软件测试领域的未来趋势。从手工测试的繁琐到自动化测试的便捷,再到人工智能(AI)技术的引入,我们将揭示这些变革如何影响测试流程、提升效率并减少错误。文章将深入浅出地分析自动化测试工具的进步和AI技术如何赋能软件测试,预测未来可能的发展路径,并提供一些行业案例作为参考。无论你是软件测试领域的新手,还是寻求进阶知识的资深人士,这篇文章都将带给你新的启示和思考。
|
7天前
|
机器学习/深度学习 数据采集 人工智能
软件测试中的人工智能:现状与未来
随着人工智能技术的迅猛发展,软件测试领域正经历着深刻的变革。本文将探讨人工智能在软件测试中的应用、挑战以及未来的发展趋势,旨在为读者提供全面而深入的理解。
|
3天前
|
机器学习/深度学习 人工智能 算法
软件测试中的人工智能应用
在当今快速发展的科技世界中,人工智能(AI)已经在各个领域中展现了其强大的影响力。软件测试作为软件开发过程中的关键步骤,也正在逐渐受到AI技术的深刻影响。本文将探讨AI在软件测试中的应用,分析其带来的优势与挑战,并提供一些实际案例来说明这些变化。通过深入理解AI在软件测试中的角色,我们可以预见一个更加高效、智能的软件测试未来。
22 0
|
5天前
|
机器学习/深度学习 人工智能 自然语言处理
软件测试中的人工智能应用
本文探讨了人工智能在软件测试中的应用,包括自动化测试、缺陷预测和测试用例生成等方面。通过实际案例分析,展示了如何利用AI技术提高软件测试的效率和准确性,并讨论了未来的发展趋势。
13 0
|
1月前
|
人工智能 搜索推荐 测试技术
软件测试的未来:自动化与人工智能的融合
随着技术的快速发展,软件测试领域也迎来了翻天覆地的变化。传统的手动测试方法正在逐渐被自动化测试所取代,而人工智能(AI)的加入则为软件测试带来了新的革命。本文将探讨自动化测试的现状、挑战以及AI如何改变软件测试的未来。