# -*- coding: utf-8 -*-
import sys
from pyspark import SparkConf
from pyspark.sql import SparkSession
from pyspark.sql.types import *
from pyspark.ml.functions import vector_to_array
import subprocess
from pyspark.sql import SQLContext
from pyspark.sql import Row
from pyspark import SparkConf
from pyspark import SparkFiles
from pyspark.sql.functions import udf, pandas_udf, rand
from pyspark.ml.feature import Word2Vec
from pyspark.sql import SparkSession
import sys
import os
# 配置环境变量,否则报错python3找不到
os.environ['PYSPARK_PYTHON'] = sys.executable
os.environ['PYSPARK_DRIVER_PYTHON'] = sys.executable
spark = SparkSession.builder.config("spark.driver.memory", "16g").config("spark.driver.maxResultSize", "8g").enableHiveSupport().appName("Query w2v1").getOrCreate()
query = "SELECT device,package_list from database.table"
query_df=spark.sql(query)
query_df.show()
# 训练 Word2Vec 模型
word2Vec = Word2Vec(vectorSize=150,
minCount=500,
windowSize=10,maxIter=1,
numPartitions=500,
inputCol="package_list",
outputCol="features")
model = word2Vec.fit(query_df)
#转换文本数据为词向量
result = model.transform(query_df)
result = result.withColumn('features', vector_to_array('features')).select('device','features')
# result.show()
result.createOrReplaceTempView('tmp1')
create_sql1='''create TABLE database.table_v150
select device,features from tmp1'''
print(create_sql1)
spark.sql(create_sql1)
spark.stop()
下面对代码进行说明,方便理解。
database.table表为需要生成词向量的原始表,我这张表数据量在10亿左右,device是设备号,package_list是设备的在装app列表,用逗号分隔的数组(比如:微信,支付宝,抖音)。
Word2Vec模型就像一个超级聪明的城市规划师。它的任务是:
-
逛小区:它会“走访”这10亿个住户的家,查看每家每户都有哪些“家具”(我们把设备理解为“家”,app理解为“家具”)。
-
发现规律:它会默默地观察和总结规律。比如:
-
它发现家里有 “游戏手柄” 的住户,很大概率同时也有 “大屏幕电视” 和 “可乐”。
-
家里有 “茶桌” 的,很可能也有 “茶壶” 和 “茶叶”。
-
而既有“游戏手柄”又有“茶桌”的住户非常少,说明这两类东西(爱好)不太相关。
-
-
给每个“家具”定坐标:规划师根据上面的规律,为每一样“家具”在一张150维的虚拟地图上确定一个精确的坐标位置。
-
坐标("游戏手柄")=[0.12, 0.85, -0.23, ..., 0.45](一个150个数字组成的列表) -
坐标("大屏幕电视")=[0.08, 0.82, -0.20, ..., 0.41] -
坐标("茶桌")=[-0.31, 0.15, 0.67, ..., -0.12] -
坐标("茶叶")=[-0.28, 0.12, 0.70, ..., -0.10]
-
你发现了什么?“游戏手柄”和“大屏幕电视”的坐标非常接近(前三个数字都很像)。而它们离“茶桌”和“茶叶”的坐标非常远。
这就意味着,在这个150维的空间里,功能相似、经常一起出现的App,它们的向量(坐标)位置就越接近。
代码中参数的作用:
-
vectorSize=150:地图的精度。150维就像用150个特征来描述一个位置,维度越高,描述得越精确,但也需要更多计算和存储。100维就像用“附近有学校、有地铁”来描述,150维就像额外加上了“噪音分贝、日照时长、邻居职业分布”等150个特征来精确描述。 -
minCount=500:规划师会忽略那些非常冷门、只有极少数家拥有的“家具”(App)。比如“外星人通讯器”只出现了几次,就直接忽略不计,因为它代表不了任何规律。 -
windowSize=10:规划师在观察一个住户家时,一次会看10件摆放在一起的“家具”来寻找它们之间的关系。
第三步:生成结果(给每个“小区住户”定位)
模型训练好后,就会生成150维的词向量结果表。
这个过程很简单:把一户人家里所有的“家具”的坐标,求一个平均中心点,这个中心点就是这户人家的坐标。
|
device (住户) |
package_list (拥有的家具) |
features (该住户的500维坐标 - 取平均值) |
|---|---|---|
|
张三 |
|
|
|
李四 |
|
|
|
王五 |
|
|
总结一下,这个程序干了这么一件事:
它通过分析10亿个设备上哪些App会同时出现,学习到了每个App的“特征”,并用150个数字(向量)来表示它。最后,用一个设备上所有App向量的平均值,作为代表这个设备“兴趣爱好”的150维特征向量。
这张“地图”有什么用?
有了这张地图,我们就可以做很多有趣的事:
-
找相似:很容易找到“兴趣爱好”相近的用户(坐标点接近的设备),给他们推荐彼此喜欢的东西。
-
用户分群:把地图上的点进行聚类,可以发现“游戏党”、“养生族”、“商务人士”等不同群体。
-
广告精准投放:向“游戏党”推送游戏广告,向“商务人士”推送高端办公软件。


被折叠的 条评论
为什么被折叠?



