吳大進
(安徽寶申會計師事務(wù)所,安徽 合肥 230001)
圍標(biāo)和串標(biāo)是招投標(biāo)過程中比較典型的一類違法違規(guī)行為,嚴(yán)重擾亂了正常市場秩序,直接傷害了發(fā)標(biāo)人和其他投標(biāo)人的合法權(quán)益,也給投標(biāo)項目質(zhì)量和安全帶來嚴(yán)重的風(fēng)險隱患,查處圍標(biāo)和串標(biāo)行為一直是審計的重點內(nèi)容。傳統(tǒng)的審計思路是核對MAC 地址是否一致、IP 地址是否一致、工程造價軟件鎖編碼是否一致以及投標(biāo)保證金繳付賬號是否一致。根據(jù)《中華人民共和國招標(biāo)投標(biāo)法實施條例》第40 條規(guī)定發(fā)現(xiàn)上述情形之一的,視為投標(biāo)人相互串通投標(biāo)。
目前,圍標(biāo)和串標(biāo)行為也隨之發(fā)生了新變化,為逃避法律法規(guī)監(jiān)管,圍標(biāo)和串標(biāo)行為越來越隱蔽,越來越職業(yè)化。圍標(biāo)人一般會聯(lián)系多家投標(biāo)人對某個重大項目進行重點投標(biāo),由圍標(biāo)人團隊統(tǒng)一制作各家標(biāo)書,陪標(biāo)人負(fù)責(zé)提供復(fù)印件、簽字、蓋章、繳付投標(biāo)保證金、上傳標(biāo)書等事項。這種圍標(biāo)和串標(biāo)方式隱蔽性強,一般很難通過MAC 地址、IP 地址、工程造價軟件鎖編碼和投標(biāo)保證金賬號一致等途徑發(fā)現(xiàn)審計證據(jù),如何發(fā)現(xiàn)重大項目中圍標(biāo)和串標(biāo)行為已經(jīng)成為擺在審計人員面前亟待解決的重要難題。
圍標(biāo)人團隊統(tǒng)一編寫各家標(biāo)書時會刻意避免雷同文本出現(xiàn),但是語言風(fēng)格、表達習(xí)慣、詞匯特征等語言表達特點不會發(fā)生本質(zhì)變化,因此投標(biāo)文件異常一致或高度雷同是重點審計方向。投標(biāo)文件響應(yīng)招標(biāo)文件,部分內(nèi)容雷同屬于正常情況,但不同投標(biāo)人技術(shù)標(biāo)中個性化內(nèi)容不可能完全相同,即使部分技術(shù)參數(shù)指標(biāo)基本相同(如技術(shù)方案、產(chǎn)品技術(shù)參數(shù)和實施計劃等),但落實到紙面上的文字也不會完全相同,因此不同投標(biāo)人制作的標(biāo)書內(nèi)容會有差異。如果2 份投標(biāo)文件使用詞匯、出現(xiàn)頻次、生僻詞、錯別字高度一致,則存在由同一個人或同一團隊編寫的重大嫌疑[1]。
傳統(tǒng)的審計方法是人工比對、分析招投標(biāo)文件,查找圍標(biāo)和串標(biāo)線索,如技術(shù)標(biāo)中方案細(xì)節(jié)一致、投標(biāo)文件中瑕疵或錯別字一致和大段內(nèi)容重復(fù)雷同等。通常每份投標(biāo)文件都在幾萬字左右,大型投標(biāo)項目一般都有幾十家甚至上百家投標(biāo)企業(yè),人工梳理如同大海撈針,難以全面處理大批量文該文件。而利用Python 的分詞技術(shù)、字典容器和矩陣演算等方法,可以用少量基礎(chǔ)代碼構(gòu)建算法模型,幫助審計人員高效地完成投標(biāo)文件詞頻統(tǒng)計、集合運算和結(jié)構(gòu)化分析、掃描投標(biāo)文件,為復(fù)雜的審計項目提供技術(shù)支持。
算法模型:設(shè)置文本詞組重合比例和重復(fù)比例2 份閾值來判斷2 份投標(biāo)文件的相似程度,如果2 份投標(biāo)文件的相似度超過一定閾值,則2 份投標(biāo)文件存在由同一個人或同一團隊編寫的重大嫌疑。
閾值1:詞組重合比例,即2 份文本中共同使用的詞組數(shù)量占2 份文本全部使用詞組數(shù)量的比例,每個詞組只計數(shù)一次[2]。
閾值2:詞組重復(fù)比例,即2 份文本中重復(fù)出現(xiàn)的詞組數(shù)量占2 份文本總詞組數(shù)量的比例,每個詞組按出現(xiàn)頻次計數(shù)。
由于漢字的使用習(xí)慣,不同文本之間都會存在詞組重合基數(shù),根據(jù)收集的500 份1.5 萬~3 萬字不同類型文該文件(包括小說、通信稿件、審計報告、產(chǎn)品說明書、投標(biāo)文件、游戲攻略和電影劇本等)的分析結(jié)果,不同類型文本之間詞組重合比例在11%~24%,詞組重復(fù)比例在13%~30%。投標(biāo)文件響應(yīng)招標(biāo)文件部分內(nèi)容雷同,同一項目投標(biāo)文件詞組重合比例和詞組重復(fù)比例較高屬于正常現(xiàn)象。2021 年某省公共資源交易中心圍標(biāo)和串標(biāo)審計項目經(jīng)公安機關(guān)協(xié)調(diào)篩選了17 個完全沒有圍標(biāo)和串標(biāo)嫌疑的項目,取得838 份投標(biāo)文件電子版,經(jīng)過分析比對同一項目投標(biāo)文件的詞組重合比例在28%~43%,詞組重復(fù)比例在31%~52%。
綜上所述,將2 份投標(biāo)文件詞組重合比例閾值設(shè)定為70%和詞組重復(fù)比例閾值設(shè)定為75%,如果詞組重合比例和詞組重復(fù)比例都超過了閾值,則2 份投標(biāo)文件高度相似,存在圍標(biāo)和串標(biāo)的重大嫌疑。進一步通過“詞頻分析結(jié)果”Excel 文件梳理關(guān)鍵詞組(生僻詞、錯別字等)出現(xiàn)頻次是否高度一致,固定審計證據(jù),鎖定涉嫌圍標(biāo)和串標(biāo)的投標(biāo)文件。
基于Python 編寫的算法模型由主程序和4 個可調(diào)用的自定義函數(shù)構(gòu)成。
第一步,導(dǎo)入需要使用的模塊,包括jieba(用于中文分詞)、docx(用于讀取word 文檔)、Counter(用于計算詞頻)和xlwings(用于Excel 數(shù)據(jù)輸出)。第二步,連續(xù)2 次調(diào)用自定義函數(shù)1,即def group_dict(file),對2 個指定的word 文檔進行分詞,并將每個詞組出現(xiàn)的次數(shù)記錄在字典中。第三步,調(diào)用自定義函數(shù)2,即def coincide(dict1,dict2),比較2 個文檔的詞組,找出重復(fù)的詞組,并將重復(fù)的詞組及其出現(xiàn)次數(shù)記錄在另一個字典中。第四步,調(diào)用自定義函數(shù)3,即def analyse(dict1,dict2,dict3),根據(jù)以上統(tǒng)計結(jié)果,輸出2 個文檔的詞組數(shù)量、重復(fù)詞組數(shù)量及比例等信息。第五步,使用print()語句將文檔的詞組數(shù)量、重復(fù)詞組數(shù)量及比例等信息打印在屏幕上,實際運行效果如圖1 所示。第六步,調(diào)用自定義函數(shù)4,即def output(dict1,dict2),將詞組及其出現(xiàn)次數(shù)分別輸出到Excel 文件中。
圖1 主程序在Python 解釋器中實際運行效果
主程序代碼如下。
import jieba # 導(dǎo)入jieba 模塊
from docx import Document # 導(dǎo)入Document模塊,用于讀取word 文檔
from collections import Counter # 導(dǎo)入Counter 模塊,用于計算詞頻
mport xlwings as xw # 導(dǎo)入xlwings 模塊
file1 = "C:/Users/86139Desktop/比對文本/20210104投標(biāo)文件1.docx"file2 ="C:/Users/86139Desktop/比對文本/20210104 投標(biāo)文件2.docx"
word_dict1=group_dict(file1) #調(diào)用自定義函數(shù)1
word_dict2=group_dict(file2) #調(diào)用自定義函數(shù)1
word_dict3=coincide(word_dict1,word_dict2) #調(diào)用自定義函數(shù)2
n1,n2,n3,n4,n5=analyse(word_dict1,word_dict2,word_dict3)#調(diào)用自定義函數(shù)3
results1=f'投標(biāo)文件1 使用詞組{len(word_dict1)}個,投標(biāo)文件2 使用詞組{len(word_dict2)}個,二個文件使用詞組重合{n1}個,詞組重合比例{n2}%'
results2=f'投標(biāo)文件1 詞組合計{sum(word_dict1.values())}個,投標(biāo)文件2 詞組合計{sum(word_dict2.values())}個,
二個文件使用重復(fù)詞組合計{n4}個,詞組重復(fù)比例{n5}%'
print(results1)
print(results2)
output(word_dict1,word_dict2) #調(diào)用自定義函數(shù)4
第一步,使用Document 函數(shù)讀取word 文檔。第二步,使用for paragraph in document.paragraphs 語句遍歷文檔的每段,調(diào)用jieba.lcut(paragraph.text)方法進行分詞,for 循環(huán)將每個詞組添加到word_list 列表中。第三步,使用Counter 函數(shù)統(tǒng)計每個詞出現(xiàn)的次數(shù),并使用del word_dict[key]方法刪除字典中的標(biāo)點符號、特殊字符、換行符和空格等干擾信息。第四步,使用sorted(word_dict.items(), key=lambda x:x[1], reverse=True)方法按照詞頻降序排序,返回排序后的“詞頻字典”return word_dict。
Python 中的字典是一種特殊的數(shù)據(jù)結(jié)構(gòu),它是一種鍵值對的集合,每個鍵都與一個值相關(guān)聯(lián)。字典的特點是其中的鍵是唯一的,值可以是任何類型,可以使用鍵來訪問值[3]。
自定義函數(shù)1 程序代碼如下。
def group_dict(file):
document = Document(file)
word_list = []
for paragraph in document.paragraphs:words = jieba.lcut(paragraph.text)for word in words:
word_list.append(word)word_dict = Counter(word_list)for key in list(word_dict.keys()):
del word_dict[key]
if key in '是的和與在等為對中年月日嗎':del word_dict[key]
if key=='':
del word_dict[key]
word_dict_sort = sorted(word_dict.items(), key=lambda x:x[1], reverse=True)
word_dict=dict(word_dict_sort)return word_dict
第一步,以dict3t = {}創(chuàng)建一個新字典。第二步,for key in dict 循環(huán)遍歷投標(biāo)文件“詞頻字典”dict1 和dict2,使用if key in dict2 判斷語句,如果2 個字典中有相同的鍵,使用min(dict1[key], dict2[key])方法將交集的鍵和較小的鍵值添加到新字典dict3 中。第三步,返回“重復(fù)詞組詞頻字典”return dict3。
自定義函數(shù)2 程序代碼如下。
def coincide(dict1,dict2):dict3t = {}
1.2.3 Transwell實驗檢測細(xì)胞遷移和侵襲能力 收集1.2.1穩(wěn)定表達miR-145SiHa細(xì)胞,無血清培養(yǎng)基制細(xì)胞懸液,接種于Transwell小室上層(3×103個/孔)[6]。Transwell小室風(fēng)干后,加入500 μL 0.1%結(jié)晶紫染色,顯微鏡下拍照并計數(shù)發(fā)生遷移的細(xì)胞數(shù)量。細(xì)胞侵襲實驗在Transwell小室上層加入50 μL 2.0 mg/mL基質(zhì)膠Matrigel,凝固后接種SiHa細(xì)胞,之后同細(xì)胞遷移操作。
for key in dict1:
if key in dict2:
dict3 [key] = min(dict1[key], dict2[key])return dict3
第一步,使用for word in dict 語句分別遍歷dict1、 dict2和dict3 這3 個字典。第二步,分析計算2 份投標(biāo)文件詞組重合比例n2 和重復(fù)比例n5 來判斷2 份文件的相似程度。第三步,返回n1、n2、n3、n4 和n5(詞組數(shù)量、詞組重合比例、總數(shù)量、重復(fù)詞組數(shù)量以及詞組重復(fù)比例),用于主程序print 語句輸出程序結(jié)果。
詞組重合比例n2=dict3 字典鍵的數(shù)量/(dict1 字典鍵的數(shù)量+dict2 字典鍵的數(shù)量-dict3 字典鍵的數(shù)量)。
詞組重復(fù)比例n5=dict3 字典鍵值合計/(dict1 字典鍵值合計+dict2 字典鍵值合計-dict3 字典鍵值合計)。
自定義函數(shù)3 程序代碼如下:
def analyse(dict1,dict2,dict3):n1 = 0
for word in dict1:
if word in dict2:
n1 += 1
n2 = round(n1 / (len(dict1) + len(dict2) - n1)*100,2)
n3 = sum(dict1.values())+sum(dict2.values())
n4 = sum(dict3.values())
n5=round(n4/(n3-n4)*100,2)
return(n1,n2,n3,n4,n5)
第一步,使用xlwings 模塊xw.Book()和wb.sheets[0]生成一個新的Excel 文件。第二步,利用解包方法for key,value in dict1.items()取得詞組重合比例和詞組重復(fù)比例。第三步,使用sht.range().value 賦值語句將詞組重合比例和詞組重復(fù)比例分析結(jié)果分別寫入A1 和A2 單元格。第四步,使用sht.range().options(transpose=True).value = list(dict3.keys())語句寫入分析過程,A4 單元格縱向?qū)懭胪稑?biāo)文件1 或文件2 中曾經(jīng)使用過的全部詞組,B4 單元格寫入投標(biāo)文件1 和文件2 中該詞組出現(xiàn)總次數(shù),C4 單元格寫入投標(biāo)文件1 該詞組出現(xiàn)次數(shù),D4 單元格寫入投標(biāo)文件2該詞組出現(xiàn)次數(shù)。第五步,以wb.save(“C:/Users/86139/Desktop/詞頻分析結(jié)果.xlsx”)語句將記錄上述分析過程的文件保存在桌面并命名“詞頻分析結(jié)果.xlsx”。自定義函數(shù)4 程序代碼如下。def output(dict1,dict2):
wb = xw.Book()
sht = wb.sheets[0]
sht.range('A1').value = results1
sht.range('A2').value = results2
dict3 = {}
for key, value in dict1.items():if key in dict2:
dict3[key] = value + dict2[key]else:
dict3[key] = value
for key, value in dict2.items():
if key not in dict1:
dict3[key] = value
sht.range('A4').value =“ 詞組”
sht.range('A5').options(transpose=True).value = list(dict3.keys())
sht.range('B4').value = '總次數(shù)'
sht.range('B5').options(transpose=True).value = list(dict3.values())
sht.range('C4').value = '投標(biāo)文件1 出現(xiàn)次數(shù)'A_list = list(dict3.keys())n=5
for i in range(len(A_list)):
if A_list[i] in dict1.keys():
sht.range('C' + str(n)).value = dict1[A_list[i]]n = n + 1
sht.range('d4').value = '投標(biāo)文件2 出現(xiàn)次數(shù)'A_list = list(dict3.keys())
n = 5
for i in range(len(A_list)):
if A_list[i] in dict2.keys():
sht.range('d' + str(n)).value = dict2[A_list[i]]n = n + 1
wb.save("C:/Users/86139/Desktop/詞頻分析結(jié)果.xlsx")wb.close()
2021 年初某省公共資源交易中心收到舉報材料,年初某市重點安置房建設(shè)項目中標(biāo)結(jié)果存在圍標(biāo)嫌疑,項目涉案金額巨大,投標(biāo)人涉及38 家企業(yè),圍標(biāo)手段非常專業(yè),檢查MAC 地址、IP 地址、工程造價軟件鎖編碼和投標(biāo)保證金賬號等均未發(fā)現(xiàn)異常。僅剩的審計方向就是比對投標(biāo)文件是否異常一致或高度雷同,如果使用傳統(tǒng)的人工方式對38 份投標(biāo)文件進行比對分析,需要3~4 名審計人員加班加點工作3 周才有可能完成,且而且比對分析效果也很難保證。
審計組運用該文審計技術(shù)僅4天時間就完成了全部38份投標(biāo)文件的相似度分析。一共38 份投標(biāo)文件,每次比對分析2 份投標(biāo)文件,共有(38×37)/2=1406 種比對組合,排除反向組合(A-B 組合與B-A 組合是相同的),有效比對組合共計1406/2=703 組。對703 組比對分析結(jié)果梳理進行匯總,發(fā)現(xiàn)32 份投標(biāo)文件呈現(xiàn)4 個規(guī)律性集合,詳見表1。其中,一個集合內(nèi)元素相似度正常,3 個集合內(nèi)元素高度相似。集合1 包括6 份投標(biāo)文件,詞組重合比例平均值為35.45%,詞組重復(fù)比例平均值為38.45%,未超過閾值;集合2 包括12 份投標(biāo)文件,詞組重合比例平均值為77.17%,詞組重復(fù)比例平均值為81.03%,超過閾值;集合3 包括9 份投標(biāo)文件,詞組重合比例平均值為79.45%,詞組重復(fù)比例平均值為82.05%,超過閾值;集合4 包括11份投標(biāo)文件,詞組重合比例平均值為74.07%,詞組重復(fù)比例平均值為79.73%,超過閾值。
表1 38 份投標(biāo)文件集合分析結(jié)果
審計組進一步利用“詞頻分析結(jié)果”Excel 文件重點梳理了38 份投標(biāo)文件的62 項關(guān)鍵詞組(生僻詞和錯別字等)的出現(xiàn)頻率,呈現(xiàn)出高度的一致性和規(guī)律性。如“砌筑檢查井”,32 份投標(biāo)文件出現(xiàn)頻次在32~35 次,其他投標(biāo)文件均少于5 次;“工程定位復(fù)測”,32 份投標(biāo)文件均出現(xiàn)8 次,其他投標(biāo)文件均未出現(xiàn)?!皦牵_)防潮層”錯別字32 份投標(biāo)文件均出現(xiàn),其他投標(biāo)文件均正確,詳見表2(關(guān)鍵詞頻率對比情況)。
表2 關(guān)鍵詞組頻率對比情況
初步鎖定32 家企業(yè)涉嫌圍標(biāo),同舉報材料反映的9 家企業(yè)涉嫌圍標(biāo)的情況大相徑庭。起初公安機關(guān)對如此短的時間就反饋審計結(jié)果和涉嫌圍標(biāo)企業(yè)如此之多也持懷疑態(tài)度,后經(jīng)公安機關(guān)偵辦核實32 家投標(biāo)人全部參與該項目串通投標(biāo)犯罪行為,32 份標(biāo)書由圍標(biāo)人團隊統(tǒng)一通過3 份標(biāo)書復(fù)制、修改、增刪制作完成。最終成功破獲該起涉及安置房工程招標(biāo)的特大串通投標(biāo)案,事半功倍的效率和精準(zhǔn)定位的審計手段得到了司法機關(guān)的高度評價和專項表彰。
該文審計方法核心通過Python 技術(shù)自動讀取文件、中文智能分詞、矩陣演算和集合運算,完成了大批量文該文件數(shù)據(jù)信息要點分割、獲取和數(shù)據(jù)關(guān)聯(lián)性分析,解決了傳統(tǒng)方法和人工手段難以全面處理大批量文該文件的難題,未來在判定論文抄襲、快速提取文本關(guān)鍵詞、敏感詞匯預(yù)警等方面都有重要的推廣意義。雖然該文審計方法提高了圍標(biāo)和串標(biāo)審計項目的審計質(zhì)量和精準(zhǔn)度,但是在程序交互性設(shè)計和算法模型方面有待進一步完善和提升。
除了上述介紹的Python 技術(shù)在圍標(biāo)和串標(biāo)項目中的審計方法,還有很多基于Python 技術(shù)的審計方法值得審計人員不斷探索和研究。Python 技術(shù)未來在審計項目數(shù)據(jù)采集清洗、數(shù)據(jù)挖掘性分析和辦公自動化等方面有廣泛的應(yīng)用前景[4]。首先,傳統(tǒng)審計范圍主要是財務(wù)數(shù)據(jù),Python技術(shù)可以將音視頻、圖像、定位信息、傳感器信息等非結(jié)構(gòu)化信息進行采集、清洗并轉(zhuǎn)換為結(jié)構(gòu)化信息,從而突破傳統(tǒng)審計內(nèi)容的限制,可提供不同維度的大數(shù)據(jù),助力于挖掘性分析,推動數(shù)據(jù)驅(qū)動型審計模式的發(fā)展[5]。其次,傳統(tǒng)審計多數(shù)是面對數(shù)據(jù)和文本的一維界面,很難找出數(shù)據(jù)中隱藏的規(guī)律和問題。Python 技術(shù)在數(shù)據(jù)交互分析、自動化輸出以及數(shù)據(jù)可視化方面都具有無與倫比的優(yōu)勢,包括審計數(shù)據(jù)以圖表、數(shù)據(jù)矩陣等形式的多維表達,可展示出豐富的細(xì)節(jié),為大數(shù)據(jù)時代創(chuàng)新審計思路、拓寬審計方法提供技術(shù)可能性。
大數(shù)據(jù)時代的到來和大數(shù)據(jù)技術(shù)的發(fā)展推動了各個行業(yè)的轉(zhuǎn)型升級,也給審計人員帶來了新的機遇和挑戰(zhàn),“君子性非異也,善假于物也”,審計人員也應(yīng)與時俱進,主動迎接挑戰(zhàn),創(chuàng)新審計思維,善于運用Python 等大數(shù)據(jù)技術(shù),將大數(shù)據(jù)技術(shù)與審計業(yè)務(wù)進行有機融合,努力使自己成長為大數(shù)據(jù)時代“一專多能”的復(fù)合型審計人才,推動審計技術(shù)的不斷創(chuàng)新。