Matlab灰色預測和統計分析
阿新 • • 發佈:2019-02-01
如何利用Matlab讀取資料進行統計分析?
假設有我在D盤根目錄下有5個txt文字,其檔案格式如下:
我們需要如何讀取這個這樣中英文數字混編的資料進行統計分析呢?
假設我們的資料都是以ANSI編碼,如果不是,需要進行另存為覆蓋儲存為這種編碼格式。
接下來,老規矩,廢話不多說,直接上程式碼。
- 編寫drop.m函式檔案,功能是篩去校選修課資料(院選修課我沒見過,故不能臆斷)。
function s=drop(s,term_type)
[bool,inx]=ismember('校_任選課',term_type);
if bool
s(inx)=[];
end
- 編寫grade.m函式檔案,以zzu績點計算規則,計算每學期的平均績點。
function grade=grade(term_credit,term_grade,term_type)
credit=drop(term_credit,term_type);
weight=credit/sum(credit);
grade=str2double(drop(term_grade,term_type));
grade=sum(weight.*grade);
end
- 編寫主函式,作圖分析,分析包括簡單灰色預測,預測準確性不做評判。
%% 初始化變數。
clc
clear
for i=1:5
str_i=num2str(i);
filename = ['D:\第' str_i '學期.txt'];
delimiter = ',';
%% 每個文字行的格式字串:
% 列1: 文字 (%s)
% 列2: 文字 (%s)
% 列3: 雙精度值 (%f)
% 列4: 文字 (%s)
% 列5: 雙精度值 (%f)
% 有關詳細資訊,請參閱 TEXTSCAN 文件。
formatSpec = '%s%s%f%s%s%[^\n\r]';
%% 開啟文字檔案。
fileID = fopen(filename,'r');
%% 根據格式字串讀取資料列。
% 如果其他檔案出現錯誤,請嘗試通過匯入工具重新生成程式碼。
dataArray = textscan(fileID, formatSpec, 'Delimiter' , delimiter, 'ReturnOnError', false);
%% 關閉文字檔案。
fclose(fileID);
%% 將匯入的陣列分配給列變數名稱
eval(['term' str_i '_sub' '=' 'dataArray{:, 1}' ';']);
eval(['term',str_i,'_type' '=' 'dataArray{:, 2}' ';'] );
eval(['term',str_i,'_credit' '=' 'dataArray{:, 3}' ';']);
eval(['term',str_i,'_score' '=' 'dataArray{:, 4}' ';'] );
eval(['term',str_i,'_grade' '=' 'dataArray{:, 5}' ';'] );
%% 清除臨時變數
clearvars filename delimiter formatSpec fileID dataArray ans;
end
grade_1=grade(term1_credit,term1_grade,term1_type);
grade_2=grade(term2_credit,term2_grade,term2_type);
grade_3=grade(term3_credit,term3_grade,term3_type);
grade_4=grade(term4_credit,term4_grade,term4_type);
grade_5=grade(term5_credit,term5_grade,term5_type);
grade=[grade_1,grade_2,grade_3,grade_4,grade_5]
term=1:5
ave_grade=(grade_1+grade_2+grade_3+grade_4+grade_5)/5;
% 建立 axes
axes1 = axes('Parent',figure,...
'XTickLabel',{'第1學期','第2學期','第3學期','第4學期','第5學期'},...
'XTick',[1 2 3 4 5]);
box(axes1,'on');
hold(axes1,'all');
% 建立 plot
plot(term,grade,'-mo',...
'LineWidth',2,...
'MarkerEdgeColor','k',...
'MarkerFaceColor',[.49 1 .63],...
'MarkerSize',12)%plot修飾命令
plot(1:0.01:5,ave_grade)
for i=1:5
text(term(i),grade(i)+0.1,num2str(grade(i)))
end
% 建立 xlabel
xlabel('學期');
% 建立 title
title(['學期績點變化(平均值:' num2str(ave_grade) ')']);
% 建立 ylabel
ylabel({'績點'});
hold off;
%%
figure
credit2=drop(term2_credit,term2_type);
sub2=drop(term2_sub,term2_type);
explode=zeros(1,length(credit2));
explode(5)=1;
pie3(credit2,explode,sub2)
title('第二學期學科學分分佈(學科重要性)');
%%
score1=str2double(drop(term1_score,term1_type))
sub1=drop(term1_sub,term1_type)
% 建立 figure
%figure;
% 建立 axes
axes1 = axes('Parent',figure,...
'XTickLabel',sub1,...
'XTick',[1 2 3 4 5 6 7 8],'FontSize',8);
box(axes1,'on');
hold(axes1,'all');
% 建立 title
title('第一學期各科成績');
% 建立 xlabel
xlabel('科目');
% 建立 ylabel
ylabel('成績');
for i=1:length(score1)
text(i,score1(i)+1,num2str(score1(i)))
end
% 建立 bar
bar(score1,'FaceColor',[0 0 0.5625],'BaseValue',60);
%% 灰色預測
figure
x0=grade;
m=1;
n=length(x0);%求x0的長度
x1=zeros(1,n);%生成與x0等長度的零向量
x1(1)=x0(1);%將x0首位賦值給x1
for i=2:n %計算累加序列 x1
x1(i)=x1(i-1)+x0(i); %x1為x0的累加序列
end
i=2:n; %對原始數列平行移位並賦給y
y(i-1)=x0(i);
y=y' %將 y 變成列向量
i=1:n-1; %計算資料矩陣 B 的第一列資料
c(i)=-0.5*(x1(i)+x1(i+1)); %兩個數平均值取負數,總感覺饒了一大圈
B=[c' ones(n-1,1)];%構造矩陣 B ,轉置後找個1伴隨
au=inv(B'*B)*B'*y;%計算引數 au 矩陣
i=1:n+1+m; %計算預測累加數列的值
ago(i)=(x0(1)-au(2)/au(1))*exp(-au(1)*(i-1))+ au(2)/au(1);
yc(1)=ago(1);
i=1:n-1; %還原數列的值
yc(i+1)=ago(i+1)-ago(i);
i=2:n;
error(i)=yc(i)-x0(i); %計算殘差值 yc(1)=ago(1);
i=1:n-1+m; %修正的還原數列的值 ,我怎麼感覺沒修正的樣子
yc(i+1)=ago(i+1)-ago(i);
c=std(error)/std(x0); %計算後驗差比,也就是殘差標準差和原數值標準差的比值
p=0;
for i=2:n
if(abs(error(i)-mean(error))<0.6745*std(x0))
p=p+1;
end
end%看殘差中有幾個數值和殘差均值的相差不大
p=p/(n-1);%p分配到每個參與的殘差上,即為小誤差概率的值
w1=min(abs(error));
w2=max(abs(error)); %計算殘差的最大最小位
i=1:n; %計算關聯度 w
w(i)=(w1+0.5*w2)./(abs(error(i))+0.5*w2);
w=sum(w)/(n-1);
au %輸出引數 a,u 的值
x0 %輸出原始序列值
ago %輸出累加數列 ago 的值
yc %輸出預測的值
error %輸出殘差的值
c %輸出後驗差比的值
p %輸出小誤差概率的值
w %輸出關聯度 w
plot(1:n,x0,'-.r+',1:m+n,yc,'--k*');
xlabel('學期');
ylabel('績點');
title(['學期績點灰色預測(預測得下一學期績點為' num2str(yc(6)) ')']);
legend(' 實測值','預測值');
- 結果如下:
也沒有其他要說的,強調一下eval函式的妙用,可以自動命名變數並進行賦值。另外,除了學分是純的數字以外,其他列的資料或多或少都摻雜著兩種以上的資料型別,因此都當做字串的格式讀入。之後再根據需要進行轉化處理。