每一個人相處都有一套生活方式,跟女人也不同,不一樣的女人要用不一樣的邏輯思考,要琢磨不一樣語句背後的含義,生活,不容易; html
對於情場小白而言,最擔憂的就是女友不開心了,畢竟好不容易纔從右手變成了實物,確定是加倍愛惜的;python
但,你真的瞭解每一句話的情緒分析嗎? 給一句話,能知道這句話的情緒佔比嗎?git
情緒分析關鍵的是詞典,網上找了下,大連理工情感詞彙本體庫比較有名,那就試試看;github
下載地址:json
連接:https://pan.baidu.com/s/18PeWl-9EjZ7O5Rdfejzgig
提取碼:qc3n
複製代碼
下載完後,看了下說明文檔,瞭解下,詞庫裏面的格式是這樣的: api
看起來好像不錯,就試試看~安全
解壓說,發現有這幾個文件: bash
簡單介紹下2個py文件:微信
這裏須要注意,使用evaluate.py時,有可能會報UnicodeEncodeError
這個錯; app
解決也很簡單,在原腳本的第11行,指定encoding用utf-8
便可:
with open('情感詞彙.csv', 'w',encoding='utf-8') as out_file:
複製代碼
而執行evaluate.py時候,須要import docopy跟pandas兩個庫,自行安裝吧;
pip install docopy
pandas的話,以前據說不少依賴,後來jb安裝個anaconda就行了(全家桶);
複製代碼
安裝完兩個庫,因docopy這個庫沒了解過,所以上官網瞭解下:
docopt官網上的介紹是:
Command-line interface description language
docopt helps you:
define interface for your command-line app, and
automatically generate parser for it.
複製代碼
從中能夠看出docopt的兩個主要功能:
再看下官網的例子:
Naval Fate.
Usage:
naval_fate ship new <name>...
naval_fate ship <name> move <x> <y> [--speed=<kn>]
naval_fate ship shoot <x> <y>
naval_fate mine (set|remove) <x> <y> [--moored|--drifting]
naval_fate -h | --help
naval_fate --version
Options:
-h --help Show this screen.
--version Show version.
--speed=<kn> Speed in knots [default: 10].
--moored Moored (anchored) mine.
--drifting Drifting mine.
複製代碼
在這個例子中,Naval Fate
是app名稱,naval_fate
是命令行命令,ship
、new
、 move
這些是可選的執行命令(commands), x
、y
、name
這些是位置參數(positional arguments), -h
、 --help
、--speed
等這些是選項參數(options);
例子裏面用
這些參數,前面加上naval_fate就造成了可用的命令,這些命令在Usage中介紹;
Usage下面的Options裏羅列了選項(options)及其描述,它具體描述了
Usage和options裏的內容就組成了幫助信息,當用戶輸入-h或--help參數時,命令行就會輸出幫助信息。
docopt會抽取幫助信息裏的內容,而後對命令行傳入的參數進行解析。
用實例來講明,建立一個test.py文檔:
"""Naval Fate.
Usage:
naval_fate.py ship new <name>...
naval_fate.py ship <name> move <x> <y> [--speed=<kn>]
naval_fate.py ship shoot <x> <y>
naval_fate.py mine (set|remove) <x> <y> [--moored | --drifting]
naval_fate.py (-h | --help)
naval_fate.py --version
Options:
-h --help Show this screen.
--version Show version.
--speed=<kn> Speed in knots [default: 10].
--moored Moored (anchored) mine.
--drifting Drifting mine.
"""
from docopt import docopt
if __name__ == '__main__':
arguments = docopt(__doc__, version='Naval Fate 2.0')
print(arguments)
複製代碼
執行命令:
python test.py ship new jb
複製代碼
結果:
{'--drifting': False,
'--help': False,
'--moored': False,
'--speed': '10',
'--version': False,
'<name>': ['jb'],
'<x>': None,
'<y>': None,
'mine': False,
'move': False,
'new': True,
'remove': False,
'set': False,
'ship': True,
'shoot': False}
複製代碼
而後再嘗試一個Usage裏沒有的命令:
Usage:
naval_fate.py ship new <name>...
naval_fate.py ship <name> move <x> <y> [--speed=<kn>]
naval_fate.py ship shoot <x> <y>
naval_fate.py mine (set|remove) <x> <y> [--moored | --drifting]
naval_fate.py (-h | --help)
naval_fate.py --version
複製代碼
from docopt import docopt
調用便可;doc
,其餘4個是可選(help
、version
、argv
、options_first
);看回evaluate.py這個文件,頂部有這麼一段:
__doc__ = '''
Usage:
emotion WORD
With Python:
EmotionDict() --> init
EmotionDict.evaluate(word) --> tuple(詞語(str), 情感分類(str), 強度(int), 極性(int)) or None
'''
複製代碼
這裏面也專門告訴py怎麼用了,那新建個test.py試試:
from 情感詞彙.evaluate import EmotionDict
test = EmotionDict()
print(test.evaluate(word="戰禍"))
複製代碼
直接運行,獲得的輸出:
('戰禍', 'ND', 5, 2)
複製代碼
對比了Excel的內容,內容是同樣的;
其餘的,請看說明.doc
,都有說明;
所以,戰禍這個詞,用貶義的方式來表達心裏的憎惡? 不知道爲何,總感受怪怪的;
一個詞就是上面的用法,那一段話呢?
就須要分詞了,中文分詞用的最多就是jieba
庫,不瞭解的同窗,請移步此處;
某博直接找來一段話,結合分詞,一塊兒看看:
seg_list = jieba.cut("帶着立場看比賽註定是痛苦的,倒不如好好品品比賽中每個精彩的瞬間!",cut_all=False)
print("Default Mode: " + "/ ".join(seg_list))
複製代碼
輸出:
Default Mode: 帶/ 着/ 立場/ 看/ 比賽/ 註定/ 是/ 痛苦/ 的/ ,/ 倒不如/ 好好/ 品品/ 比賽/ 中/ 每/ 一個/ 精彩/ 的/ 瞬間/ !
複製代碼
seg_list = jieba.cut("帶着立場看比賽註定是痛苦的,倒不如好好品品比賽中每個精彩的瞬間!",cut_all=False)
test = EmotionDict()
for i in seg_list:
print(i)
print(test.evaluate(word=i))
複製代碼
輸出:
帶
None
着
None
立場
None
看
None
比賽
None
註定
None
是
None
痛苦
('痛苦', 'NB', 7, 0)
的
None
,
None
倒不如
None
好好
None
品品
None
比賽
None
中
None
每
None
一個
None
精彩
('精彩', 'PH', 7, 1)
的
None
瞬間
None
!
None
複製代碼
標點符號沒作過濾,不太影響; 簡單看了下,那麼多個詞,只有精彩、痛苦
是有返回內容的,也就說明,原來的詞庫遠遠不夠;
並且要把對應的PH、數字對應起來,還須要單獨寫一個轉換邏輯,還要過濾各類符號,這裏面仍是有不少小細節作的,到這裏,效果實在太差了,主要是,詞庫內容太少了,不少詞語都沒有,壓根就沒辦法判斷;
既然不本身造輪子,那就看看別人的吧,這種語境分析,第一時間就想起BAT了,那就一塊兒看看BAT吧;
直接某度搜索某度天然語言處理
,直接彈出某度AI開放平臺,點擊後看下產品服務,選擇天然語言處理,就看到有提供情感傾向分析
,同時也有對話情緒識別
兩個服務,二者應該是共同原理,就看前者了;
點擊後,登陸,直接點擊api文檔,翻到情感傾向分析接口;
對包含主觀觀點信息的文本進行情感極性類別(積極、消極、中性)的判斷,並給出相應的置信度。
請求示例
URL參數
參數 | 值 |
---|---|
access_token | 經過API Key和Secret Key獲取的access_token,參考「Access Token獲取」 |
Header以下
參數 | 值 |
---|---|
Content-Type | application/json |
Body請求示例
{
"text": "蘋果是一家偉大的公司"
}
複製代碼
請求參數
參數 | 類型 | 描述 |
---|---|---|
text | string | 文本內容(GBK編碼),最大2048字節 |
返回參數 參數|說明|描述 --|--| log_id|uint64|請求惟一標識碼 sentiment|int|表示情感極性分類結果,0:負向,1:中性,2:正向 confidence|float|表示分類的置信度,取值範圍[0,1] positive_prob|float|表示屬於積極類別的機率 ,取值範圍[0,1] negative_prob|float|表示屬於消極類別的機率,取值範圍[0,1]
返回示例
{
"text":"蘋果是一家偉大的公司",
"items":[
{
"sentiment":2, //表示情感極性分類結果
"confidence":0.40, //表示分類的置信度
"positive_prob":0.73, //表示屬於積極類別的機率
"negative_prob":0.27 //表示屬於消極類別的機率
}
]
}
複製代碼
Access Token獲取是經過API Key和Secret Key來獲取的,那這兩個怎麼獲取?
還記得情感傾向分析的主頁嗎?有個當即使用的按鈕,要去建立應用;
點擊建立應用,輸入應用名稱、描述,而後點擊查看應用詳情,這裏面的API Key 跟Secret Key須要使用到;
來到access token獲取網址,按照要求試試,官方給的是py2,用py3重弄下,代碼以下:
import requests
url = 'https://aip.baidubce.com/oauth/2.0/token'
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.32 Safari/537.36",
"Content-Type":"application/json"
}
params = {
"grant_type":"client_credentials",
"client_id":你的API Key,
"client_secret":你的Secret Key
}
response = requests.post(url,headers=headers,params=params)
text = response.json().get("access_token")
print(text)
複製代碼
對應的結果就是access_token的值啦;
這裏遇到個坑,按照官方文檔操做,用requests庫,不管怎麼調,最終都會報下面這個錯;
{'log_id': 3838837857684473751, 'error_code': 282004, 'error_msg': 'invalid parameter(s)'}
複製代碼
最後網上找了很久,改用urllib庫就行了,一臉懵逼。。貼代碼:
import json
import urllib
# 獲取情緒內容
access_token=你的access_token值
url = 'https://aip.baidubce.com/rpc/2.0/nlp/v1/sentiment_classify?access_token='+access_token
headers={'Content-Type':'application/json'}
post_data = {"text":"帶着立場看比賽註定是痛苦的,倒不如好好品品比賽中每個精彩的瞬間!"}
data=json.dumps(post_data).encode('GBK')
request = urllib.request.Request(url, data)
response = urllib.request.urlopen(request)
content = response.read()
content_str = str(content, encoding="gbk")
print(content_str)
複製代碼
輸出:
{"log_id": 830621152984506211, "text": "帶着立場看比賽註定是痛苦的,倒不如好好品品比賽中每個精彩的瞬間!", "items": [{"positive_prob": 0.521441, "confidence": 0.571177, "negative_prob": 0.478559, "sentiment": 1}]}
複製代碼
根據官網文檔,上面4個字段含義以下:
按照上面的結果,那這句話應該是屬於中性詞,偏積極;
直接找,會發現文智天然語言處理,產品介紹文檔在這裏,API指南在這裏,官方提供demo,py的demo在這裏;
download代碼,github上說須要安全憑證,點擊登陸獲取;
而後還要安裝對應的依賴庫,提供2種方式任君選擇:
$ pip install qcloudapi-sdk-python
或者下載源碼安裝
$ git clone https://github.com/QcloudApi/qcloudapi-sdk-python
複製代碼
python setup.py install
而後打開tests下的demo.py,修改模塊、接口名、接口參數便可;
#!/usr/bin/python
# -*- coding: utf-8 -*-
# 引入雲API入口模塊
from QcloudApi.qcloudapi import QcloudApi
''' module: 設置須要加載的模塊 '''
module = 'wenzhi'
''' action: 對應接口的接口名,請參考wiki文檔上對應接口的接口名 '''
action = 'TextSentiment'
''' config: 雲API的公共參數 '''
config = {
'Region': 'ap-guangzhou',
'secretId': 'AKIDmmuRdgSV8sjR0eokVh2159Kp2OiyPHPQ',
'secretKey': 'DNS9h6aBFLYo2BAEBPePI3d3IMGzb7ml',
}
# 接口參數
action_params = {
"content":"帶着立場看比賽註定是痛苦的,倒不如好好品品比賽中每個精彩的瞬間!"
}
try:
service = QcloudApi(module, config)
print(service.generateUrl(action, action_params))
print(service.call(action, action_params))
except Exception as e:
import traceback
print('traceback.format_exc():\n%s' % traceback.format_exc())
複製代碼
輸出:
b'{"code":0,"message":"","codeDesc":"Success","positive":0.58672362565994,"negative":0.41327640414238}'
複製代碼
對了,某訊沒有免費的體驗,jb恰好是新人領了個免費禮包,若是不是新手,就要本身充錢的,很X訊;
點擊這裏-情感分析,登陸,點擊開通,而後來到控制檯;
點擊基礎版,api調試:
選擇api,這裏關於情感分析的,只有電商類的,其餘都跟情感沒啥關係:
按照要求,輸入你的access key跟secret,點擊調試便可:
關於響應的講解,點擊這裏,能夠看到polarity的參數值,所以,例子是負面的,很合理;
剩下的,就是購買了,270起,感興趣的瞭解下,使用的話,就到這裏了;
阿里提供在線調試,比較方便,可是類型太少了,並且不夠詳細,結果就是正面、負面、中性3選1,一旦哪天有Bug,就慘了;
這個章節不想講述太多內容,以前思路都有講過,只是把代碼結合下而已,詳情請參考下面兩篇文章:
JB的Python之旅-豆瓣自動頂貼功能
JB的Python之旅-爬蟲篇-新浪微博內容爬取
上面3個平臺的結果很明顯,只能用某度,畢竟,免費嘛;
push到微信用的是server醬,直接貼代碼:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import re
from json import JSONDecodeError
import time
import requests
from apscheduler.schedulers.blocking import BlockingScheduler
import json
import urllib
wb_url = "https://m.weibo.cn/profile/info?uid=你要關注的微博用戶id"
server_url = "http://sc.ftqq.com/你的server醬.send"
# 獲取情緒內容
access_token='你的百度access_token值'
bd_url = 'https://aip.baidubce.com/rpc/2.0/nlp/v1/sentiment_classify?access_token='+access_token
wb_headers = {
"Host": "m.weibo.cn",
"Referer": "https://m.weibo.cn/u/隨便,通常是你要關注的微博用戶id",
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) "
"Version/9.0 Mobile/13B143 Safari/601.1",
}
wb_params = {
"text": "{text}",
"desp": "{desp}"
}
statuses_id = ""
scheduler = BlockingScheduler()
page_size = 10
def get_time():
""" 獲取當前時間 """
return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
def push_wx(text=None, desp=None):
""" 推送消息到微信 :param text: 標題 :param desp: 內容 :return: """
wb_params['text'] = text
wb_params['desp'] = desp
response = requests.get(server_url, params=wb_params)
json_data = response.json()
if json_data['errno'] == 0:
print(get_time() + " 推送成功。")
else:
print(json_data)
print("{0} 推送失敗:{1} \n {2}".format(get_time(), json_data['errno'], json_data['errmsg']))
def filter_emoji(text, replace=""):
""" 過濾Emoji表情 :param text: 原文 :param replace: 將Emoji替換爲此內容 :return: 過濾後的內容 """
try:
co = re.compile(u'[\U00010000-\U0010ffff]')
except re.error:
co = re.compile(u'[\uD800-\uDBFF][\uDC00-\uDFFF]')
return co.sub(replace, text)
def get_desp(user, statuse):
""" 獲取微博內容 """
global text;
global nick_name;
# 我的信息
avatar = user['profile_image_url'] # 頭像
nick_name = user['screen_name'] # 暱稱
follow_count = user['follow_count'] # 關注
followers_count = user['followers_count'] # 粉絲
description = user['description'] # 個性簽名
# 微博信息
image = ""
created_at = statuse['created_at'] # 時間
source = statuse['source'] # 發送微博的設備
# 微博內容
if 'raw_text' in statuse:
print(statuse)
text = statuse['raw_text']
else:
text = statuse['text']
text = filter_emoji(text, "[emoji]")
# 獲取圖片
if 'pics' in statuse:
pics = statuse['pics']
for pic in pics:
image += "\n\n".format(pic['url'])
return "\n\n### {1}\n\n關注:{2} and 粉絲:{3}\n\n簽名:{4}\n\n發送時間:{5}\n\n設備:{6}\n\n微博內容:\n\n{7}\n\n{8}" \
.format(avatar, nick_name, follow_count, followers_count, description, created_at, source, text, image)
def start_task():
# print("執行查詢任務")
response = requests.get(wb_url, headers=wb_headers)
try:
json_data = response.json()
except JSONDecodeError as e:
print(get_time() + " Json解析異常, 跳過這次循環:" + str(e))
return
state = json_data['ok']
if state != 1:
push_wx(get_time() + " 你的女友又掛啦,狀態碼:" + str(state) + ",快去看看吧。", "")
scheduler.remove_job('wb')
return
data = json_data['data']
user = data['user']
statuses = data['statuses']
size = len(statuses)
if size < page_size:
print(get_time() + " 返回數據不正確,跳過本次循環。 size:" + str(size))
return
first_statuse = statuses[0]
new_id = first_statuse['id']
global statuses_id
if new_id != statuses_id:
print(get_time() + " 有新微博! id-> " + new_id)
# 獲取微博信息
desp = get_desp(user, first_statuse)
title = "女神更新微博啦"
release_text = SentimentAnalysis()
push_wx(title, release_text+desp + "\n\n[微博原文](https://m.weibo.cn/profile/2105667905)")
statuses_id = new_id
def SentimentAnalysis():
post_data = {"text": text}
data = json.dumps(post_data).encode('GBK')
request = urllib.request.Request(bd_url, data)
response = urllib.request.urlopen(request)
content = response.read()
content_str = str(content, encoding="gbk")
data = json.loads(content_str)
# 積極、消極、可信度的機率
positive_prob = '%.2f%%' % (data["items"][0]["positive_prob"] * 100)
negative_prob = '%.2f%%' % (data["items"][0]["negative_prob"] * 100)
confidence = '%.2f%%' % (data["items"][0]["confidence"] * 100)
sentiment = data["items"][0]["sentiment"]
if (positive_prob > negative_prob):
prob = positive_prob
elif (positive_prob < negative_prob):
prob = negative_prob
else:
prob = positive_prob
if (sentiment == 0 ):
prob_text = "負面"
elif (sentiment == 1 ):
prob_text = "中性"
elif (sentiment == 2):
prob_text = "正向"
analysis_text = "你女神博主:"+nick_name + ",發佈了情緒值爲"+prob+",疑似是"+prob_text+"情緒的微博,快來看看吧,可信度:"+confidence+",微博原文是:"+text
return analysis_text
if __name__ == '__main__':
print(get_time() + " 騷年,噩夢來襲!")
scheduler.add_job(start_task, "interval", seconds=6, id="wb")
scheduler.start()
複製代碼
代碼不能直接用,要手動輸入幾個值,微博用戶id、某度access_token、server醬,完;
%
不知道爲何被過濾了,正常是XX%這樣的格式,可是看着懂就行了,不糾結;
經過上面的推送信息,信息最大化,也得出對應的情緒值,可是,女人說的話,要視不一樣場景而決定其含義;
好比吵架時的分手,其實就是要你哄,要你抱;
好比成家後的不要,是不捨得,偷偷買吧;
複製代碼
而這種含義,不結合語境是無法判斷的;
而女人的心思,別猜,買/哄/舔就對了;
對了,前提是得有個男/女友,否則,仍是買點護膚品慰勞下本身的右手吧;
本文主要介紹了情緒分析的內容,有手動統計,也有利用BAT平臺的接口,出了某度有免費接口提供外,其餘都要收費,並且不低,用來調試或者內部用用,用某度的挺好的,量多可能會收費,但沒找到具體文檔,不糾結了;
同時學習了Py的docopt模塊,會抽取幫助信息裏的內容,而後對命令行傳入的參數進行解析;
而在試用BAT平臺時,會發現調用接口都須要安全憑證/受權校驗,目的仍是爲了安全性,這塊是值得學習的,回想下,內部接口是否無需校驗就可直接調用?是否會被第三方利用的可能?
最好,祝有女友的,幸福美滿,避開全部障礙,早日拉埋天窗; 沒女友的,學會聊天,保持自信,別太死板,最重要是有上進心,陽光活力,換位思考,若是你是女生,你會喜歡本身嗎?
最後,謝謝你們!