我正在尝试计算和绘制bigrams频率的分布 首先,我确实生成了所有可能的bigrams,它们提供了1296个双字母
然后我从给定文件中提取bigrams并将其保存在words1
中我的问题是如何为文件a.txt计算这1296个双子星的频率? 如果文件中根本没有出现一些双字母,那么它们的频率应为零
a.txt是任何文本文件
clear
clc
%************create bigrams 1296 ***************************************
chars ='1234567890abcdefghijklmonpqrstuvwxyz';
chars1 ='1234567890abcdefghijklmonpqrstuvwxyz';
bigram='';
for i=1:36
for j=1:36
bigram = sprintf('%s%s%s',bigram,chars(i),chars1(j));
end
end
temp1 = regexp(bigram, sprintf('\\w{1,%d}', 1), 'match');
temp2 = cellfun(@(x,y) [x '' y],temp1(1:end-1)', temp1(2:end)','un',0);
bigrams = temp2;
bigrams = unique(bigrams);
bigrams = rot90(bigrams);
bigram = char(bigrams(1:end));
all_bigrams_len = length(bigrams);
clear temp temp1 temp2 i j chars1 chars;
%****** 1. Cleaning Data ******************************
collection = fileread('e:\a.txt');
collection = regexprep(collection,'<.*?>','');
collection = lower(collection);
collection = regexprep(collection,'\W','');
collection = strtrim(regexprep(collection,'\s*',''));
%*******************************************************
temp = regexp(collection, sprintf('\\w{1,%d}', 1), 'match');
temp2 = cellfun(@(x,y) [x '' y],temp(1:end-1)', temp(2:end)','un',0);
words1 = rot90(temp2);
%*******************************************************
words1_len = length(words1);
vocab1 = unique(words1);
vocab_len1 = length(vocab1);
[vocab1,void1,index1] = unique(words1);
frequencies1 = hist(index1,vocab_len1);
答案 0 :(得分:2)
嘿,类似于Dennis解决方案,你可以使用histc()
string1 = 'ASHRAFF'
histc(string1,'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
这会检查由字符串'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
定义的区间中的条目数,这有希望是字母表(只是快速写入,所以没有保证)。结果是:
Columns 1 through 21
2 0 0 0 0 2 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0
Columns 22 through 26
0 0 0 0 0
对我的解决方案进行一点修改:
string1 = 'ASHRAFF'
alphabet1='A':'Z'; %%// as stated by Oleg Komarov
data=histc(string1,alphabet1);
results=cell(2,26);
for k=1:26
results{1,k}= alphabet1(k);
results{2,k}= data(k);
end
如果你现在看results
,你可以很容易地检查它是否有效:D
答案 1 :(得分:2)
bsxfun
的计算字符数的解决方案 -
counts = sum(bsxfun(@eq,[string1-0]',65:90))
输出 -
counts =
2 0 0 0 0 2 0 1 0 0 ....
如果您希望得到每个字母的计数表格 -
out = [cellstr(['A':'Z']') num2cell(counts)']
输出 -
out =
'A' [2]
'B' [0]
'C' [0]
'D' [0]
'E' [0]
'F' [2]
'G' [0]
'H' [1]
'I' [0]
....
请注意,这是对大写字母区分大小写的计数。
对于小写字母计数,请将此编辑用于此早期代码 -
counts = sum(bsxfun(@eq,[string1-0]',97:122))
对于不区分大小写的计数,请使用此 -
counts = sum(bsxfun(@eq,[upper(string1)-0]',65:90))
让我们假设您已将所有可能的双字母组合保存在1D单元阵列bigrams1
中,并且来自文件的传入双字母组合将保存到另一个单元阵列words1
中。让我们也假设它们中的某些值用于演示 -
bigrams1 = {
'ar';
'de';
'c3';
'd1';
'ry';
't1';
'p1'}
words1 = {
'de';
'c3';
'd1';
'r9';
'yy';
'de';
'ry';
'de';
'dd';
'd1'}
现在,您可以使用此代码获取words1
中存在的bigrams1
的双字母组的计数 -
[~,~,ind] = unique(vertcat(bigrams1,words1));
bigrams_lb = ind(1:numel(bigrams1)); %// label bigrams1
words1_lb = ind(numel(bigrams1)+1:end); %// label words1
counts = sum(bsxfun(@eq,bigrams_lb,words1_lb'),2)
out = [bigrams1 num2cell(counts)]
代码运行的输出是 -
out =
'ar' [0]
'de' [3]
'c3' [1]
'd1' [2]
'ry' [1]
't1' [0]
'p1' [0]
结果显示 - ar
中找不到所有可能的bigrams列表中的第一个元素words1
;第二个元素de
在words1
中有三次出现,依此类推。
答案 2 :(得分:1)
这个答案会创建所有bigrams,文件中的加载会进行一些清理,然后使用unique
和histc
的组合来计算行数
请注意这里的顺序非常重要,因为unique会对数组进行排序,这样就可以预先创建它,以便输出符合期望值;
[y,x] = ndgrid(['0':'9','a':'z']);
allBigrams = [x(:),y(:)];
这会删除大小写,然后拉出任何0-9或a-z字符,然后创建这些
的列向量fileText = lower(fileread('d:\loremipsum.txt'));
cleanText = regexp(fileText,'([a-z0-9])','tokens');
cleanText = cell2mat(vertcat(cleanText{:}));
通过移动一个并连接
从文件创建双字节fileBigrams = [cleanText(1:end-1),cleanText(2:end)];
所有双字母组的集合被添加到我们的集合中(因此可以为所有可能的值创建值)。然后使用unique
的第3个输出为每个唯一行分配值∈{1,2,...,1296}。然后使用histc
创建计数,其中二进制位等于unique
输出中的一组值,从每个二进制数中减去1以删除我们添加的完整集合双字母
[~,~,c] = unique([fileBigrams;allBigrams],'rows');
counts = histc(c,1:1296)-1;
查看针对文字的计数
[allBigrams, counts+'0']
或可能更有用的东西......
[sortedCounts,sortInd] = sort(counts,'descend');
[allBigrams(sortInd,:), sortedCounts+'0']
ans =
or9
at8
re8
in7
ol7
te7
do6 ...
答案 3 :(得分:0)
没有查看整个代码片段,但是从问题顶部的示例中,我认为您正在寻找直方图:
string1 = 'ASHRAFF'
nr = histc(string1,'A':'Z')
会给你:
2 0 0 0 0 2 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0
(通过hist
获得了可行的解决方案,但是@The Minion节目histc
在这里更容易使用。)
请注意,此解决方案仅处理大写字母。
如果你想把小写字母放在正确的bin中,你可能想要这样做:
string1 = 'ASHRAFF'
nr = histc(upper(string1),'A':'Z')
或者如果您希望它们单独显示:
string1 = 'ASHRaFf'
nr = histc(upper(string1),['a':'z' 'A':'Z'])
答案 4 :(得分:0)
bi_freq1 = zeros(1,all_bigrams_len);
for k=1: vocab_len1
for i=1:all_bigrams_len
if char(vocab1(k)) == char(bigrams(i))
bi_freq1(i) = frequencies1(k);
end
end
end