From 2e09f51faf77aaad4e137905936f430601d732e9 Mon Sep 17 00:00:00 2001 From: limingjie <560193@gree.com.cn> Date: Fri, 8 Mar 2019 16:38:13 +0800 Subject: [PATCH] frist commit --- bottom_function/.gitkeep | 0 .../__pycache__/data_read.cpython-36.pyc | Bin 0 -> 3044 bytes .../__pycache__/m_SQL.cpython-36.pyc | Bin 0 -> 4156 bytes .../__pycache__/normalization.cpython-36.pyc | Bin 0 -> 1533 bytes bottom_function/data/.gitkeep | 0 bottom_function/data/HGDstopwords.txt | 767 ++++++++++++++++++ bottom_function/data/gree_logo.jpg | Bin 0 -> 85970 bytes .../data/plot_graph/plot_domain.jpg | Bin 0 -> 48357 bytes bottom_function/data/unisound_logfile | 2 + bottom_function/m_SQL.py | 107 +++ bottom_function/normalization.py | 64 ++ .../processing_unisound_logfile.py | 408 ++++++++++ ..._analysis.py => chat_function _analysis.py | 0 domain_structure_analysis.py | 112 +++ response_analysis.py | 50 ++ response_error_analysis.py | 63 ++ response_time_analysis.py | 45 + second_test.py | 159 ++++ time_series_analysis.py | 111 +++ user_portrait_analysis.py | 88 ++ 20 files changed, 1976 insertions(+) delete mode 100644 bottom_function/.gitkeep create mode 100644 bottom_function/__pycache__/data_read.cpython-36.pyc create mode 100644 bottom_function/__pycache__/m_SQL.cpython-36.pyc create mode 100644 bottom_function/__pycache__/normalization.cpython-36.pyc delete mode 100644 bottom_function/data/.gitkeep create mode 100644 bottom_function/data/HGDstopwords.txt create mode 100644 bottom_function/data/gree_logo.jpg create mode 100644 bottom_function/data/plot_graph/plot_domain.jpg create mode 100644 bottom_function/data/unisound_logfile create mode 100644 bottom_function/m_SQL.py create mode 100644 bottom_function/normalization.py create mode 100644 bottom_function/processing_unisound_logfile.py rename chat_function__analysis.py => chat_function _analysis.py (100%) create mode 100644 domain_structure_analysis.py create mode 100644 response_analysis.py create mode 100644 response_error_analysis.py create mode 100644 response_time_analysis.py create mode 100644 second_test.py create mode 100644 time_series_analysis.py create mode 100644 user_portrait_analysis.py diff --git a/bottom_function/.gitkeep b/bottom_function/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/bottom_function/__pycache__/data_read.cpython-36.pyc b/bottom_function/__pycache__/data_read.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..505ee565a246996d3291be877a52fd95c07dca45 GIT binary patch literal 3044 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 literal 0 HcmV?d00001 diff --git a/bottom_function/__pycache__/normalization.cpython-36.pyc b/bottom_function/__pycache__/normalization.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..60228e84415bcb4873560640dfa3cef36a58a460 GIT binary patch literal 1533 zcmZWoO>f&q5Zy0QGG)nfn>J}sw26TpSfEOSUV^|d3e<4ZLj|KwQGigOGTgO7nj-1l zb?q3`NxAmWpV42_`(AtMU+}3jE7@^fN*vDa4u|i}oB5{SkNy&B@>7S9zsaqOga0ku z<|P#qI0&he1FbyHN*^sXS8I0uu}oqn4^&+F?AiSnljB4 z?6A?-j+yg6iG~W1s~`5CPY&N^Z&E!!)ODdUYbHj`)5_-A6yCANwVqE8emt7IuC1-- z)8n%$vw2-jDmX~X{4&MWsCj!8?UuQ*Sv_y|`UnkihUD^#nX=PsCQ}Ro+cgpI;t)^$f6fRh88;uVw&N)Qzg#hE}O8^GcbRB?C+~#i~r3)V^{3|D^V$R;CM| zciaE__y$4?!4NL!L#hYh9b||VFYFTZy=I?*(^50Eq@XQo#Hz@GVk^I8P+>ZbxeJP1 zy-pp^&aC5&nZ-Qm8dX^!qF|#o4wf@d{Vu*99@yHSZNujbq9#O%> z(0&ESk|kNN8Cmd)!xoz8)r*AyxI3*_1kh?>wb_b-E&{M@5w>B$C0$bU{B+m`Ej#Jx zp%rbgq>`NoJ#2Xq;EIyd;V-1+K#q?ctu(e>9QryrfpvG{xJ+j*GB(xLoaZ0{FF~d- zZ9pvzC>?;0KI5H2x5E@be^$_q2 zSqQ6$GIoy+n8ui!3gNKbRA>hlIA$$fvIVoWW!{4t6s+YSrfB_$jIZdUnEO)uY)%w) zUd4eER$W-n!iBazQI$!yR=|`5$^1tD{RRf#A@hk=^ZGY6HI2&hw4CCUr5RMhJOyxT zsUsi*Qa`>+M8JlZ`b%&?WOnh$i~L~0ffn~*maO zCdu~o)B=a~{^t;u1W5MjT>`_K=ymWjh&2%yXi*x8hz_X6LdW!A{qH%Zl?#p4Fu{5Y z&XP?(9wV3okUj}lPmSH~o9cb(SFkbPEg-(8ewMqt^ID#jY7aZo48e3M{-U7Uje5~X GQRiRHs9{Y2 literal 0 HcmV?d00001 diff --git a/bottom_function/data/.gitkeep b/bottom_function/data/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/bottom_function/data/HGDstopwords.txt b/bottom_function/data/HGDstopwords.txt new file mode 100644 index 0000000..a5a37bc --- /dev/null +++ b/bottom_function/data/HGDstopwords.txt @@ -0,0 +1,767 @@ +——— +》), +)÷(1- +”, +)、 +=( +: +→ +℃ +& +* +一一 +~~~~ +’ +. +『 +.一 +./ +-- +』 +=″ +【 +[*] +}> +[⑤]] +[①D] +c] +ng昉 +* +// +[ +] +[②e] +[②g] +={ +} +,也 +‘ +A +[①⑥] +[②B] +[①a] +[④a] +[①③] +[③h] +③] +1. +-- +[②b] +’‘ +××× +[①⑧] +0:2 +=[ +[⑤b] +[②c] +[④b] +[②③] +[③a] +[④c] +[①⑤] +[①⑦] +[①g] +∈[ +[①⑨] +[①④] +[①c] +[②f] +[②⑧] +[②①] +[①C] +[③c] +[③g] +[②⑤] +[②②] +一. +[①h] +.数 +[] +[①B] +数/ +[①i] +[③e] +[①①] +[④d] +[④e] +[③b] +[⑤a] +[①A] +[②⑧] +[②⑦] +[①d] +[②j] +〕〔 +][ +:// +′∈ +[②④ +[⑤e] +12% +b] +... +................... +…………………………………………………③ +ZXFITL +[③F] +」 +[①o] +]∧′=[ +∪φ∈ +′| +{- +②c +} +[③①] +R.L. +[①E] +Ψ +-[*]- +↑ +.日 +[②d] +[② +[②⑦] +[②②] +[③e] +[①i] +[①B] +[①h] +[①d] +[①g] +[①②] +[②a] +f] +[⑩] +a] +[①e] +[②h] +[②⑥] +[③d] +[②⑩] +e] +〉 +】 +元/吨 +[②⑩] +2.3% +5:0 +[①] +:: +[②] +[③] +[④] +[⑤] +[⑥] +[⑦] +[⑧] +[⑨] +…… +—— +? +、 +。 +“ +” +《 +》 +! +, +: +; +? +. +, +. +' +? +· +——— +── +? +— +< +> +( +) +〔 +〕 +[ +] +( +) +- ++ +~ +× +/ +/ +① +② +③ +④ +⑤ +⑥ +⑦ +⑧ +⑨ +⑩ +Ⅲ +В +" +; +# +@ +γ +μ +φ +φ. +× +Δ +■ +▲ +sub +exp +sup +sub +Lex +# +% +& +' ++ ++ξ +++ +- +-β +< +<± +<Δ +<λ +<φ +<< += += +=☆ +=- +> +>λ +_ +~± +~+ +[⑤f] +[⑤d] +[②i] +≈ +[②G] +[①f] +LI +㈧ +[- +...... +〉 +[③⑩] +第二 +一番 +一直 +一些 +一下 +许多 +种 +有的是 +也就是说 +末##末 +啊 +阿 +哎 +哎呀 +哎哟 +唉 +俺 +俺们 +按 +按照 +吧 +吧哒 +把 +罢了 +被 +本 +本着 +比 +比方 +比如 +鄙人 +彼 +彼此 +边 +别 +别的 +别说 +并 +并且 +不比 +不成 +不单 +不但 +不独 +不管 +不光 +不过 +不仅 +不拘 +不论 +不怕 +不然 +不如 +不特 +不惟 +不问 +不只 +朝 +朝着 +趁 +趁着 +乘 +冲 +除 +除此之外 +除非 +除了 +此 +此间 +此外 +从 +从而 +打 +待 +但 +但是 +当 +当着 +到 +得 +的 +的话 +等 +等等 +地 +第 +叮咚 +对 +对于 +多 +多少 +而 +而况 +而且 +而是 +而外 +而言 +而已 +尔后 +反过来 +反过来说 +反之 +非但 +非徒 +否则 +嘎 +嘎登 +该 +赶 +个 +各 +各个 +各位 +各种 +各自 +给 +根据 +跟 +故 +故此 +固然 +关于 +管 +归 +果然 +果真 +过 +哈 +哈哈 +呵 +和 +何 +何处 +何况 +何时 +嘿 +哼 +哼唷 +呼哧 +乎 +哗 +还是 +还有 +换句话说 +换言之 +或 +或是 +或者 +极了 +及 +及其 +及至 +即 +即便 +即或 +即令 +即若 +即使 +几 +几时 +己 +既 +既然 +既是 +继而 +加之 +假如 +假若 +假使 +鉴于 +将 +较 +较之 +叫 +接着 +结果 +借 +紧接着 +进而 +尽 +尽管 +经 +经过 +就 +就是 +就是说 +据 +具体地说 +具体说来 +开始 +开外 +靠 +咳 +可 +可见 +可是 +可以 +况且 +啦 +来 +来着 +离 +例如 +哩 +连 +连同 +两者 +了 +临 +另 +另外 +另一方面 +论 +嘛 +吗 +慢说 +漫说 +冒 +么 +每 +每当 +们 +莫若 +某 +某个 +某些 +拿 +哪 +哪边 +哪儿 +哪个 +哪里 +哪年 +哪怕 +哪天 +哪些 +哪样 +那 +那边 +那儿 +那个 +那会儿 +那里 +那么 +那么些 +那么样 +那时 +那些 +那样 +乃 +乃至 +呢 +能 +你 +你们 +您 +宁 +宁可 +宁肯 +宁愿 +哦 +呕 +啪达 +旁人 +呸 +凭 +凭借 +其 +其次 +其二 +其他 +其它 +其一 +其余 +其中 +起 +起见 +起见 +岂但 +恰恰相反 +前后 +前者 +且 +然而 +然后 +然则 +让 +人家 +任 +任何 +任凭 +如 +如此 +如果 +如何 +如其 +如若 +如上所述 +若 +若非 +若是 +啥 +上下 +尚且 +设若 +设使 +甚而 +甚么 +甚至 +省得 +时候 +什么 +什么样 +使得 +是 +是的 +首先 +谁 +谁知 +顺 +顺着 +似的 +虽 +虽然 +虽说 +虽则 +随 +随着 +所 +所以 +他 +他们 +他人 +它 +它们 +她 +她们 +倘 +倘或 +倘然 +倘若 +倘使 +腾 +替 +通过 +同 +同时 +哇 +万一 +往 +望 +为 +为何 +为了 +为什么 +为着 +喂 +嗡嗡 +我 +我们 +呜 +呜呼 +乌乎 +无论 +无宁 +毋宁 +嘻 +吓 +相对而言 +像 +向 +向着 +嘘 +呀 +焉 +沿 +沿着 +要 +要不 +要不然 +要不是 +要么 +要是 +也 +也罢 +也好 +一 +一般 +一旦 +一方面 +一来 +一切 +一样 +一则 +依 +依照 +矣 +以 +以便 +以及 +以免 +以至 +以至于 +以致 +抑或 +因 +因此 +因而 +因为 +哟 +用 +由 +由此可见 +由于 +有 +有的 +有关 +有些 +又 +于 +于是 +于是乎 +与 +与此同时 +与否 +与其 +越是 +云云 +哉 +再说 +再者 +在 +在下 +咱 +咱们 +则 +怎 +怎么 +怎么办 +怎么样 +怎样 +咋 +照 +照着 +者 +这 +这边 +这儿 +这个 +这会儿 +这就是说 +这里 +这么 +这么点儿 +这么些 +这么样 +这时 +这些 +这样 +正如 +吱 +之 +之类 +之所以 +之一 +只是 +只限 +只要 +只有 +至 +至于 +诸位 +着 +着呢 +自 +自从 +自个儿 +自各儿 +自己 +自家 +自身 +综上所述 +总的来看 +总的来说 +总的说来 +总而言之 +总之 +纵 +纵令 +纵然 +纵使 +遵照 +作为 +兮 +呃 +呗 +咚 +咦 +喏 +啐 +喔唷 +嗬 +嗯 +嗳 \ No newline at end of file diff --git a/bottom_function/data/gree_logo.jpg b/bottom_function/data/gree_logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..92941586bc459623366401167132e4a8b423c7dc GIT binary patch literal 85970 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 `)KEdC`c)P6lik8o+x#+2rVkzn+sE1z$E&16*-* zA-L*{MRWcfaH5DIAl^W3ClE`)UCM*Tz6&LPP88v70w~?&DJbTTM2zX6{5P0s5*oR= z)8T|$LD!3LCy=O}4J5mhFHwq}ShX5zxDQ_YG%%T<)7E$Mh1I@IYy2ekEk-!$wg9|g zc#r_3@g$h=6h2Ee_a9PyN{xTJ$B_I1G6mxOy&!#h5PMQ~+T2}~H*({vtlVC)uaWNR zS<}enyXU6W(}tStksHOB2{U{dg{K3&G(daLbJ74k@Yh5CH6wS@Z92HS?*nFda}m_g z1WoSMcT)s%fMh@-Q3}*EpT8D>!INId{@+~G7oho@Bi@|xXMG)6`4^Rr+t`QfcxWsD zAw|M=h_S7|OQ=5b|fpw%MvDZJLuE z1QYy((z+=WR~#+S*)Pa@PMAUn8=1>A*Cgly(~8Frc@ChJ#_i;^rnk@Fd> z|K2}R2S9(o)cYoz+y$B@W8;IuGU!DYRp3pS++S6w4-zvX{cZ>@P>>s+vHT9oYrn5k z5x)NYO*%RGRKqvP8cFR#6RWzRX6EE}N(K<8+Ns~f8FOoLGnj^h#-l*4zt;s!hh5X| zrcP5Zv0IqY^QU5nJKq4@-xbPq!jha$MSbL^Rp=SRJ7ai1yR#X?J7ajKvn8L;%^2Q) z;*~xNNOA;}bFSjs_YTHl(os0gsY4EutV%Mx&?I^15&bP~Ez9r7 zu_zDsWV5BmcE3=*b?AE0b^Nx5Nb-9q^DQ-dr61rW?O+Di!Fr{1Vb1j%A$(ER6R)=g zwmSQBOpndAaX2Bp(A3@I^y~=tZ8dM2ZRO^pHd5Z-V3n88hB+K67YC1UHuKNlCt>rd zX`|SswvOB!>1R>bQyVMQ_t+UYECsNlW1zQ9!pQP)E#j-~_i|W7_hz|LD7(DBu(L{p zWB{5_-t}hr*py?WHPa-Dpr6w9#S%d8xx^M`S?;4!&E1fra?XX*hiwb`4&SuuPmEiZ zzW5w8mvM|5P7u{Md-%B-xXZ>f*kHR&9OU{#zBy;U0xD2+jg8@>$1VrGJ_`=OL&hQ__eVL``iYs8h#ojYK8wENu%pd-vJWGqznZ>NDR_n%05 z_4&5KMd&a~@+uBCkiY4K+n8wVT665a+E39wz`s!?zCC5X3SiHWuo*X=#|un`RoX@*%=i}t1Fe= z5;`&;3g3o#h{#>GQpb2n?71SaM=VBP)&^S?;jr24+%U4b(=*9D*r9l`w0KLX(`k*v zX%+9s*C}TixGS&IylWpJlGCQdwc`w3ab-9YLh(5YG_YdW{fJ#&MpyzH6w*cOhDZ_~ zt`7|7Qj=RRXSW)?Jaw(7euektWQz_C>%?c=*6opoHF?m3jt zlDVlm2Q^t1^7px)LD3@Z_TMHA2Q^|pGPKLLsF2k(cS?8YMDrztS?9{Df^;cGgir!| zKa(=a2+DR}$uqFfHNMzBLV6JCh!9EI;ZGtp-Ih4GE!e7O^VqR;4CzR^9#UOY=?sId>BP&z*eK+PrtlwWlN z!XF2Q18owAr%=ZMI0-0%;%V<0tQ98+BfZJ37-T1ZAF|vHnnK~7d`3V~6T0$(+L#iu zJWdeD=!Ov-1h7X?>o^=vfdjp{7XV9BCk$94AU+mU>U68VJvl`UJ@QxHp)1WD7s{ z2OcOMQ9Nn*nH9wJp3gw$n{p;#U>Z!d1$xEqAfmt5U78 zG*@(ZH!TIQ-j(10LYZ)x7GYy0;s+o> zSkeO7PyPtXK87wqpGqPATVgika8l#rA7X@|e@W&U*{hD_3sr3M|;Ns}ApOdh8LjW__i``5w${7@K< z0&I+stN<}4h-rrFKJHNKW≫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 Ww^e>HRG5+TjGX^XbO1fo_= "' + startTime + '" and datetime< "' + endTime + '"' + data = pd.read_sql_query(sql, con=engine) + return data + + def delData(self, tableName, keyWord): + word='"'+keyWord+'"' + sql = 'DELETE FROM {tableName} WHERE query={keys}'.format(tableName=tableName,keys=word) + self.cursor.execute(sql) + self.commit() + + + # 关闭数据库连接 + def closeConnect(self): + self.db.close() + + # 提交 + def commit(self): + self.db.commit() + + def delete(self, tableName): + self.db.cursor("DELETE * FROM {}".format(tableName)) + + + diff --git a/bottom_function/normalization.py b/bottom_function/normalization.py new file mode 100644 index 0000000..b93466c --- /dev/null +++ b/bottom_function/normalization.py @@ -0,0 +1,64 @@ +import re +import string +import jieba +import jieba.posseg as psg + + +# 加载停用词 + +def get_stopword_list(): + # 停用词表存储路径,每一行为一个词,按行读取进行加载 + # 进行编码转换确保匹配准确率 + stop_word_path = './data/HGDstopwords.txt' + stopword_list = [sw.replace('\n', '') for sw in open(stop_word_path, encoding='UTF-8').readlines()] + return stopword_list + + +def seg_to_list(sentence, pos=False): + if not pos: + # 不进行词性标注的分词方法 + seg_list = jieba.cut(sentence) + else: + # 进行词性标注的分词方法 + seg_list = psg.cut(sentence) + return seg_list + + +# 去除干扰词 +def word_filter(seg_list, pos=False): + stopword_list = get_stopword_list() + filter_list = [] + # 根据POS参数选择是否词性过滤 + ## 不进行词性过滤,则将词性都标记为n,表示全部保留 + for seg in seg_list: + if not pos: + word = seg + flag = 'n' + else: + word = seg.word + flag = seg.flag + if not flag.startswith('n'): + continue + # 过滤停用词表中的词,以及长度为<2的词 + if not word in stopword_list and len(word) > 0: + filter_list.append(word) + + return filter_list + + +def remove_special_characters(text, pos=False): + tokens = seg_to_list(text, pos) + filtered_tokens = word_filter(tokens, pos) + filtered_text = ' '.join(filtered_tokens) + return filtered_text + + +def normalize_corpus(corpus, pos): + normalized_corpus = [] + for text in corpus: + # corrected_sent, detail = pycorrector.correct(text) + # print(detail) + # text1 = remove_special_characters(corrected_sent, pos) + text1 = remove_special_characters(text, pos) + normalized_corpus.append(text1) + return normalized_corpus diff --git a/bottom_function/processing_unisound_logfile.py b/bottom_function/processing_unisound_logfile.py new file mode 100644 index 0000000..e58569a --- /dev/null +++ b/bottom_function/processing_unisound_logfile.py @@ -0,0 +1,408 @@ +# -*- coding: utf-8 -*- +# author:Li Mingjie time:2019/1/24 +# Brief:process unisound logfile + +import json +import re +import pandas as pd +import threading +import bottom_function.m_SQL as qb +import datetime as dt +import paramiko + + +class timing_processing: + def __init__(self): + self.data = pd.DataFrame() + self.datetime = pd.Timestamp("2019-01-01 00:00:00") + self.db = qb.Schema(host="localhost", user="root", password="560193", mysqlName="semantic_data_schema", + port="3306") + self.gree_list = ["aircleaner", "airconditioner", "airconditionerfan", "airsteward", "curtain", + "dehumidifier", "disinfection", "fanner", "furnace", "humidifier", "playcontrol", + "refrigerator", "ricecooker", "smokelampblackmachine", "universalcontrol", "ventilation", + "washingmachine", + "waterheater"] + self.tencent_list = ["almanac", "ancient_poem", "astro", "baike", "chat", "chengyu", "common_qa", "finance", + "fm", "food", "general_question_answering", "history", "holiday", "joke", "music", "news", + "recipe", "science", "sound", "sports", "stock", "translate", "weather"] + + def data_storage(self): + data = open('./data/unisound_logfile', 'r', encoding='utf-8').readlines() + + datetime_data = [] + macwifi_data = [] + macvoice_data = [] + query_data = [] + classify_data = [] + code_data = [] + domain_data = [] + intent_data = [] + response_data = [] + costtime_data = [] + + error_data = [] + for line_data in data: + if line_data == '': + continue + line_data = line_data.strip('\n') + data1 = str(line_data).lower() + data1 = data1.replace('[ctoc query log]', '{"ctoc query log":{"time":"') + data1 = data1 + '"}}' + + data1 = data1.replace('request:', '","request_m":"') + data1 = data1.replace('{"reqparam":', '","request":{"reqparam":') + # data1 = data1.replace('true', '"true"').replace('false', '"false"') + data1 = data1.replace("\'", "") + # data1 = data1.replace('\\', '') + data1 = data1.replace('response:', '"response":').replace('costtime:', ',"costtime":"') + data1 = data1.replace('\t', '') + js_data = json.loads(data1) + + try: + dom = 'null' + inte = 'null' + resp = 'null' + code = 0 + macw = 'null' + macv = 'null' + datetime = js_data['ctoc query log']['time'] + qu = js_data['ctoc query log']['request']['reqparam']['nluret']['asr_recongize'] + qu = re.sub(',', '', qu) + if 'status' in js_data['ctoc query log']['response']: + cla = 'control' + else: + cla = 'application' + if cla == 'application': + dom = js_data['ctoc query log']['response']['header']['semantic']['domain'] + inte = js_data['ctoc query log']['response']['header']['semantic']['intent'] + if js_data['ctoc query log']['response']['response_text'] is not None: + resp = str(js_data['ctoc query log']['response']['response_text']) + resp = resp.replace('\n', '').replace(' ', '') + code = js_data['ctoc query log']['response']['header']['semantic']['code'] + else: + code = js_data['ctoc query log']['response']['code'] + dom = inte = resp = js_data['ctoc query log']['response']['errortype'] + if cla == 'control': + code = js_data['ctoc query log']['response']['status']['code'] + errort = js_data['ctoc query log']['response']['status']['errortype'] + resp = errort + if code == 0: + dom = js_data['ctoc query log']['response']['semantic']['service'] + inte = js_data['ctoc query log']['response']['semantic']['action'] + else: + dom = errort + inte = errort + costt = str(js_data['ctoc query log']['costtime']) + costt = str(costt.replace('ms', '')) + if 's' in costt: + m_cost = float(costt.split('s', 1)[0]) * 1000 + else: + m_cost = float(costt) + par = js_data['ctoc query log']['request']['reqparam']['common']['trafficparameter'] + par_list = par.split(';') + for m_par in par_list: + if 'macwifi' in m_par: + macw = m_par.replace('macwifi=', '') + elif 'macvoice' in m_par: + macv = m_par.replace('macvoice=', '') + + datetime_data.append(datetime) + macwifi_data.append(macw) + macvoice_data.append(macv) + query_data.append(qu) + classify_data.append(cla) + code_data.append(code) + domain_data.append(dom) + intent_data.append(inte) + response_data.append(resp) + costtime_data.append(m_cost) + except: + error_data.append(line_data) + + outdata = pd.DataFrame( + {'datetime': datetime_data, 'mac_wifi': macwifi_data, 'mac_voice': macvoice_data, + 'query': query_data, 'classify': classify_data, 'code': code_data, + 'domain': domain_data, 'intent': intent_data, 'response_data': response_data, + 'cost_time_ms': costtime_data}) + errordata = pd.DataFrame({'data': error_data}) + + outdata['datetime'] = pd.to_datetime(outdata['datetime']) + outdata = outdata.sort_values(by=['datetime']) + self.datetime = dt.datetime.strftime(outdata['datetime'][0], "%Y-%m-%d %H ") + outdata = outdata.set_index('datetime') + self.data = outdata + control_error_data = outdata[(outdata['classify'] == 'control') & (outdata['code'] != 0)] + application_error_data = outdata[(outdata['classify'] == 'application') & (outdata['code'] != 0)] + control_error_data.drop_duplicates(subset='query', keep='first', inplace=True) + application_error_data.drop_duplicates(subset='query', keep='first', inplace=True) + + self.db.dataframeToMysql(data=outdata, tableName="semantic_data_table") + self.db.dataframeToMysql(data=errordata, tableName="error_format_data") + self.db.dataframeToMysql(data=control_error_data, tableName="control_error_data") + self.db.dataframeToMysql(data=application_error_data, tableName="application_error_data") + + print('storage the data to SQL is complete') + + # timer=threading.Timer(3600,data_storage) + # timer.start() + + def domain_data_to_statistics(self, data, data_type): + + print('Start domain data classification:') + data_dict_domain = {} + if data_type == 'control': + data_dict_domain = {"datetime": pd.Timestamp(2019, 1, 1), "aircleaner": 0, "airconditioner": 0, + "airconditionerfan": 0, "airsteward": 0, "curtain": 0, "dehumidifier": 0, + "disinfection": 0, "fanner": 0, "furnace": 0, "humidifier": 0, "playcontrol": 0, + "refrigerator": 0, "ricecooker": 0, + "smokelampblackmachine": 0, "universalcontrol": 0, "ventilation": 0, + "washingmachine": 0, "waterheater": 0} + + table_name = "control_domain_data" + self.gree_list = self.db.GetField(tableName=table_name) + domain_list = self.gree_list + + elif data_type == 'application': + data_dict_domain = {"datetime": pd.Timestamp(2019, 1, 1), "almanac": 0, "ancient_poem": 0, "astro": 0, + "baike": 0, "chat": 0, "chengyu": 0, "common_qa": 0, "finance": 0, "fm": 0, "food": 0, + "general_question_answering": 0, "history": 0, "holiday": 0, "joke": 0, "music": 0, + "news": 0, "recipe": 0, "science": 0, "sound": 0, "sports": 0, "stock": 0, + "translate": 0, + "weather": 0} + table_name = "application_domain_data" + self.tencent_list = self.db.GetField(tableName=table_name) + domain_list = self.tencent_list + else: + print("data_type is error,you must chose control or application.") + return -1 + + sm_data = data + for domain_data in sm_data['domain']: + if domain_data in data_dict_domain.keys(): + data_dict_domain[domain_data] = data_dict_domain[domain_data] + 1 + else: + data_dict_domain.update({domain_data: 1}) + + if domain_data not in domain_list: + if data_type == 'control': + self.gree_list.append(domain_data) + if data_type == 'control': + self.tencent_list.append(domain_data) + self.db.setAddField(tableName=table_name, field=domain_data) + + data_dict_domain['datetime'] = self.datetime + aldtaframe = pd.DataFrame(data_dict_domain, index=[0]) + aldtaframe['datetime'] = pd.to_datetime(aldtaframe['datetime']) + aldtaframe = aldtaframe.set_index('datetime') + + self.db.dataframeToMysql(data=aldtaframe, tableName=table_name) + + print("Complete write") + + def costtime_data_to_statistics(self, data): + print('Start cost time data statistics:') + all_data_dict = {} + gree_list = self.gree_list + tencent_list = self.tencent_list + + all_data_dict = {"datetime": pd.Timestamp(2019, 1, 1), "0~500ms": "0", "500~1000ms": "0", "1000~2000ms": "0", + "2000~3000ms": "0", "3000~5000ms": "0", "morethan5000ms": "0", } + + all_tencent_dict = {} + all_gree_dict = {} + gree_data_dict = {} + tencent_data_dict = {} + + tencent_data = data[data['classify'] == 'tencent'] + gree_data = data[data['classify'] == 'gree'] + for dom1 in tencent_list: + num1 = tencent_data.loc[(tencent_data['cost_time_ms'] >= 0) & (tencent_data['cost_time_ms'] < 500) & ( + tencent_data['domain'] == dom1), ['domain', 'cost_time_ms']].domain.count() + tencent_data_dict.update({dom1: num1}) + sort_data_list = sorted(tencent_data_dict.items(), key=lambda item: item[1], reverse=True) + if len(sort_data_list) >= 3: + all_tencent_dict.update({"tencent1": sort_data_list[:3]}) + else: + all_tencent_dict.update({"tencent1": sort_data_list}) + tencent_data_dict.clear() + sort_data_list.clear() + + for dom2 in tencent_list: + num1 = tencent_data.loc[(tencent_data['cost_time_ms'] >= 500) & (tencent_data['cost_time_ms'] < 1000) & ( + tencent_data['domain'] == dom2), ['domain', 'cost_time_ms']].domain.count() + tencent_data_dict.update({dom2: num1}) + sort_data_list = sorted(tencent_data_dict.items(), key=lambda item: item[1], reverse=True) + if len(sort_data_list) >= 3: + all_tencent_dict.update({"tencent2": sort_data_list[:3]}) + else: + all_tencent_dict.update({"tencent2": sort_data_list}) + tencent_data_dict.clear() + sort_data_list.clear() + + for dom3 in tencent_list: + num1 = tencent_data.loc[(tencent_data['cost_time_ms'] >= 1000) & (tencent_data['cost_time_ms'] < 2000) & ( + tencent_data['domain'] == dom3), ['domain', 'cost_time_ms']].domain.count() + tencent_data_dict.update({dom3: num1}) + sort_data_list = sorted(tencent_data_dict.items(), key=lambda item: item[1], reverse=True) + if len(sort_data_list) >= 3: + all_tencent_dict.update({"tencent3": sort_data_list[:3]}) + else: + all_tencent_dict.update({"tencent3": sort_data_list}) + tencent_data_dict.clear() + sort_data_list.clear() + + for dom4 in tencent_list: + num1 = tencent_data.loc[(tencent_data['cost_time_ms'] >= 2000) & (tencent_data['cost_time_ms'] < 3000) & ( + tencent_data['domain'] == dom4), ['domain', 'cost_time_ms']].domain.count() + tencent_data_dict.update({dom4: num1}) + sort_data_list = sorted(tencent_data_dict.items(), key=lambda item: item[1], reverse=True) + if len(sort_data_list) >= 3: + all_tencent_dict.update({"tencent4": sort_data_list[:3]}) + else: + all_tencent_dict.update({"tencent4": sort_data_list}) + tencent_data_dict.clear() + sort_data_list.clear() + + for dom5 in tencent_list: + num1 = tencent_data.loc[(tencent_data['cost_time_ms'] >= 3000) & (tencent_data['cost_time_ms'] < 5000) & ( + tencent_data['domain'] == dom5), ['domain', 'cost_time_ms']].domain.count() + tencent_data_dict.update({dom5: num1}) + sort_data_list = sorted(tencent_data_dict.items(), key=lambda item: item[1], reverse=True) + if len(sort_data_list) >= 3: + all_tencent_dict.update({"tencent5": sort_data_list[:3]}) + else: + all_tencent_dict.update({"tencent5": sort_data_list}) + tencent_data_dict.clear() + sort_data_list.clear() + + for dom6 in tencent_list: + num1 = tencent_data.loc[ + (tencent_data['cost_time_ms'] >= 5000) & (tencent_data['domain'] == dom6), ['domain', + 'cost_time_ms']].domain.count() + tencent_data_dict.update({dom6: num1}) + sort_data_list = sorted(tencent_data_dict.items(), key=lambda item: item[1], reverse=True) + if len(sort_data_list) >= 3: + all_tencent_dict.update({"tencent6": sort_data_list[:3]}) + else: + all_tencent_dict.update({"tencent6": sort_data_list}) + tencent_data_dict.clear() + sort_data_list.clear() + + for gom1 in gree_list: + num1 = gree_data.loc[ + (gree_data['cost_time_ms'] >= 0) & (gree_data['cost_time_ms'] < 500) & (gree_data['domain'] == gom1), [ + 'domain', 'cost_time_ms']].domain.count() + gree_data_dict.update({gom1: num1}) + sort_data_list = sorted(gree_data_dict.items(), key=lambda item: item[1], reverse=True) + if len(sort_data_list) >= 3: + all_gree_dict.update({"gree1": sort_data_list[:3]}) + else: + all_gree_dict.update({"gree1": sort_data_list}) + gree_data_dict.clear() + sort_data_list.clear() + + for gom2 in gree_list: + num1 = gree_data.loc[(gree_data['cost_time_ms'] >= 500) & (gree_data['cost_time_ms'] < 1000) & ( + gree_data['domain'] == gom2), ['domain', 'cost_time_ms']].domain.count() + gree_data_dict.update({gom2: num1}) + sort_data_list = sorted(gree_data_dict.items(), key=lambda item: item[1], reverse=True) + if len(sort_data_list) >= 3: + all_gree_dict.update({"gree2": sort_data_list[:3]}) + else: + all_gree_dict.update({"gree2": sort_data_list}) + gree_data_dict.clear() + sort_data_list.clear() + + for gom3 in gree_list: + num1 = gree_data.loc[(gree_data['cost_time_ms'] >= 1000) & (gree_data['cost_time_ms'] < 2000) & ( + gree_data['domain'] == gom3), ['domain', 'cost_time_ms']].domain.count() + gree_data_dict.update({gom3: num1}) + sort_data_list = sorted(gree_data_dict.items(), key=lambda item: item[1], reverse=True) + if len(sort_data_list) >= 3: + all_gree_dict.update({"gree3": sort_data_list[:3]}) + else: + all_gree_dict.update({"gree3": sort_data_list}) + gree_data_dict.clear() + sort_data_list.clear() + + for gom4 in gree_list: + num1 = gree_data.loc[(gree_data['cost_time_ms'] >= 2000) & (gree_data['cost_time_ms'] < 3000) & ( + gree_data['domain'] == gom4), ['domain', 'cost_time_ms']].domain.count() + gree_data_dict.update({gom4: num1}) + sort_data_list = sorted(gree_data_dict.items(), key=lambda item: item[1], reverse=True) + if len(sort_data_list) >= 3: + all_gree_dict.update({"gree4": sort_data_list[:3]}) + else: + all_gree_dict.update({"gree4": sort_data_list}) + gree_data_dict.clear() + sort_data_list.clear() + + for gom5 in gree_list: + num1 = gree_data.loc[(gree_data['cost_time_ms'] >= 3000) & (gree_data['cost_time_ms'] < 5000) & ( + gree_data['domain'] == gom5), ['domain', 'cost_time_ms']].domain.count() + gree_data_dict.update({gom5: num1}) + sort_data_list = sorted(gree_data_dict.items(), key=lambda item: item[1], reverse=True) + if len(sort_data_list) >= 3: + all_gree_dict.update({"gree5": sort_data_list[:3]}) + else: + all_gree_dict.update({"gree5": sort_data_list}) + gree_data_dict.clear() + sort_data_list.clear() + + for gom6 in gree_list: + num1 = gree_data.loc[(gree_data['cost_time_ms'] >= 5000) & (gree_data['domain'] == gom6), ['domain', + 'cost_time_ms']].domain.count() + gree_data_dict.update({gom6: num1}) + sort_data_list = sorted(gree_data_dict.items(), key=lambda item: item[1], reverse=True) + if len(sort_data_list) >= 3: + all_gree_dict.update({"gree6": sort_data_list[:3]}) + else: + all_gree_dict.update({"gree6": sort_data_list}) + gree_data_dict.clear() + sort_data_list.clear() + + for c, g, t in zip(list(all_data_dict.keys())[1:], all_gree_dict.values(), all_tencent_dict.values()): + all_data_dict[c] = str(g + t) + all_data_dict['datetime'] = self.datetime + + aldtaframe = pd.DataFrame([all_data_dict]) + aldtaframe['datetime'] = pd.to_datetime(aldtaframe['datetime']) + aldtaframe = aldtaframe.set_index('datetime') + self.db.dataframeToMysql(data=aldtaframe, tableName="cost_time_data") + + print("Complete write") + + def run(self): + self.data_storage() + controldata = self.data[(self.data['classify'] == 'gree') & (self.data['code'] == 0)] + applicationdata = self.data[(self.data['classify'] == 'tencent') & (self.data['code'] == 0)] + self.domain_data_to_statistics(data=controldata, data_type="control") + self.domain_data_to_statistics(data=applicationdata, data_type="application") + self.costtime_data_to_statistics(data=self.data) + + +# TP = timing_processing() +# TP.run() +# timer = threading.Timer(20, TP.run) +# timer.start() + +# st = pd.Timestamp("2018-12-01 00:00:00") +# et = pd.Timestamp("2019-01-01 00:00:00") +# u = (et - st).days * 24 +# for i in range(u): +# print("提取第 %d 小时" % i) +# TP = timing_processing() +# start_time = st + dt.timedelta(hours=i) +# end_time = start_time + dt.timedelta(hours=1) +# TP.datetime = end_time +# TP.data = TP.db.getData(tableName='semantic_data_table', startTime=str(start_time), +# endTime=str(end_time)) +# data = TP.data +# controldata = data[(data['classify'] == 'gree') & (data['code'] == 0)] +# applicationdata = data[(data['classify'] == 'tencent') & (data['code'] == 0)] +# TP.domain_data_to_statistics(data=controldata, data_type="control") +# TP.domain_data_to_statistics(data=applicationdata, data_type="application") +# TP.costtime_data_to_statistics(data=data) + +TP = timing_processing() +TP.data_storage() diff --git a/chat_function__analysis.py b/chat_function _analysis.py similarity index 100% rename from chat_function__analysis.py rename to chat_function _analysis.py diff --git a/domain_structure_analysis.py b/domain_structure_analysis.py new file mode 100644 index 0000000..cdc583e --- /dev/null +++ b/domain_structure_analysis.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +# author:Li Mingjie time:2019/2/28 +# Brief:Domain Structure Analysis + +import pandas as pd +import matplotlib.pyplot as plt +import bottom_function.data_read as dr +import json +from flask import Flask +from flask import request +from flask_cors import CORS + + +def data_statistics_plot(datatype, starttime, endtime, graphtype): + csv_data = pd.DataFrame() + csv_data = dr.read_domain_data(datatype=datatype, starttime=starttime, endtime=endtime) + + csv_data = csv_data.drop(columns=['datetime']) + csv_data['col_sum'] = csv_data.apply(lambda x: x.sum(), axis=1) + csv_data.loc['row_sum'] = csv_data.apply(lambda x: x.sum()) + # csv_data = csv_data[~csv_data.isin([0])] + m_data = pd.Series() + m_data = csv_data.loc['row_sum'][:-1] + # m_data.dropna(inplace=True) + m_data.sort_values(ascending=False, inplace=True) + m_data = m_data[m_data.values != 0] + fig = plt.figure(figsize=(10, 6)) + + if graphtype == 'pie': + e = [] + for j in m_data.index: + if j == 'chat' or j == 'airconditioner': + e.append(0.1) + else: + e.append(0) + if len(m_data.index) > 6: + labels = list(m_data.index[:6]) + labels.append('others') + fracs = list(m_data.values[:6]) + other = sum(list(m_data.values[6:])) + fracs.append(other) + else: + labels = list(m_data.index) + fracs = list(m_data.values) + + v_sum = sum(fracs) + v_data = fracs + for i in range(0, len(fracs)): + v_data[i] = fracs[i] / v_sum * 100 + fracs = v_data + explode = e[:(len(fracs))] + if sum(e[len(fracs):]) > 0: + explode[-1] = 0.1 + plt.pie(x=fracs, labels=labels, explode=explode, autopct='%3.2f%%', shadow=True, startangle=90) + elif graphtype == 'bar': + name_list = list(m_data.index) + num_list = list(m_data.values) + m_data.plot(kind=graphtype, use_index=True) + m_data.plot(kind='line', use_index=True) + plt.xticks(rotation=45) + plt.ylabel('Number', fontsize=12, labelpad=5) + for x, y in zip(range(len(num_list)), num_list): + plt.text(x, y, '%d' % y, ha='left', va='center', fontsize=9) + else: + m_data.plot(kind=graphtype, use_index=True) + plt.title(str(starttime) + ' to ' + str(endtime) + ' semantic domain analysis of ' + graphtype + ' graph', + fontsize=12) + plt.tight_layout(5) + path = '/roobo/soft/phpmyadmin/plot_domain.jpg' + plt.savefig(path) + return path + + +app = Flask(__name__) +CORS(app, supports_credentials=True) + + +@app.route('/SPDAS/domain_structure_analysis1', methods=['POST']) +def domain(): + param = ({"data_type": [{"value": "control"}, {"value": "application"}, {"value": "all"}], + "time": "2018-12-01 00:00:00/2018-12-02 00:00:00", + "graph_type": [{"value": "bar"}, {"value": "pie"}]}) + return json.JSONEncoder().encode(param) + + +@app.route('/SPDAS/domain_structure_analysis2', methods=['POST']) +def domain_form(): + # 需要从request对象读取表单内容: + data = request.get_data() + json_re = json.loads(data) + print(json_re) + datatype = json_re['data_type'] + m_time = json_re['time'] + graphtype = json_re['graph_type'] + str_time = str(m_time) + m_time = str_time.split('/') + starttime = m_time[0] + endtime = m_time[1] + image_path = data_statistics_plot(datatype=datatype, starttime=starttime, endtime=endtime, graphtype=graphtype) + path = ({"domain_image": image_path}) + return json.JSONEncoder().encode(path) + + +if __name__ == '__main__': + app.run(debug=True, host='10.7.19.129', port=5000) + +# str_time = str('2018.12.01 00:00:00/2018.12.02 00:00:00') +# m_time = str_time.split('/') +# starttime = m_time[0] +# endtime = m_time[1] +# print(starttime) +# data_statistics_plot(datatype='all', starttime='2018-12-01 00:00:00', endtime='2018-12-02 00:00:00', graphtype='pie') diff --git a/response_analysis.py b/response_analysis.py new file mode 100644 index 0000000..72a85d0 --- /dev/null +++ b/response_analysis.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# author:Li Mingjie time:2019/3/7 +# Brief: + +import json +from flask import Flask +from flask import request +from flask_cors import CORS +import response_time_analysis +import response_error_analysis + +app = Flask(__name__) +CORS(app, supports_credentials=True) + + +@app.route('/SPDAS/response_analysis1', methods=['POST']) +def domain(): + param = ({"data_type": [{"value": "control"}, {"value": "application"}, {"value": "all"}], + "effect_type": [{"value": "cost_time"}, {"value": "response_error"}], + "time": "2018-12-01 00:00:00/2018-12-02 00:00:00"}) + return json.JSONEncoder().encode(param) + + +@app.route('/SPDAS/response_analysis2', methods=['POST']) +def domain_form(): + # 需要从request对象读取表单内容: + data = request.get_data() + json_re = json.loads(data) + datatype = json_re['data_type'] + + effecttype = json_re['effect_type'] + m_time = json_re['time'] + str_time = str(m_time) + m_time = str_time.split('/') + starttime = m_time[0] + endtime = m_time[1] + if effecttype == 'cost_time': + image_path = response_time_analysis.cost_time_plot(datatype=datatype, starttime=starttime, endtime=endtime) + path = ({"response_image": image_path}) + return json.JSONEncoder().encode(path) + else: + image_path = response_error_analysis.error_data_statistics_plot(datatype=datatype, starttime=starttime, + endtime=endtime, + graphtype='bar') + path = ({"response_image": image_path}) + return json.JSONEncoder().encode(path) + + +if __name__ == '__main__': + app.run(debug=True, host='10.7.19.129', port=5000) diff --git a/response_error_analysis.py b/response_error_analysis.py new file mode 100644 index 0000000..5e63d74 --- /dev/null +++ b/response_error_analysis.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# author:Li Mingjie time:2019/2/28 +# Brief:Response Error Analysis + +import pandas as pd +import matplotlib.pyplot as plt +import sys +import bottom_function.data_read as dr +import cgi + + +def error_data_statistics_plot(datatype, starttime, endtime, graphtype): + csv_data = pd.DataFrame() + csv_data = dr.read_data(datatype=datatype, starttime=starttime, endtime=endtime) + csv_data.drop_duplicates(subset='query', keep='first', inplace=True) + error_dict = {} + for i in range(len(csv_data)): + error_code = "error " + str(csv_data.ix[i]['code']) + if error_code in error_dict.keys(): + error_dict[error_code] += 1 + else: + error_dict.update({error_code: 1}) + + fig = plt.figure(figsize=(10, 6)) + if graphtype == 'pie': + e = [] + code_other = 0 + for j in error_dict.keys(): + if j != "error 501": + e.append(0.1) + code_other += error_dict[j] + else: + e.append(0) + + labels = ["error 501", "others"] + fracs = [error_dict["error 501"], code_other] + + v_sum = sum(fracs) + v_data = fracs + for fx in range(0, len(fracs)): + v_data[fx] = fracs[fx] / v_sum * 100 + fracs = v_data + explode = e[:(len(fracs))] + if sum(e[len(fracs):]) > 0: + explode[-1] = 0.1 + plt.pie(x=fracs, labels=labels, explode=explode, autopct='%3.2f%%', shadow=True, startangle=90) + + if graphtype == 'bar': + name_list = list(error_dict.keys()) + num_list = list(error_dict.values()) + plt.bar(range(len(num_list)), num_list) + plt.xticks(range(len(name_list)), name_list) + plt.ylabel('Number', fontsize=12, labelpad=5) + for x, y in zip(range(len(num_list)), num_list): + plt.text(x, y, '%d' % y, ha='center', va='bottom', fontsize=9) + + plt.title(str(starttime) + ' to ' + str(endtime) + ' semantic domain analysis of ' + graphtype + ' graph', + fontsize=12) + plt.tight_layout(5) + path = '/roobo/soft/phpmyadmin/response_error.jpg' + plt.savefig(path) + return path + diff --git a/response_time_analysis.py b/response_time_analysis.py new file mode 100644 index 0000000..a6a3bea --- /dev/null +++ b/response_time_analysis.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# author:Li Mingjie time:2019/2/28 +# Brief:Response time analysis + +import matplotlib.pyplot as plt +import bottom_function.data_read as dr + + +def cost_time_plot(datatype, starttime, endtime): + cost_time_dict = dr.read_cost_time_data(datatype=datatype, starttime=starttime, endtime=endtime) + y_max = 0 + xl_list = list(cost_time_dict.keys()) + fig = plt.figure(figsize=(10, 6)) + + for x in range(6): + lab_list = [] + y_list = [] + x_list = [] + t_list = list(cost_time_dict[xl_list[x]])[0:3] + for m in t_list: + lab_list.append(m[0]) + y_list.append(m[1]) + x += 0.2 + x_list.append(x) + y_max = max(y_list) if max(y_list) > y_max else y_max + + plt.bar(x_list, y_list, width=0.2, color=['r', 'g', 'b']) + for i, j, lab in zip(x_list, y_list, lab_list): + plt.text(i, j, lab, ha='center', va='bottom', fontsize=9, rotation=70) + # plt.rcParams['font.family'] = ['sans-serif'] + # plt.rcParams['font.sans-serif'] = ['SimHei'] + # plt.xticks(np.arange(0.5,6,1),xl_list,position=(0.06,-0.07)) + plt.ylim(0, y_max * 1.2) + plt.xticks(np.arange(0.5, 6, 1), xl_list) + if datatype == 'application': + plt.title(str(starttime) + ' to ' + str(endtime) + ' cost time analysis of application resources', fontsize=12) + elif datatype == 'control': + plt.title(str(starttime) + ' to ' + str(endtime) + ' cost time analysis of control resources', fontsize=12) + else: + plt.title(str(starttime) + ' to ' + str(endtime) + ' cost time analysis of all resources', fontsize=12) + plt.tight_layout(5) + path = '/roobo/soft/phpmyadmin/response_time.jpg' + plt.savefig(path) + return path + diff --git a/second_test.py b/second_test.py new file mode 100644 index 0000000..996f993 --- /dev/null +++ b/second_test.py @@ -0,0 +1,159 @@ +# -*- coding: utf-8 -*- +# author:Li Mingjie time:2019/2/28 +# Brief:second test + +import time +import requests +import matplotlib.pyplot as plt +import pandas as pd +import bottom_function.m_SQL as qb +import bottom_function.data_read as dr +import json +from flask import Flask +from flask import request +from flask_cors import CORS + + +def second_test(text, classify): + try: + + # 接口的url + url = "http://api.gree.com:8088/unisound/v1/query" + headers = {"Content-Type": "application/x-www-form-urlencoded"} + # 接口的参数 + data = { + "uid": "unisound", + "token": "9ff9874dd2f8b6d9e0343c22c23f4248543eec156303703b42a38488e581be42", + "macWifi": "test-mac", + "macVoice": "", + "query": text, + "classify": classify + } + r = requests.request("post", url, json=data, headers=headers) + # 解析返回结果 + second_test_log = r.text + # 将平台的返回数据转成json格式 + second_test_log = json.loads(second_test_log) + if classify == 'gree': + status = (second_test_log.get('status')) + else: + status = second_test_log['header']['semantic'] + if status is None: + status = second_test_log + # 0.2秒延迟 + time.sleep(0.5) + # 取出二次测试后的返回日志对应的状态码 + status_codes = status["code"] + + return status_codes + except Exception as result: + print("进行二次测试时出错:{}".format(result)) + + +def second_test_plot(datatype, starttime, endtime, graphtype): + csv_data = pd.DataFrame() + csv_data = dr.read_data(datatype=datatype, starttime=starttime, endtime=endtime) + if datatype == 'error_control': + table_name = "control_error_data" + elif datatype == 'error_application': + table_name = "application_error_data" + db = qb.Schema(host="localhost", user="560193", password="jay560193", mysqlName="semantic_data_schema", port="3306") + classsify = csv_data.ix[0]['classify'] + error_dict = {} + for i in range(len(csv_data)): + # query = str(csv_data.ix[i]['query'].encode('utf-8').decode('utf-8-sig')) + query = csv_data.ix[i]['query'] + if query.startswith(u'\ufeff'): + query = query.encode('utf8')[3:].decode('utf8') + if query is None: + continue + status_code = second_test(text=query, classify=classsify) + if status_code == 0: + db.delData(tableName=table_name, keyWord=query) + print('delete semantic data "%s" for second test' % query) + continue + error_code = "error " + str(csv_data.ix[i]['code']) + if error_code in error_dict.keys(): + error_dict[error_code] += 1 + else: + error_dict.update({error_code: 1}) + + fig = plt.figure(figsize=(10, 6)) + if graphtype == 'pie': + e = [] + code_other = 0 + for j in error_dict.keys(): + if j != "error 501": + e.append(0.1) + code_other += error_dict[j] + else: + e.append(0) + + labels = ["error 501", "others"] + fracs = [error_dict["error 501"], code_other] + + v_sum = sum(fracs) + v_data = fracs + for fx in range(0, len(fracs)): + v_data[fx] = fracs[fx] / v_sum * 100 + if v_data[fx] == 100: + v_data = v_data[:1] + labels = labels[:1] + break + fracs = v_data + explode = e[:(len(fracs))] + if sum(e[len(fracs):]) > 0: + explode[-1] = 0.1 + plt.pie(x=fracs, labels=labels, explode=explode, autopct='%3.2f%%', shadow=True, startangle=90) + + if graphtype == 'bar': + name_list = list(error_dict.keys()) + num_list = list(error_dict.values()) + plt.bar(range(len(num_list)), num_list) + plt.xticks(range(len(name_list)), name_list) + plt.ylabel('Number', fontsize=12, labelpad=5) + for x, y in zip(range(len(num_list)), num_list): + plt.text(x, y, '%d' % y, ha='center', va='bottom', fontsize=9) + + plt.title( + str(starttime) + ' to ' + str(endtime) + ' second test of error response analysis with ' + graphtype + ' graph', + fontsize=12) + plt.tight_layout(5) + path = '/roobo/soft/phpmyadmin/second_test.jpg' + plt.savefig(path) + return path + + +app = Flask(__name__) +CORS(app, supports_credentials=True) + + +@app.route('/SPDAS/second_test1', methods=['POST']) +def domain(): + param = ({"data_type": [{"value": "error_control"}, {"value": "error_application"}], + "time": "2018-12-01 00:00:00/2018-12-02 00:00:00", + "graph_type": [{"value": "bar"}, {"value": "pie"}]}) + return json.JSONEncoder().encode(param) + + +@app.route('/SPDAS/second_test2', methods=['POST']) +def domain_form(): + # 需要从request对象读取表单内容: + data = request.get_data() + json_re = json.loads(data) + datatype = json_re['data_type'] + + m_time = json_re['time'] + str_time = str(m_time) + m_time = str_time.split('/') + starttime = m_time[0] + endtime = m_time[1] + graphtype = json_re['graph_type'] + + image_path = second_test_plot(datatype=datatype, starttime=starttime, endtime=endtime, graphtype=graphtype) + path = ({"test_image": image_path}) + return json.JSONEncoder().encode(path) + + +if __name__ == '__main__': + app.run(debug=True, host='10.7.19.129', port=5000) diff --git a/time_series_analysis.py b/time_series_analysis.py new file mode 100644 index 0000000..91ef7c4 --- /dev/null +++ b/time_series_analysis.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- +# author:Li Mingjie time:2019/2/28 +# Brief:Time Series Data Analysis +import pandas as pd +import matplotlib.pyplot as plt +import datetime as dt +import bottom_function.data_read as dr +import json +from flask import Flask +from flask import request +from flask_cors import CORS + + +def datetime_data_plot(timetype, starttime, endtime, graphtype): + gree_data = dr.read_domain_data(datatype="control", starttime=starttime, endtime=endtime) + tent_data = dr.read_domain_data(datatype="application", starttime=starttime, endtime=endtime) + + # gree_data['datetime'] = gree_data['datetime'].apply(lambda x: dt.datetime.strftime(x, "%Y-%m-%d %H ")) + # tent_data['datetime'] = tent_data['datetime'].apply(lambda x: dt.datetime.strftime(x, "%Y-%m-%d %H ")) + + gree_data = gree_data.set_index('datetime', drop=True) + tent_data = tent_data.set_index('datetime', drop=True) + mg_data = gree_data.apply(sum, axis=1) + mt_data = tent_data.apply(sum, axis=1) + + g_data = pd.DataFrame() + t_data = pd.DataFrame() + all_data = pd.DataFrame() + if timetype == "hour": + g_data = mg_data.resample('H').sum() + t_data = mt_data.resample('H').sum() + all_data = pd.concat([g_data, t_data], axis=1) + all_data.columns = ['control', 'application'] + index_data = all_data.index.tolist() + for i in range(len(index_data)): + index_data[i] = dt.datetime.strftime(index_data[i], "%Y-%m-%d %H ") + all_data.index = index_data + if timetype == "day": + g_data = mg_data.resample('D').sum() + t_data = mt_data.resample('D').sum() + all_data = pd.concat([g_data, t_data], axis=1) + all_data.columns = ['control', 'application'] + index_data = all_data.index.tolist() + for i in range(len(index_data)): + index_data[i] = dt.datetime.strftime(index_data[i], "%Y-%m-%d") + all_data.index = index_data + if timetype == "month": + g_data = mg_data.resample('M').sum() + t_data = mt_data.resample('M').sum() + all_data = pd.concat([g_data, t_data], axis=1) + all_data.columns = ['control', 'application'] + index_data = all_data.index.tolist() + for i in range(len(index_data)): + index_data[i] = dt.datetime.strftime(index_data[i], "%Y-%m") + all_data.index = index_data + if timetype == "year": + g_data = mg_data.resample('Y').sum() + t_data = mt_data.resample('Y').sum() + all_data = pd.concat([g_data, t_data], axis=1) + all_data.columns = ['control', 'application'] + index_data = all_data.index.tolist() + for i in range(len(index_data)): + index_data[i] = dt.datetime.strftime(index_data[i], "%Y") + all_data.index = index_data + + fig = plt.figure(figsize=(16, 6)) + all_data.plot(kind=graphtype, stacked=True, use_index=True) + plt.xticks(rotation=45) + + plt.title(str(starttime) + ' to ' + str( + endtime) + ' ' + timetype + ' datetime domain analysis of ' + graphtype + ' graph', + fontsize=10) + plt.tight_layout(5) + path = '/roobo/soft/phpmyadmin/plot_time.jpg' + plt.savefig(path) + return path + + +app = Flask(__name__) +CORS(app, supports_credentials=True) + + +@app.route('/SPDAS/time_series_analysis1', methods=['POST']) +def domain(): + param = ({"time_type": [{"value": "hour", "id": 1}, {"value": "day", "id": 2}, + {"value": "month", "id": 3}, {"value": "year", "id": 4}], + "time": "2018-12-01 00:00:00/2018-12-02 00:00:00", + "graph_type": [{"value": "bar"}, {"value": "pie"}]}) + return json.JSONEncoder().encode(param) + + +@app.route('/SPDAS/time_series_analysis2', methods=['POST']) +def domain_form(): + # 需要从request对象读取表单内容: + data = request.get_data() + json_re = json.loads(data) + print(json_re) + timetype = json_re['time_type'] + m_time = json_re['time'] + graphtype = json_re['graph_type'] + str_time = str(m_time) + m_time = str_time.split('/') + starttime = m_time[0] + endtime = m_time[1] + image_path = datetime_data_plot(timetype=timetype, starttime=starttime, endtime=endtime, graphtype=graphtype) + path = ({"time_image": image_path}) + return json.JSONEncoder().encode(path) + + +if __name__ == '__main__': + app.run(debug=True, host='10.7.19.129', port=5000) diff --git a/user_portrait_analysis.py b/user_portrait_analysis.py new file mode 100644 index 0000000..73d060a --- /dev/null +++ b/user_portrait_analysis.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# author:Li Mingjie time:2019/2/28 +# Brief:User Portrait Analysis + +from wordcloud import WordCloud +import cv2 +import matplotlib.pyplot as plt +import bottom_function.data_read as dr +from bottom_function import normalization as norm +import json +from flask import Flask +from flask import request +from flask_cors import CORS + + +def portrait_plot(datatype, starttime, endtime): + n_data = dr.read_data(datatype=datatype, starttime=starttime, endtime=endtime) + if n_data.empty: + return 0 + query_data = '' + for q in n_data['query']: + str_q = str(q) + query_data = query_data + "," + str_q + + cut_text = norm.remove_special_characters(query_data) + + color_mask = cv2.imread('./bottom_function/data/gree_logo.jpg') + + cloud = WordCloud( + # 设置字体,不指定就会出现乱码 + font_path=" C:\\Windows\\Fonts\\STXINGKA.TTF", + # font_path=path.join(d,'simsun.ttc'), + font_step=1, + width=720, + height=720, + # 设置背景色 + background_color='white', + # 词云形状 + mask=color_mask, + # 允许最大词汇 + max_words=10000, + # 最大号字体 + max_font_size=50, + min_font_size=5 + ) + + wCloud = cloud.generate(cut_text) + # wCloud.to_file('../data/word_cloud/cloud.jpg') + + plt.imshow(wCloud, interpolation='bilinear') + plt.axis('off') + til = datatype + ' ' + starttime + endtime + 'user portrait of word cloud' + plt.title(til) + path = '/roobo/soft/phpmyadmin/plot_user.jpg' + plt.savefig(path) + return path + + +app = Flask(__name__) +CORS(app, supports_credentials=True) + + +@app.route('/SPDAS/user_portrait_analysis1', methods=['POST']) +def domain(): + param = ({"data_type": [{"value": "control"}, {"value": "application"}, {"value": "all"}], + "time": "2019.01.01 00:00:00/2019.01.02 00:00:00"}) + return json.JSONEncoder().encode(param) + + +@app.route('/SPDAS/user_portrait_analysis2', methods=['POST']) +def domain_form(): + # 需要从request对象读取表单内容: + data = request.get_data() + json_re = json.loads(data) + + datatype = json_re['data_type'] + m_time = json_re['time'] + str_time = str(m_time) + m_time = str_time.split('/') + starttime = m_time[0] + endtime = m_time[1] + image_path = portrait_plot(datatype=datatype, starttime=starttime, endtime=endtime) + path = {"user_image": image_path} + return json.JSONEncoder().encode(path) + + +if __name__ == '__main__': + app.run(debug=True, host='10.7.19.129', port=5000) -- GitLab