## 五 商品关键词权重选择

### 5.1 TEXTRANK和TFIDF的权重问题

- textrank的权重

``` shell
+------+--------+----+-------------------+
|sku_id|industry| tag|            weights|
+------+--------+----+-------------------+
|   148|    电子产品|  高度|                1.0|
|   148|    电子产品|  终端| 0.9880227098783998|
|   148|    电子产品|WPOS| 0.9474997114660046|
|   148|    电子产品|  身份| 0.8859077272889758|
|   148|    电子产品| 触摸屏| 0.8677093692671172|
|   148|    电子产品|  森锐| 0.8643336666795045|
|   148|    电子产品| 收银机| 0.8606879409613701|
|   148|    电子产品|  智能|  0.853869407929065|
|   148|    电子产品|  业务| 0.8500761345577008|
|   148|    电子产品| 读卡器| 0.6114834155265747|
|   148|    电子产品|  正品| 0.5977867682869656|
|   148|    电子产品|  包邮| 0.5962385663111377|
|   148|    电子产品|数码配件| 0.4880302016489459|
|   148|    电子产品|  数码|0.48644615569271077|
|   148|    电子产品|  购物|  0.442940968516803|
|   463|    电子产品| 读卡器|                1.0|
|   463|    电子产品|  颜色| 0.7811873889257711|
|   463|    电子产品|  安卓| 0.5651375469154993|
|   463|    电子产品|  手机|  0.458740094560001|
|   463|    电子产品|  电脑| 0.4219429919380977|
+------+--------+----+-------------------+
```

- tfidf的权重

``` shell
+------+-------+-------------------+
|sku_id|keyword|              tfidf|
+------+-------+-------------------+
|   148|     智能|0.12920924724659527|
|   148|     数码|0.09416669674352422|
|   148|    读卡器|0.22691875231942266|
|   148|     正品| 0.1984394909665287|
|   148|   数码配件| 0.2300917543361638|
|   148|     购物| 0.2408169399138654|
|   148|     包邮| 0.2752684393351877|
|   148|    触摸屏|0.31885875801848024|
|   148|     高度| 0.3896366762502419|
|   148|    收银机|0.45724967270727696|
|   148|     终端|  0.515996300178136|
|   148|     业务|  0.537514526329006|
|   148|     森锐| 0.6107553455735467|
|   148|     身份| 0.6107553455735467|
|   148|   WPOS| 0.6672418695993603|
|   463|     颜色|0.08984603313709096|
|   463|     黑色|0.20849464181052813|
|   463|     电脑|0.17166530284651157|
|   463|     手机|0.20699498923484225|
|   463|     数码|0.05231483152418012|
+------+-------+-------------------+
```

- 问题 两种方式提取效果都不好 

- 解决方法：优化分词效果，比如将部分不太相关词语设为停用词，如业务、高度等词
- 目前方案：将tfidf权重和textrank权重加权平均，降低两者都导致的过高或过低的词概率
  - 比如148号sku商品，如果使用tfidf，那么发现“读卡器”，比“购物”这样的词权重还低；如果使用textrank，发现“数码”“数码配件”这样的词比“正品”“包邮”这样的还低，但如果相加求平均后，可以使用这个问题得到解决。

### 5.2  加权平均实现

- 创建spark session

``` python
import os
# 配置spark driver和pyspark运行时，所使用的python解释器路径
PYSPARK_PYTHON = "/root/miniconda2/envs/bigdata/bin/python"
# 当存在多个版本时，不指定很可能会导致出错
os.environ["PYSPARK_PYTHON"] = PYSPARK_PYTHON
os.environ["PYSPARK_DRIVER_PYTHON"] = PYSPARK_PYTHON
```

```python
# spark配置信息
# 注意：添加
from pyspark import SparkConf
from pyspark.sql import SparkSession

SPARK_APP_NAME = "mergeTagWeights"
SPARK_URL = "spark://192.168.199.88:7077"

conf = SparkConf()    # 创建spark config对象
config = (
	("spark.app.name", SPARK_APP_NAME),    # 设置启动的spark的app名称，没有提供，将随机产生一个名称
	("spark.executor.memory", "4g"),    # 设置该app启动时占用的内存用量，默认1g
	("spark.master", SPARK_URL),    # spark master的地址
    ("spark.executor.cores", "4"),    # 设置spark executor使用的CPU核心数
    ("hive.metastore.uris", "thrift://localhost:9083"),    # 配置hive元数据的访问，否则spark无法获取hive中已存储的数据
)
# 查看更详细配置及说明：https://spark.apache.org/docs/latest/configuration.html

conf.setAll(config)

# 利用config对象，创建spark session
spark = SparkSession.builder.config(conf=conf).enableHiveSupport().getOrCreate()
```

- 创建textrank和tfidf加权结果表

``` python
sql = """
select 
sku_tag_weights.sku_id, 
sku_tag_weights.industry, 
sku_tag_weights.tag, 
sku_tag_weights.weights textrank, 
sku_tag_tfidf.weights tfidf, 
(sku_tag_weights.weights+sku_tag_tfidf.weights)/2 weights 
from sku_tag_weights,sku_tag_tfidf 
where sku_tag_weights.sku_id=sku_tag_tfidf.sku_id and 
sku_tag_weights.tag=sku_tag_tfidf.tag 
"""
df = spark.sql(sql)
df.show()
```

显示结果

``` shell
+------+--------+-------+-------------------+-------------------+-------------------+
|sku_id|industry|    tag|           textrank|              tfidf|            weights|
+------+--------+-------+-------------------+-------------------+-------------------+
|    85|    电子产品|     数码|0.37669191799893376|0.07434212900804543| 0.2255170235034896|
|   172|    电子产品|   USB2| 0.5297582014310518| 0.4902682570089824| 0.5100132292200171|
|   182|    电子产品|     型号| 0.9112570559313992| 0.4417105502575884| 0.6764838030944937|
|   190|    电子产品|    雷克沙|0.18932069864134093|0.25239101355870736|0.22085585610002414|
|   271|    电子产品|   数码配件|0.18629417960331815|0.16435125309725987|  0.175322716350289|
|   282|    电子产品|    香槟色|0.20939011016154468|  0.450895660720322|0.33014288544093334|
|   305|    电子产品|     星空|0.25201085335696144|0.32303206716234273| 0.2875214602596521|
|   312|    电子产品|   SONY| 0.6481662914614708| 0.4221730662623697| 0.5351696788619202|
|   326|    电子产品|     川宇| 0.3939664586744098| 0.8599491424894472| 0.6269578005819285|
|   334|    电子产品| TOPSSD|0.37769613311191574| 0.9027798790978679| 0.6402380061048918|
|   334|    电子产品|     天硕|0.31446175905424484| 0.9027798790978679| 0.6086208190760564|
|   351|    电子产品|   数码配件| 0.3284858938211362|0.43142203938030715|0.37995396660072167|
|   370|    电子产品|     功能|  0.171914010773732|0.20335407147331752|0.18763404112352478|
|   403|    电子产品|   数码配件| 0.3543503711641944| 0.2465268796458898|0.30043862540504207|
|   410|    电子产品|MicroSD| 0.3341093557715508|0.35569624565338087| 0.3449028007124658|
|   414|    电子产品|     颜色| 0.1632912209999795|0.03465489849573508|0.09897305974785729|
|   441|    电子产品|    手机卡|0.09101143769017656|0.21072675335984295|0.15086909552500977|
|   441|    电子产品|     数码|0.09553860210195766|0.04556453068235043|0.07055156639215404|
|   450|    电子产品|   数码配件|0.41273510820561926|0.21571101969015358| 0.3142230639478864|
|   456|    电子产品|     数码| 0.2580242294098149|0.06726192624537444|0.16264307782759468|
+------+--------+-------+-------------------+-------------------+-------------------+
only showing top 20 rows
```

- 把结果保存到hive中

```python
df.registerTempTable("tempTable")
sql = """CREATE TABLE IF NOT EXISTS sku_tag_merge_weights(
sku_id INT,
industry STRING,
tag STRING,
textrank DOUBLE,
tfidf DOUBLE,
weights DOUBLE
)"""
spark.sql(sql)
spark.sql("INSERT INTO sku_tag_merge_weights SELECT * FROM tempTable")
spark.sql("SELECT * FROM sku_tag_merge_weights").where("sku_id=148").show()
```

显示结果

``` shell
+------+--------+----+-------------------+-------------------+-------------------+
|sku_id|industry| tag|           textrank|              tfidf|            weights|
+------+--------+----+-------------------+-------------------+-------------------+
|   148|    电子产品|  智能|  0.853869407929065|0.12920924724659527|0.49153932758783014|
|   148|    电子产品|WPOS| 0.9474997114660046| 0.6672418695993603| 0.8073707905326825|
|   148|    电子产品|  包邮| 0.5962385663111377| 0.2752684393351877| 0.4357535028231627|
|   148|    电子产品|  购物|  0.442940968516803| 0.2408169399138654| 0.3418789542153342|
|   148|    电子产品|  终端| 0.9880227098783998|  0.515996300178136| 0.7520095050282679|
|   148|    电子产品|  身份| 0.8859077272889758| 0.6107553455735467| 0.7483315364312613|
|   148|    电子产品|  正品| 0.5977867682869656| 0.1984394909665287|0.39811312962674716|
|   148|    电子产品| 触摸屏| 0.8677093692671172|0.31885875801848024| 0.5932840636427987|
|   148|    电子产品|  森锐| 0.8643336666795045| 0.6107553455735467| 0.7375445061265256|
|   148|    电子产品|  数码|0.48644615569271077|0.09416669674352422| 0.2903064262181175|
|   148|    电子产品| 收银机| 0.8606879409613701|0.45724967270727696| 0.6589688068343236|
|   148|    电子产品|  高度|                1.0| 0.3896366762502419|  0.694818338125121|
|   148|    电子产品| 读卡器| 0.6114834155265747|0.22691875231942266| 0.4192010839229987|
|   148|    电子产品|  业务| 0.8500761345577008|  0.537514526329006| 0.6937953304433534|
|   148|    电子产品|数码配件| 0.4880302016489459| 0.2300917543361638| 0.3590609779925549|
+------+--------+----+-------------------+-------------------+-------------------+
```

