查看原文
其他

AI 行业实践精选:通过机器学习刺激销量——如何利用NLP挖掘潜在客户

2017-03-09 AI科技大本营

【AI100 导读】在这篇博客中,作者会向大家介绍如何以更有效的方式通过 Xeneta 进行营销,会训练一个机器学习算法,通过对于公司的描述来预测潜在客户的质量。



提出问题




它诞生于业务发展代表爱德华(Edvard)的一项需求。他已经厌倦了枯燥无聊的工作——每天都要处理满是公司名称的巨型 Excel 表格,需要付出很大的努力才能从中找到想要联系的那个公司。

 

潜在合作公司列表(来自sec.gov网站)

 

这种对销售资格进行预审的工作可能要花上好几个小时的时间。因为它要求销售代表去了解列表中的每一家公司(比如说通过领英来了解公司的背景。)因此他/她可以做一个有效预测,估计某家公司是否适合我们的 SaaS 应用程序。


如何做一个有效预测呢?想要了解它,首先您需要了解我们是如何运行该程序的:

 

从本质上讲,Xeneta 通过提供海上运费市场情报来帮助节省集装箱运成本。

 

与市场平均值相比,这位顾客可以在海运成本上节约74万8千美金。

 

更具体地说,如果你的公司每年会运输超过500个集装箱,通过使用 Xeneta,可以看到明显的成本节省效果。我们可以精确地告诉你,在哪些项目上你所付的费用高出了市场平均值。

 

使用这个小部件的客户签约率 (紫色线) 与市场平均水平 (绿色曲线)的比较,集装箱大小为20英尺,自中国发往北欧。

 

这就意味着我们的目标客户背景各不相同,他们唯一的共同特征是都涉及到了海运。 这是我们为目标公司分类的一些例子:


  • 汽车行业

  • 海上货物运输

  • 化工业

  • 消费及零售业

  • 廉价商品

 

假设




尽管客户范围广泛,在寻找合作线索时无疑是一种挑战,但我们仍可通过公司的描述来判断其是否对 Xeneta 感兴趣。因为通常公司描述中会包含某些线索,我们可以了解到他们是否在世界各地运送货物。


这让我们认为:

 

通过公司的描述,我们可否训练出一个算法来预估该公司是不是 Xeneta 的潜在顾客?

 

如果可行的话,这个算法对于销售团队来说就帮了大忙了,因为它可以在人工评估资格之前就对那个 Excel 表格做出严格的筛选。

 

发展




最初开始研发的时候,我迅速意识到机器学习的部分并不是唯一的问题。 我们还需要找到公司描述的方法。

 

我们认为搜索公司网站并选取”关于我们“部分的信息可行。但是这似乎是一项杂乱无章而又耗费时间的任务。所以我们开始寻找应用程序接口。做了一些搜索后我们发现,FullContact 包含公司的应用程序接口,可以为我们提供上百万家公司的描述。


 

然而,它们的 API 只能接受公司的 URL 作为输入,这在我们的 excel 表格中极少显示出来。


因此我们不得不寻找一种方法来获取 URL,我们按照以下流程来操作:


  • 使用谷歌 API 来搜索公司姓名(我知道这很变态)

  • 反复查找搜索结果并找出最近似正确的 URL

  • 使用这个 URL 来查询 FullContact API

 

当然在每个步骤中都会有损失,因此我们试图找到更好的方法。 然而,上述方法对于测试我们的想法来说已经足够好了。

 

数据集




在有相关代码的地方,我们的下一步就是创建新的训练数据集。 这个数据集至少需要包含 1000 个有资质的公司和 1000 个没有资质的公司。

 

第一步的分类非常简单,我们只要从 SalesForce 调出1000名 Xeneta 用户的资料就可以了。


而寻找1000个不符合资格的公司确实是有点难,因为我们避免接触的公司并不会保留数据。因此爱德华人工录入了1000个不够资格的公司。

 

清洗数据




这步完成后,是时候开始编写自然语言运行脚本了。第一步就是清除所有的描述,因为它们过于混乱并且包含了很多不相关的信息。


如下就是一个例子,我将描述目前正在用的清洗技能的每一步,向你展示原始数据如何变成整齐有序的数组。

 

原始描述示例。

 

正则表达式


首先我们要做的是用常规表达来清除那些不是字母的字符,因为我们的模型只能学习相关的词汇。

 

description = re.sub(“[^a-zA-Z]”, “ “, description)


在删除非字母顺序字符之后。

 

词干分析器

 

我们也会将词汇词干化。 这意味着按照词干将一个词的不同变形形式减少。 因此,相比去接受 manufacturer、manufaction、manufactured 以及  manufactoring 这样多变的单词,我们更愿意把它们都简化统一为  manufact。


from nltk.stem.snowball import SnowballStemmer

stemmer = SnowballStemmer(‘english’)
description = getDescription()description = [stemmer.stem(word) for word in description]

 

在词汇词干化之后。

 

停止词


然后我们使用自然语言 Toolkit 去删除那些停止词,停止词就是和文本的概念化理解几乎没有关联的单词,例如 is、to、for、at、I、it 等。

 

from nltk.corpus import stopwords
stopWords = set(stopwords.words('english'))

description = getDescription()


description = [word for word in description if not word in stopWords]

 

在删除停止词之后。

 

转换数据




然而,清洗并词干化数据对于我们的机器学习其实没有任何帮助,因为我们还需要将公司描述转换成一些机器能够理解的东西,也就是数字。

 

Bag of Words(BoW)

 

对此,我们使用 BoW 法。如果您对 BoW 并不熟悉的话,我建议阅读这个 Kaggle 教程(https://www.kaggle.com/c/word2vec-nlp-tutorial/details/part-1-for-beginners-bag-of-words)。


BoW 是将文本词汇转换成矢量的简易工具。矢量中的每一项都代表了一个特定的词汇。Scikit 学习中的字数矢量器给您提供了一个超级简单的方法来完成它:

 

from sklearn.feature_extraction.text import Count


Vectorizervectorizer = CountVectorizer(analyzer = ‘word’, max_features=5000)

vectorizer.fit(training_data)
vectorized_training_data = vectorizer.transform(training_data)

 

Max_features 参数会告诉矢量器您想要词汇库中存在多少个单词。在这个例子中,矢量器包括了5000个在我们的数据集中最频繁出现的词汇,拒绝包含其他词汇。

 

这个例子只包含很少的 BoW 矢量(35个)。(我们的有5000个之多。)

 

Tf-idf 转化

 

最终,我们也应用 tf-idf 来进行转换。tf-idf 是词频与逆文档频率的缩写。

这项技术可以调整你文档中出现的不同词汇的重要性。


更具体地说,tf-idf 将会突出在一个描述中频繁出现的词汇(也就是词频),特别重要的词汇就是在整个数据集中反复出现的词汇(逆文档频率)。

 

from sklearn.feature_extraction.text import TfidfTransformer

tfidf = TfidfTransformer(norm=’l1')


tfidf.fit(vectorized_training_data)

tfidf_vectorized_data = tfidf.transform(vectorized_training_data)

 

再一次,scikit 学习通过提供箱外 tf-idf 让我们这一天变得十分轻松。简单来说就是用模型适应矢量化的训练数据,然后用转化方法将其转换。

 

应用tf-idf后的矢量。(抱歉格式很糟糕)

 

算法




当所有数据被清除、矢量化并转化后,我们终于可以开始进行机器学习了,机器学习是其中最简单的部分。

 

我首先将数据分为70%的训练数据和30%的测试数据,然后开始用两个 scikit 学习算法:随机森林 (RF) 和 K 最近邻 (KNN)。结果马上清晰明了,射频的表现明显优于 KNN 分类算法。因为前者的准确率将近80%,而后者维持在60%的水平。


拟合出一个 scikit 学习模型超级简单︰


def runForest(X_train, X_test, Y_train, Y_test):
  forest = RandomForestClassifier(n_estimators=100)
  forest = forest.fit(X_train, Y_train)
  score = forest.score(X_test, Y_test)

  return score


forest_score = runForest(X_train, X_test, Y_train, Y_test)

 

因此,我继续用射频来看看通过调整可以提高多少准确率。以下是我调整的参数:

 

  • 词汇:计数向量器在词汇中计入了多少词(目前是5000)

  • 单位范围:词汇的规模,包括 BoW(目前3字词汇可以有1-3种意思)

  • 评估量:评估量要包含随机森林(目前是90)中的量

 

通过对以上参数的调整,算法在测试数据集中可以达到 86.4% 的准确率。这对于我们的销售团队来说已经很有帮助了。


未来方向




然而,代码无论如何都进行不下去了。但是有很多方法可以解决它。比如说,算法更偏向我们已经在训练数据中记录的描述。 这可能是在测试更真实环境的数据时会出现的瓶颈。


未来我们将在如下方面努力:


  • 获取更多的数据(抹除,其它应用程序接口,提高数据清洗效果)

  • 测试其它类型的数据转换(比如 word2vec)

  • 测试其他机器学习算法(比如神经网络)

   

本文作者 Per Harald Borgen 毕业于奥斯陆大学,目前是 Scrimba 的联合创始人。


本文由 AI100 编译,转载需得到本公众号同意。




编译:AI100

原文链接:https://medium.com/xeneta/boosting-sales-with-machine-learning-fbcf2e618be3




查看更多 AI 最新头条,请访问 AI100 微信公众号:




点击↙阅读原文↙查看更多资讯 

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存