From 8098ad25a4b9e34a7fb27e5fefd3bb32240dc9c7 Mon Sep 17 00:00:00 2001 From: starlee Date: Sun, 10 Mar 2019 17:18:38 +0800 Subject: [PATCH] handel senti --- .vscode/settings.json | 3 + 4_rq3.tex | 266 +++++++++--------- .../custom-config/EmoticonLookupTable.txt | 123 ++++++++ .../custom-config/ReviewCommentAddition.txt | 24 ++ experiment_code/rq3.py | 149 +++++++++- 5 files changed, 431 insertions(+), 134 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 experiment_code/custom-config/EmoticonLookupTable.txt create mode 100644 experiment_code/custom-config/ReviewCommentAddition.txt diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..41fac95 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.linting.pylintEnabled": true +} \ No newline at end of file diff --git a/4_rq3.tex b/4_rq3.tex index 3dc7d13..5b3570c 100644 --- a/4_rq3.tex +++ b/4_rq3.tex @@ -5,7 +5,7 @@ \label{rq3} In order to investigate what kind of crowd duplications are more likely to be accepted, % we conduct manual inspection and regression analysis. -% \subsubsection{Manual inspection.} +\subsubsection{Manual inspection.} we manually explore the decision elaborations made by reviewers when they make a choice between duplications. This work is conducted on 100 pairs~\footnote{\url{https://github.com/whystar/dup_pr_cmt/blob/master/README.md}} @@ -232,177 +232,177 @@ closing in favour of \#10582 % ######################################### % ############ 2019-01-12注释掉 ############ -% % work pattern -% \subsubsection{Regression analysis.} -% Furthermore, -% we would like to explore whether there are some other metrics -% that are not explicitly mentioned by the reviewers -% but do have an effect the duplication competition. -% Based on our research experience and the review of prior related studies, -% we collect the following metrics from three different perspectives. +% work pattern +\subsubsection{Regression analysis.} +Furthermore, +we would like to explore whether there are some other metrics +that are not explicitly mentioned by the reviewers +but do have an effect the duplication competition. +Based on our research experience and the review of prior related studies, +we collect the following metrics from three different perspectives. -% % 贡献者和审阅者对文件的掌控力,修改次数,历史touch数 +% 贡献者和审阅者对文件的掌控力,修改次数,历史touch数 -% % 回归分析 -% \vspace{0.5em} -% \noindent\textbf{Contributor level metrics.} +% 回归分析 +\vspace{0.5em} +\noindent\textbf{Contributor level metrics.} -% Contributor level metrics are used to represent the role and contribution experience -% of developers, -% which includes the following items. -% % 如何获得这些特征 等等 +Contributor level metrics are used to represent the role and contribution experience +of developers, +which includes the following items. +% 如何获得这些特征 等等 -% \textit{Core\_team.} -% % 表征角色 -% This is a binary metric, -% indicating whether a contributor is the member of the core management team of the project. -% Specifically in the paper, -% the developers who have the privilege to close others' pull-request -% form the core management team. +\textit{Core\_team.} +% 表征角色 +This is a binary metric, +indicating whether a contributor is the member of the core management team of the project. +Specifically in the paper, +the developers who have the privilege to close others' pull-request +form the core management team. -% \textit{Submission\_exp.} -% % 表征经验 -% This metric measures a contributor's prior submission experience, -% which is computed by counting the number of prior pull-requests and issues -% submitted by the contributor to a specific project -% before the contribution. +\textit{Submission\_exp.} +% 表征经验 +This metric measures a contributor's prior submission experience, +which is computed by counting the number of prior pull-requests and issues +submitted by the contributor to a specific project +before the contribution. -% \textit{Discussion\_exp.} -% % 表征经验 -% Similar to $Submission\_exp$, -% this metric measures a contributor's prior discussion experience -% and it indicates the number of prior comments that the contributor has made -% on the pull-requests and issues of a specific project -% before this contribution. +\textit{Discussion\_exp.} +% 表征经验 +Similar to $Submission\_exp$, +this metric measures a contributor's prior discussion experience +and it indicates the number of prior comments that the contributor has made +on the pull-requests and issues of a specific project +before this contribution. -% \vspace{0.5em} -% \noindent\textbf{Pull-request level metrics.} +\vspace{0.5em} +\noindent\textbf{Pull-request level metrics.} -% Pull-request level metrics represent the main profile and change information -% of a pull-request, which includes the following items. +Pull-request level metrics represent the main profile and change information +of a pull-request, which includes the following items. -% \textit{First\_pr.} -% % 表征新手 -% This is a binary metric which indicates -% whether this is the first time for a contributor to submit a pull-request -% to a specific project. +\textit{First\_pr.} +% 表征新手 +This is a binary metric which indicates +whether this is the first time for a contributor to submit a pull-request +to a specific project. -% \textit{Early\_arrival.} -% This binary metric is used to indicate whether -% a pull-request is submitted early than the other one for a pair of duplications. -% Therefore, -% the metric $Submitted\_early$ of the early submitted pull-request is set to be $True$, -% while for the pull-request with late submission time the metric value is $False$. +\textit{Early\_arrival.} +This binary metric is used to indicate whether +a pull-request is submitted early than the other one for a pair of duplications. +Therefore, +the metric $Submitted\_early$ of the early submitted pull-request is set to be $True$, +while for the pull-request with late submission time the metric value is $False$. -% \textit{Churn.} -% This metric represents the total number of lines of code -% that a pull-requests has changed (\ie added, removed and modified). +\textit{Churn.} +This metric represents the total number of lines of code +that a pull-requests has changed (\ie added, removed and modified). -% \textit{\#Files.} -% This metric indicates the total number of the files -% that a pull-requests has changed (\ie created, deleted and modified). +\textit{\#Files.} +This metric indicates the total number of the files +that a pull-requests has changed (\ie created, deleted and modified). -% % \textit{Test\_touched.} -% % This is a binary metric which represents -% % whether a pull-request has changed the test files. +% \textit{Test\_touched.} +% This is a binary metric which represents +% whether a pull-request has changed the test files. -% \vspace{0.5em} -% \noindent\textbf{Review level metrics.} +\vspace{0.5em} +\noindent\textbf{Review level metrics.} -% Review level metrics mainly inflect the information -% contained in the code review process of a pull-request, -% which includes the following items. +Review level metrics mainly inflect the information +contained in the code review process of a pull-request, +which includes the following items. -% \textit{Review\_duration.} -% This metric computes the review duration of a pull-request -% from the time it is submitted -% to the duplication exposure time when its duplicate relation with another one is detected. +\textit{Review\_duration.} +This metric computes the review duration of a pull-request +from the time it is submitted +to the duplication exposure time when its duplicate relation with another one is detected. -% \textit{\#Comments.} -% This metric indicates the total number of review comments -% a pull-request has received until the duplication exposure time. +\textit{\#Comments.} +This metric indicates the total number of review comments +a pull-request has received until the duplication exposure time. -% \textit{\#Comments\_inline.} -% This metric indicates the total number of inline comments -% a pull-request has received until the duplication exposure time. -% Actually, -% reviewers can leave two kinds of review comments on a pull-request, -% \ie \textit{inline comments} which mainly focus on solution details -% and \textit{issue comments} which usually talk about the general issues of the whole pull-request~\cite{Zhi2017What}. +\textit{\#Comments\_inline.} +This metric indicates the total number of inline comments +a pull-request has received until the duplication exposure time. +Actually, +reviewers can leave two kinds of review comments on a pull-request, +\ie \textit{inline comments} which mainly focus on solution details +and \textit{issue comments} which usually talk about the general issues of the whole pull-request~\cite{Zhi2017What}. -% \begin{table*}[h] -% \centering -% \caption{Overview of metrics} -% \begin{tabular}{r c c c c c c c} +\begin{table*}[h] + \centering + \caption{Overview of metrics} + \begin{tabular}{r c c c c c c c} -% \bottomrule -% \textbf{Statistic} &\textbf{Mean} &\textbf{St.} & \textbf{Min} &\textbf{Median} &\textbf{Max} \\ + \bottomrule + \textbf{Statistic} &\textbf{Mean} &\textbf{St.} & \textbf{Min} &\textbf{Median} &\textbf{Max} \\ -% \midrule -% % \textbf{Contributor level metrics}\hspace{1em} \\ -% Core team &0.38 & 0.49 &0 &0 &1 \\ -% Submission\_exp &107.95 & 233.42 &0 &12 &2284 \\ -% Discussion\_exp &1092.07 & 2939.49 &0 &45 &40978 \\ -% \midrule -% % \textbf{Pull-request level metrics}\hspace{1em} \\ -% First\_pr &0.25 & 0.44 &0 &0 &1 \\ -% Early\_arrival &0.50 & 0.50 &0 &0.50 &1 \\ -% Churn &313.1 & 1998.92 &0 &14 &45955 \\ -% \#Files &9.79 & 104.61 &0 &1 &3874 \\ + \midrule + % \textbf{Contributor level metrics}\hspace{1em} \\ + Core team &0.38 & 0.49 &0 &0 &1 \\ + Submission\_exp &107.95 & 233.42 &0 &12 &2284 \\ + Discussion\_exp &1092.07 & 2939.49 &0 &45 &40978 \\ + \midrule + % \textbf{Pull-request level metrics}\hspace{1em} \\ + First\_pr &0.25 & 0.44 &0 &0 &1 \\ + Early\_arrival &0.50 & 0.50 &0 &0.50 &1 \\ + Churn &313.1 & 1998.92 &0 &14 &45955 \\ + \#Files &9.79 & 104.61 &0 &1 &3874 \\ -% \midrule -% % \textbf{Review level metrics}\hspace{1em} \\ -% Review\_duration &3610558 & &8 &212672 &124941046 \\ -% \#Comments &6.59 & 14.11 &0 &2 &231 \\ -% \#Comments\_inline &4.427 & 8.39 &0 &2 &165 \\ + \midrule + % \textbf{Review level metrics}\hspace{1em} \\ + Review\_duration &3610558 & &8 &212672 &124941046 \\ + \#Comments &6.59 & 14.11 &0 &2 &231 \\ + \#Comments\_inline &4.427 & 8.39 &0 &2 &165 \\ -% \toprule -% \end{tabular} -% \label{tab:sub_metrics} -% \end{table*} + \toprule + \end{tabular} + \label{tab:sub_metrics} +\end{table*} -% \begin{table*}[h] -% \centering -% \caption{Statistical models for \hl{happence} of duplicate pull-requets} -% \begin{tabular}{r c c } -% \toprule +\begin{table*}[h] + \centering + \caption{Statistical models for \hl{happence} of duplicate pull-requets} + \begin{tabular}{r c c } + \toprule -% & Estimate & Significance \\ -% \midrule -% % \textbf{Contributor level metrics}\hspace{1em} \\ -% Core team & & \\ -% First\_pr & & \\ -% \#Prev\_pr & & \\ + & Estimate & Significance \\ + \midrule + % \textbf{Contributor level metrics}\hspace{1em} \\ + Core team & & \\ + First\_pr & & \\ + \#Prev\_pr & & \\ -% \midrule -% % \textbf{Pull-request level metrics}\hspace{1em} \\ -% Churn & & \\ -% \#Files & & \\ -% Test\_touched & & \\ -% Sub\_early & & \\ + \midrule + % \textbf{Pull-request level metrics}\hspace{1em} \\ + Churn & & \\ + \#Files & & \\ + Test\_touched & & \\ + Sub\_early & & \\ -% \midrule -% % \textbf{Review level metrics}\hspace{1em} \\ -% Review\_duration & & \\ -% \#Comments & & \\ -% \#Comments\_inline & & \\ -% \bottomrule -% \multicolumn{3}{l}{\emph{*** p \textless 0.001, ** p \textless 0.01, *p \textless 0.05}} -% \end{tabular} -% \label{tab:sta_models} -% \end{table*} + \midrule + % \textbf{Review level metrics}\hspace{1em} \\ + Review\_duration & & \\ + \#Comments & & \\ + \#Comments\_inline & & \\ + \bottomrule + \multicolumn{3}{l}{\emph{*** p \textless 0.001, ** p \textless 0.01, *p \textless 0.05}} + \end{tabular} + \label{tab:sta_models} +\end{table*} % ############ 2019-01-12注释掉 ############ diff --git a/experiment_code/custom-config/EmoticonLookupTable.txt b/experiment_code/custom-config/EmoticonLookupTable.txt new file mode 100644 index 0000000..e64589b --- /dev/null +++ b/experiment_code/custom-config/EmoticonLookupTable.txt @@ -0,0 +1,123 @@ +%-( -1 +%-) 1 +(-: 1 +(: 1 +(^ ^) 1 +(^-^) 1 +(^.^) 1 +(^_^) 1 +(o: 1 +(o; 0 +)-: -1 +): -1 +)o: -1 +*) 0 +*\o/* 1 +--^--@ 1 +0:) 1 +38* -1 +8) 1 +8-) 0 +8-0 -1 +8/ -1 +8\ -1 +8c -1 +:# -1 +:'( -1 +:'-( -1 +:( -1 +:) 1 +:*( -1 +:,( -1 +:-& -1 +:-( -1 +:-(o) -1 +:-) 1 +:-* 1 +:-* 1 +:-/ -1 +:-/ 0 +:-D 1 +:-O 0 +:-P 1 +:-S -1 +:-\ -1 +:-\ 0 +:-| -1 +:-} 1 +:/ -1 +:0->-<|: 0 +:3 1 +:9 1 +:D 1 +:E -1 +:F -1 +:O -1 +:P 1 +:P 1 +:S -1 +:X 1 +:[ -1 +:[ -1 +:\ -1 +:] 1 +:_( -1 +:b) 1 +:l 0 +:o( -1 +:o) 1 +:p 1 +:s -1 +:| -1 +:| 0 +:� 1 +:�( -1 +;) 0 +;^) 1 +;o) 0 +/ -1 +>:( -1 +>:) 1 +>:D 1 +>:L -1 +>:O -1 +>=D 1 +>[ -1 +>\ -1 +>o> -1 +@}->-- 1 +B( -1 +Bc -1 +D: -1 +X( -1 +X( -1 +X-( -1 +XD 1 +XD 1 +XO -1 +XP -1 +XP 1 +^_^ 1 +^o) -1 +x3? 1 +xD 1 +xP -1 +|8C -1 +|8c -1 +|D 1 +}:) 1 + +#for review comment @ 2018-04-21 +:bell: 5 +#good:3, great:3, awesome:4 +:+1: 5 ++1 3 +-1 -3 \ No newline at end of file diff --git a/experiment_code/custom-config/ReviewCommentAddition.txt b/experiment_code/custom-config/ReviewCommentAddition.txt new file mode 100644 index 0000000..2c1091f --- /dev/null +++ b/experiment_code/custom-config/ReviewCommentAddition.txt @@ -0,0 +1,24 @@ +##This file contains domain-specific changes to the main sentiment dictionary and evaluative terms. +##Changes to the main sentiment dictionary are for words that have a different sentiment for the domain +## or are non-sentiment evaluative words in the domain that are not associated with any particular feature. +##Domain-specific changes to the main sentiment dictionary take the form +##Word sentiment strength (from -5,-4,-3,-2,1,2,3,4,5) +## e.g., heavy -3 +##Or phrase sentiment strength (from -5,-4,-3,-2,1,2,3,4,5) for idiomatic phrases +##Evaluative terms take the form: +##Object evaluative term sentiment strength (from -5,-4,-3,-2,1,2,3,4,5) +## e.g., screen small -3 (note to mike: very/little) +##Lines starting with two hashes are ignored + +##Sentiment dictionary additions and changes +##squash 3 + +##testing 4 + +##Idiomatic phrases +##doing it 3 + +##Evaluative terms +lgtm 3 + + diff --git a/experiment_code/rq3.py b/experiment_code/rq3.py index b7f9ef3..e511ec8 100644 --- a/experiment_code/rq3.py +++ b/experiment_code/rq3.py @@ -306,6 +306,147 @@ def veriry_metrics(): print "https://github.com/%s/%s/pull/%d"%(u_n, r_n, pr_num) +# 2019-02-27以后的代码 +# 计算每一个pr所有评论的情感极性 +# 只看issue级别的;如果有@人的话,说明是在对话,可以先着重看@作者的;应该说越往后的评论越重要 + + + + +def get_deci_time(repo_id, dup_pr, mst_pr): + '''获取一对重复pr的决策时间 ''' + # 哪一个被先关闭了或者被先合并了 + + # 现获取各自的时间点 + repo_id = gt_gh[repo_id] + dup_ct, dup_dt, dup_D = _rw_dur(repo_id, dup_pr) + mst_ct, mst_dt, mst_D = _rw_dur(repo_id, mst_pr) + + # 判断是否有overlap #其实只看dup_ct与mst_dt的关系就可以了,因为dup是晚于mst提交的 + if dup_ct > mst_dt or mst_ct > dup_dt: + return None + + # 判断决策时间 + if dup_dt < mst_dt: + return dup_dt + else: + return mst_dt + +import re +import subprocess +import shlex +def _txt_clean(text): + '''清洗文本''' + # 把评论中的一些干扰项去除掉 + # 代码去掉 + text = re.sub('(```[\s\S]*?```|``[\s\S]*?``|`[\s\S]*?`)',"@@cmmcode@@",text) + # 他人的引用去掉 + text = re.sub('(>.*\n|on.*\nwrote:)', "@@cmmref@@", text.lower())#去掉引用块 + # 超链接去掉 + text = re.sub("((http|ftp|https)://)(([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,6})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,4})*(/[a-zA-Z0-9\&%_\./-~-]*)?","@@cmmhttp@@",text)#去掉http + + # 把换行符去掉 + text = re.sub(r"\n"," ", text) + # 把多个空格替换成一个空格 + text = re.sub(r"\s+"," ", text) + + return text + + +def _txt_sent(txt): + '''一段文本的情感''' + # print "\tbc: ", txt.strip() + txt = _txt_clean(txt) + # print "\tac: ", txt + + ss_data_path = "/Users/lizhixing/Documents/project" + cmd_str = "java -jar SentiStrength.jar stdin sentidata SentiStrength_Data/ explain additionalFile ReviewCommentAddition.txt" + p = subprocess.Popen(shlex.split(cmd_str), cwd=ss_data_path, + stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) + + stdout_text, stderr_text = p.communicate(txt) + sentis = [item.strip() for item in stdout_text.split("\t")] + # extract the positive value, negative value, and explanation. + # print "\t", sentis + return sentis[:2] + + +def _cmt_senti(repo_id, pr_num, decide_time): + '''在decide_time前提交的几个comment的情感分析''' + cursor.execute("select id,author from `pull-request` where prj_id=%s and pr_num=%s", + (repo_id, pr_num)) + pr_id, pr_author = cursor.fetchone() + print pr_id, repo_id, pr_num, pr_author + + # 取出pr的所有comment + cursor.execute("select author_name, comment_body, comment_type, created_at,id from comments where pr_id=%s",(pr_id,)) + cmts = cursor.fetchall() + print"\ttotal:",len(cmts) + + # 挑选出非作者本人的评论(非决策comment到底还留不留呢?有些是夸奖两句直接接受了) + cmts = [item for item in cmts if item[0] != pr_author] + print"\tno pr_author:",len(cmts) + # print"\n" + + # 按时间排序,从决策时间往前看n个 + decide_time = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.localtime(decide_time)) + cmts = [item for item in sorted(cmts, key=lambda x:x[3], reverse=True) if item[3]<=decide_time] + if len(cmts) == 0: + return + senti_num = [0,0] #记录各种极性情感的评论的个数 + for cmt in cmts: + # print "\t", cmt[0], cmt[3], cmt[2] + cmt_senti = _txt_sent(cmt[1]) + if int(cmt_senti[0]) > 1: + senti_num[0] += 1 + if int(cmt_senti[1]) < -1: + senti_num[1] += 1 + # print "\n" + + print "\t SENTI_P: ", senti_num, [1.0*item/len(cmts) for item in senti_num] + +def load_cust_cfg(): + # 把项目中的定制化配置文件更新到 sentistrength相应目录下 + ss_dir = ss_data_path = "/Users/lizhixing/Documents/project/SentiStrength_Data" + + with open("%s/ReviewCommentAddition.txt"%(ss_dir,),"w+") as t_fp: + t_fp.truncate() + with open("custom-config/ReviewCommentAddition.txt","r+") as s_fp: + for line in s_fp: + t_fp.write(line) + with open("%s/EmoticonLookupTable.txt"%(ss_dir,),"w+") as t_fp: + t_fp.truncate() + with open("custom-config/EmoticonLookupTable.txt","r+") as s_fp: + for line in s_fp: + t_fp.write(line) + # 目前配置的有 + # lgtm: 3. + +def cmt_sentiment(): + # 可以这样:每一个评论有这样的极性得分[p,n],然后看他所有的评论中,p>1的比例有多少,n<-1的比例有多少 + # 也就说有两个指标,包含积极情感的审阅意见占比; 包含消极情感的审阅意见占比 + load_cust_cfg() + cursor.execute("select prj_id,mst_pr,dup_pr,idn_cmt from duplicate") + import random + dups = [list(item) for item in cursor.fetchall()] #cvt 2 list to shuffle + random.shuffle(dups) + for dup in dups[:5]: + # 取出pr的相关信息 + repo_id, dup_pr, mst_pr, idn_cmt = dup + print dup + + # 判断两个pr的决策时间 + decide_time = get_deci_time(repo_id,mst_pr,dup_pr) + if decide_time is None: + print "no overlapped" + print "*"*20 + continue + + # 挨个判断 + _cmt_senti(repo_id, dup_pr, decide_time) + _cmt_senti(repo_id, mst_pr, decide_time) + print "*"*20 + if __name__ == '__main__': # init() # _author_core() @@ -317,4 +458,10 @@ if __name__ == '__main__': # metric_dist() - # veriry_metrics() \ No newline at end of file + # veriry_metrics() + + # 测试情感分析效果 + # load_cust_cfg() + # cmt_str = "lgtm, we can merge this pr. +1" + # _txt_sent(cmt_str) + cmt_sentiment()