# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# +
import numpy as np
import pandas as pd

#   1.导入训练集的数据、数据预处理

df=pd.read_csv("train.csv")              #打开训练集文件
clm=df.columns                            #clm为各列的列标
mean=np.nanmean(df,axis=0)                #求出每一列的均值mean（用来填充缺失值）
j=0                                       
for i in clm:                             #用均值替换缺失值
    df[i].fillna(mean[j],inplace=True)    
    j=j+1 
m=20000         #样本数
n=785          #X的项数
df_X=df.drop('id',axis=1)             
df_X=df_X.drop('label',axis=1)                #去掉训练集中的outcome和id两列
df_X=np.c_[np.ones((m,1)),df_X]           #再加上一列全为1的数据作为“x0”，得到训练集的X矩阵df_X
df_X=np.array(df_X)
max_X=df_X.max(axis=1)         #求出每一行的最大值
min_X=df_X.min(axis=1)         #求出每一行的最小值
X = np.empty(shape=df_X.shape,dtype=float)                 
for i in range(m):
    X[i,:]=(df_X[i,:]-min_X[i])/(max_X[i]-min_X[i])        #归一化
df_X=X                              #得到归一化后的X矩阵
df_Y=df['label'][:]              #得到标签矩阵
df_Y=np.array(df_Y)
theta=np.random.uniform(0,1,(10,n))    #存放theta


# -

#  2.用梯度下降法训练模型
def softmax(X):   #定义softmax函数
    return np.exp(X) / np.sum(np.exp(X))


count=100                #迭代次数
alpha=0.1                #学习率
for i in range(count):
    for j in range(m):
        x=df_X[j].reshape(-1, 1)
        y=np.zeros((10, 1))        #独热编码
        y[df_Y[j]]=1               #独热编码
        predict_y=softmax(np.dot(theta, x))       #算出每个标签的概率，存放于predict_y中
        theta=theta-alpha*(np.dot((predict_y- y), x.T))    #更新theta的值  
print(theta)          #看看theta

# +
 #  3.预测
test=pd.read_csv("test.csv")              #打开训练集文件 
test_X=test.drop('id',axis=1)             #去掉id那一列
test_X=np.c_[np.ones((10000,1)),test_X]           #再加上一列全为1的数据作为“x0”，得到测试集的X矩阵
test_X=np.array(test_X)

max_test_X=test_X.max(axis=1)         #求出每一行的最大值
min_test_X=test_X.min(axis=1)         #求出每一行的最小值

for i in range(10000):
    test_X[i,:]=(test_X[i,:]-min_test_X[i])/(max_test_X[i]-min_test_X[i])        #归一化  
print(test_X)

# +
#  4.将预测写入文件
label=np.empty(shape=(10000,1),dtype=int)              #label用来存放预测出的标签
test_Y=np.empty(shape=(10000,10),dtype=int)              #test_Y用来存放预测出的标签的独热编码
for i in range(10000):                                 #根据已得出的theta预测test_Y
    test_Y[i]=np.dot(theta,test_X[i])
    label[i]=np.argmax(softmax(test_Y[i]))

label=label.T
label=label.flatten()            #把数组降为一维 
a=np.array(range(10000))         #a用来存放id
a=a.flatten()                    #把数组降为一维
dataframe = pd.DataFrame({'id':a,'label':label})             #把a，label放入dateframe
dataframe.to_csv("test_ddr.csv",index=False,sep=',')      #把dateframe写入文件中

# +

#  5.评估（并没有成功写出来的，以下代码作废）

test_0=df.sample(frac=1/5,replace=True,random_state=1,axis=0)
test_0_X=test_0.drop('label',axis=1)             
test_0_X=test_0_X.drop('id',axis=1)                
test_0_X=np.c_[np.ones((4000,1)),test_0_X]          
test_0_X=np.array(test_0_X)
max_X=test_0_X.max(axis=1)         #求出每一行的最大值
min_X=test_0_X.min(axis=1)         #求出每一行的最小值
X = np.empty(shape=test_0_X.shape,dtype=float)                 
for i in range(4000):
    X[i,:]=(test_0_X[i,:]-min_X[i])/(max_X[i]-min_X[i])        #归一化
test_0_X=X                              
test_0_Y=test_0['label'][:]                 
test_0_Y=np.array(test_0_Y)                 

# +
p_label=np.empty(shape=(4000,1),dtype=int)            #test_0_label用来存放预测出的标签
p_Y=np.empty(shape=(4000,10),dtype=int)              #p_Y用来存放预测

TP=0
FN=0
FP=0

for i in range(4000):                                
    p_Y[i]=np.dot(theta,test_0_X[i])                  #预测中
    p_label[i]=np.argmax(softmax(test_Y[i]))
    y=np.zeros((10, 1))        
    y[p_label[i]]=1            #得出预测出的标签的独热编码y
    y0=np.zeros((10,1))
    y0[test_0_Y[i]]=1         #得出真实的标签的独热编码y0
    #真正例
    TP=TP+np.sum(np.logical_and(np.equal(y0,1),np.equal(y,1)))
    #假正例
    FP=FP+np.sum(np.logical_and(np.equal(y0,0),np.equal(y,1))) 
    #假反例
    FN=FN+np.sum(np.logical_and(np.equal(y0,0),np.equal(y,0)))
    
#FN_mean=
micro_P=TP_mean/(TP_mean+FP_mean)  #微查准率
micro_R=TP_mean/(TP_mean+FP_mean)  #微查全率
micro_F1=2*micro_P*micro_R/(micro_P+micro_R)
print(micro_P)
print(micro_R)
print(micro_F1)
# -



StarcoderdataJupyterScriptsDedupFiltered