python学习 101-utils工具类的编写

前言: 

        本人也是开始学习python,感觉到python的简单和编写容易之处。我是以自然语言处理为入口进行学习python的,所以会涉及一些文本处理的工作。因为受以前学习java语言的影响,本人会喜欢自己封装一些方法作为自己的工具类/工具函数,因此本人此次发布的是自己写的一些工具函数作为分享。(不喜勿喷 谢谢)^-^

工具函数大致列表:

名字即功能:

1.文件1读入写入文件2
2.文件1内容分词去逗号存入文件2
3.函数1调用函数2进行分词和去符号去停用词
4.为了计算p(w),words总数,去重words总数
5.[1,2,3]+[4,5,6]=[5,7,9]
6.[1,2,3]*2=[2,4,6]
7.余弦距离 Li
8.余弦距离
9.得到一个A_rate之后乘以的新wordVector
10.得到一个词的词向量
11.字典根据value进行排序
12.'''将字典数据存入到二进制文件中'''
13.二进制文件中读入数据并转化为字典'''
14.csv文件时为其头部加上列名
15.测试集与训练集计算
16.随机选择数据
17.li arctan(1/|a-b|)
18.19.准确率

代码:

# coding:utf8
import jieba
import numpy as np
import gensim
import csv
import pickle
import pandas as pd
import math
# 工具函数
'''
    读入文件1数据写入文件2 这个函数是学习初期对读入文件和写入文件的
    一个简单实现,就是讲txt1中的数据通过读取然后在写入文件txt2中
    注意在函数结束时的close方法的调用防止内存占用
'''


def read1ToWrite2(readfile_path, writefile_path):
    fin = open(readfile_path, 'r')  # 路径写死了
    fou = open(writefile_path, 'w')
    line = fin.readlines()  # 加s的是获取所有数据
    for i in line:
        fou.write(i)
    fin.close()
    fou.close()


"""
这个函数那是在第一个函数的基础上进行改进
增加了使用jieba进行分词,是按照一行进行读取的同时设置了分词模式,
并使用了简单粗暴的方法进行了逗号等字符的去除
同时并将数据写入另一个文件中    
"""


# 文件1内容分词去逗号存入文件2
def cutWordTofile(writefile_path, cutWordfile_path):
    fin = open(writefile_path, 'r')  # 路径写死了
    fou = open(cutWordfile_path, 'w')
    line = fin.readline()
    while line:
        newline = ' '.join(jieba.cut(line, cut_all=False)).replace(',', '').replace('。', '')  # 结巴分词并去除逗号
        fou.write(newline)
        line = fin.readline()  # 每次更新一个line相当于i++
    fin.close()
    fou.close()


"""
这段函数里面总共有两个函数组成是进一步的改进,增加了停用词的去除
并实现了停用词的动态增加
函数一执行文件的读写操作,函数1调用函数2进行分词和去符号去停用词等操作
"""


# 读入文件分词之后存入文件中间有三函数(1,2,)的调用使用线进行分割
# --------------------------------------------------------------------------------------------------------
# 1读入文件分词之后存入文件
def readCutRemovewrite(readfile_path, writefile_path):
    inputs = open(readfile_path, 'r', encoding='utf-8')
    outputs = open(writefile_path, 'w', encoding='utf8')
    for line in inputs:
        line_seg = seg_sentence(line)  # 这里的返回值是字符串
        outputs.write(line_seg + '\n')
    outputs.close()
    inputs.close()


# 2句子分词并去停用词
def seg_sentence(sentence):
    # 2创建停用词list
    stopWords = [line.strip() for line in open('data/stopWord.txt', 'r', encoding='utf-8').readlines()]
    sentence_seged = jieba.cut(sentence.strip())
    outstr = ''
    for word in sentence_seged:
        if word not in stopWords:
            if word != '\t':
                outstr += word
                outstr += " "
    return outstr


# --------------------------------------------------------------------------------------------------------
"""
这个函数是为了计算p(w),在分词的同时记录以下数据
1所有words总数
2去重words总数
3每一个唯一word的概率
带着写入文件功能
"""


def get_words_Word_wordRate(readFilePath, writeFilePath):
    with codecs.open(readFilePath, 'r', 'utf8') as f:
        txt = f.read()
    fout = open(writeFilePath, 'w', encoding='utf-8')
    seg_list = jieba.cut(txt)
    c = Counter()  # 内函数计数器继承了字典类
    count = 0
    for x in seg_list:
        if len(x) > 1 and x != '\r\n':
            count += 1
            c[x] += 1
    print('words result')
    print('all number result')
    print(count)
    print('no repeat words result')
    print(len(c))
    for key, value in c.most_common():  # 5就是返回5个词无参数 就是所有
        # print('%s  %d' % (key,   round(value/count, 5)))#other write
        # print(key, ' '*3, value, ' '*3,  round(value/count, 10))
        writestr = key + ' ' * 10 + str(round(value / count, 10)) + '\n'  # 通过str将int转成string
        fout.write(writestr)
    f.close()
    fout.close()


'''函数@liyang 将两个list[] 中每一个值对应相加如[1,2,3]+[4,5,6]=[5,7,9]
 返回值为新列表的长度和 数据'''

#这个函数有了更新使用了矩阵multi_dynamic_list_sum(multi_list)
def two_list_sum(alist, blist):
    c = [a[i] + b[i] for i in range(min(len(a), len(b)))]
    return c


'''函数@liyang 将list[] 中每一个值对应相乘一个数a如[1,2,3]*2=[2,4,6]
 返回值为新列表的数据'''

def list_mult_a(listt, a):
    # 警告,当list的很大且数据都是小数存在,a也是小数时,
    # 这个函数会报错,说a不能是float类型 但实际检验过程中是可为float的
    b = [i * a for i in listt]
    return b


'''这是对上一个函数的改进 变成矩阵在乘防止出现问题'''
def listto_matrix_mult_a(list, a):
    b = np.array(list)
    c = b * a
    return c


'''输入:是两个向量的坐标
    输出: 两者的余弦距离'''

def cosineSimilarity_Li(a_vect, b_vect):
    '''@liyang'''
    dot_val = 0.0
    a_norm = 0.0
    b_norm = 0.0
    cos = None

    for i in range(min(len(a_vect), len(b_vect))):
        dot_val += a_vect[i] * b_vect[i]  # 分子
        a_norm += a_vect[i] ** 2  # a_vect绝对值
        b_norm += b_vect[i] ** 2  # b_vect绝对值
    if a_norm == 0 or b_norm == 0:
        cos = -1
    else:
        cos = dot_val / ((a_norm * b_norm) ** 0.5)

    return cos


'''余弦距离'''

def cosineSimilarity(a_vect, b_vect):
    '''@others'''
    dot_val = 0.0
    a_norm = 0.0
    b_norm = 0.0
    cos = None
    for a, b in zip(a_vect, b_vect):
        dot_val += a * b
        a_norm += a ** 2
        b_norm += b ** 2
    if a_norm == 0.0 or b_norm == 0.0:
        cos = -1
    else:
        cos = dot_val / ((a_norm * b_norm) ** 0.5)
    return cos


'''动态多重list相加 如:[[1, 2, 3], [4, 5, 6], [7, 8, 9]] 每一位对应相加得[12 15 18]'''
'''from liutao 使用numpy转化成矩阵计算'''

#对上边函数进行了更新
def multi_dynamic_list_sum(multi_list):
    b = np.array(multi_list)
    list_sum = b.sum(axis=0)  # 这里的0也可以是1 为每一个小list求和
    return list_sum


# liyang2018.10.5---------------------------------------------------------------------------------------------------
'''@liyang得到一个A_rate之后乘以的新wordVector'''
def word2vectoMultiA_rate(word, A_rate):
    '''
    :param word: 词语
    :param A_rate: A概率
    :return: a概率*词向量的结果
    '''
    fdir = r'model/'
    model = gensim.models.Word2Vec.load(fdir + 'cauc.incivi.text.model')
    wordVector = model[word]
    newWordVector = listto_matrix_mult_a(wordVector, A_rate)
    return newWordVector


'''@liyang得到一个词的词向量,为了平均词向量准备的'''

def getword2vector_for_averageVs(word):
    '''
    :param word: 词语
    :return: 词向量
    '''
    fdir = 'model/'
    model = gensim.models.Word2Vec.load(fdir + 'cauc.incivi.text.model')
    wordVector = model[word]
    return wordVector

# liyang2018.10.5---------------------------------------------------------------------------------------------------
'''字典根据value进行排序'''
def sortDictForValueWriteCsv(Senteindex,dict):
    '''
    把一个字典根据value进行排序,并保存前10个
    :param Senteindex:外部参数
    :param dict:字典
    :return:
    '''
    csvfile = open('result/simiSifResult.csv', 'a+', encoding='utf-8', newline='')
    csvWrite = csv.writer(csvfile)
    # csvWrite.writerow(('societyIndex','caucnumber' 'cosine'))
    a=sorted(dict.items(),key=lambda item:item[1],reverse=True)#核心代码
    countt = 1 #计时器
    for i ,j in a:
        if countt<=10:
            csvWrite.writerow((Senteindex,i,j))
            countt+=1
        else:
            break
    csvfile.close()

'''判断A B C D个数那个最多就返回时哪一类'''
def getMaxABCD(A, B, C, D):
    strA = None
    if max(A, B, C, D) == A:
        strA = 'A'
    if max(A, B, C, D) == B:
        strA = 'B'
    if max(A, B, C, D) == C:
        strA = 'C'
    if max(A, B, C, D) == D:
        strA = 'D'
    return strA

'''将字典数据存入到二进制文件中'''
def saveDictInBinFile(Dict,filepath):
    '''
    :param Dict: 字典
    :param filepath: 保存路径
    :return:
    '''
    f = open(filepath, 'wb')
    # pickle.dump(1, f)
    pickle.dump(Dict, f)
    f.close
    print('二进制文件保存成功')

'''二进制文件中读入数据并转化为字典'''
def readFromInBinToDict(filepath):
    '''
    将二进制文件读取变成字典
    :param filepath: 二进制文件路径
    :return:字典
    '''
    f = open(filepath, 'rb')#     file为.dat文件
    # pickle.load(f)
    d = pickle.load(f)
    f.close()
    Dict = {}
    Dict = d
    print('二进制文件读取完成')
    return Dict

'''在写入csv文件时为其头部加上列名但是因为to_csv()不知怎么用,所有已就用这个了'''
def setCscHead(filepath,list):
    '''
    :param filepath: 文件路径
    :param list: 列名的集合列表
    :return:
    '''
    csvfile = open(filepath, 'w', encoding='utf-8', newline='')
    csvWrite = csv.writer(csvfile)
    csvWrite.writerow(list)
    csvfile.close()
    print('csv列名写完成')

'''这个函数是为生成好的测试集和训练集 两个字典进行计算的 并把计算结果保存起来'''
def testAndTrainCalculat(testDict,trainDict,testfile,trainfile,resultfile):
    '''
       :param testDict: 测试集字典
       :param trainDict: 训练集字典
       :param testfile: 测试集原文件
       :param trainfile: 训练集原文件
       :param resultfile: 计算结果保存文件
       :return:
       '''
    testdata = pd.read_csv(testfile)
    traindata = pd.read_csv(trainfile)
    COS_DICT={}
    list=[]
    for teindex,tevs in testDict.items():
        for trindex,trvs in trainDict.items():
            cos = cosineSimilarity(tevs,trvs)#计算相似度
            COS_DICT.setdefault(trindex,cos)
        a = sorted(COS_DICT.items(), key=lambda item: item[1], reverse=True)#字典排序 降序

        list.append([teindex,a[0][0],a[0][1],testdata.loc[teindex-1,'classs'],testdata.loc[teindex-1,'descrip'],
                     traindata.loc[a[0][0]-1,'class'],traindata.loc[a[0][0]-1,'describe']])
        #上面这个list中加入的东西比较多包括 testfile里面的下标、类别、句子,trainfile也一样
        COS_DICT.clear()
    # dataframe = pd.DataFrame(list)
    # setCscHead(resultfile,['teindex','trindex','cos','teclass','tedescribe','trclass','trdescribe'])
    # dataframe.to_csv(resultfile,mode='a',index=False,encoding='utf-8',header=False)
    print('测试集认定最max相似完成')

'''这个函数是为生成好的测试集和训练集 两个字典进行计算的 并把计算结果的(前十个)保存起来'''
def testAndTrainCalculatTen(testDict,trainDict,testfile,trainfile,resultfile):
    '''
    :param testDict: 测试集字典
    :param trainDict: 训练集字典
    :param testfile: 测试集原文件
    :param trainfile: 训练集原文件
    :param resultfile: 计算结果保存文件
    :return:
    '''
    testdata = pd.read_csv(testfile)
    traindata = pd.read_csv(trainfile)
    COS_DICT={}
    list=[]
    for teindex,tevs in testDict.items():
        for trindex,trvs in trainDict.items():
            cos = cosineSimilarity(tevs,trvs)#计算相似度
            COS_DICT.setdefault(trindex,cos)
        a = sorted(COS_DICT.items(), key=lambda item: item[1], reverse=True)#字典排序 降序
        for i in range(10):
            list.append([teindex,a[i][0],a[i][1],testdata.loc[teindex-1,'classs'],testdata.loc[teindex-1,'descrip'],
                         traindata.loc[a[i][0]-1,'class'],traindata.loc[a[i][0]-1,'describe']])
        #上面这个list中加入的东西比较多包括 testfile里面的下标、类别、句子,trainfile也一样
        COS_DICT.clear()
    dataframe = pd.DataFrame(list)
    print('list长度',len(list))
    setCscHead(resultfile,['teindex','trindex','cos','teclass','tedescribe','trclass','trdescribe'])
    dataframe.to_csv(resultfile,mode='a',index=False,encoding='utf-8',header=False)
    print('测试集认定相似前10个完成')


'''随机选择数据的函数'''
def dataRandomSelectFromDBSoAndCa():
    data = pd.read_csv("F:\研究生课题\数据\DBsociAndCauc.csv")
    datalist=[]
    randomlist = []
    for i in range(111):#循环几次就是选择出多少条出来
        randmindex=random.randint(1, len(data))
        randomlist.append(randmindex)

    dataSelect=data.ix[randomlist,:]
    print(dataSelect.classs.value_counts()/len(dataSelect)) #统计每一类的所占的比例

    dataframe = pd.DataFrame(dataSelect)
    dataframe.to_csv('data/DBtestSoAndCa.csv', index=False)
    print('数据选择完成')


'''融合函数 Li_arctan(x)语义融合了处罚规则'''
def Liarctan(testPL,trainPL):
    if testPL==trainPL:
        a = (2/math.pi)*math.atan(1/math.fabs(0.001))
    else:
        a = (2/math.pi)*math.atan(1/math.fabs(testPL-trainPL))
    return a

def rightRateForTen(testfile,testresult):
    '''前10个,先确定好类,在计算准确率'''
    datatest = pd.read_csv(testfile)
    data = pd.read_csv(testresult)
    datatrindex = data[['trclass']]
    # print(datatrindex)
    # allcount = 1
    count = 0
    A_count = 0
    B_count = 0
    C_count = 0
    D_count = 0
    list=[]
    for i in datatrindex.values:
        # print(i)
        if i=='A':
            A_count+=1
        if i=='B':
            B_count+=1
        if i=='C':
            C_count+=1
        if i=='D':
            D_count+=1
        count+=1
        if count==10:
            predictClass=getMaxABCD(A_count,B_count,C_count,D_count)
            list.append(predictClass)
            count=0
            A_count = 0
            B_count = 0
            C_count = 0
            D_count = 0
    print('predictclass列的长度:',len(list))
    datatest['predictClass']=list
    dataRate=datatest[datatest['classs']==datatest['predictClass']]
    print('准确个数:',len(dataRate))
    print('准确率:', len(dataRate) / len(datatest))

def rightRateForMax(resultfile):
    '''max准确率求解'''
    data= pd.read_csv(resultfile)
    dataright=data[data['teclass']==data['trclass']]
    print('总个数:',len(data))
    print('准确个数:',len(dataright))
    print('准确率:',len(dataright)/len(data))

猜你喜欢

转载自blog.csdn.net/u013521274/article/details/84993954